<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="365463" data-post-id="365463">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Zurga" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Zurga/120/38832_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Zurga
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I am a bit short on time right now, but will try to post it this weekend.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="365463" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/locally-deploy-phoenix-liveview-using-nix/70831/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-365463" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="365463"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="365613" data-post-id="365613">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="serpent" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/serpent/120/14597_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  serpent
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Please do! This should be plug &amp; play – but it’s next to impossible!  <img src="https://forum.elixirforum.com/images/emoji/apple/joy.png?v=15" title=":joy:" class="emoji" alt=":joy:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="365613" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/locally-deploy-phoenix-liveview-using-nix/70831/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-365613" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="365613"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="365656" data-post-id="365656">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="serpent" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/serpent/120/14597_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  serpent
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Got it to work, finally. Little knowledge dump here – still room for improvement. Comes with a little helper script to connect to the running node (if enabled in the module).</p>
<p><code>heroicons</code> as Mix dep is problematic: 1. comes in via git, 2. is not a Mix package</p>
<p>Moved it to npm as per <a href="https://latinum.xyz/posts/phoenix-1.7-with-npm/" class="inline-onebox" rel="noopener nofollow ugc">Phoenix 1.7 with npm · Latinum</a>.</p>
<p>If you don’t want to introduce a <code>Release</code> module, you can also eval app start and repo migration directly in the startup script (or do it manually).</p>
<h1><a name="p-365656-final-packagenix-1" class="anchor" href="#p-365656-final-packagenix-1" aria-label="Heading link" rel="nofollow"></a>Final package.nix</h1>
<pre data-code-wrap="nix"><code class="lang-nix">{
  lib,
  beamPackages,
  nodejs,
  makeWrapper,
  fetchgit,
  buildNpmPackage,
}: let
  pname = "senegal-phoenix";
  version = "0.1.0";

  src = fetchgit {
    url = "https://git.example.com/self/senegal-phoenix.git";
    rev = "07ec6af047c5df2ed97f3d806070dd4ce1a46fd8";
    sha256 = "sha256-id2oxX8a5wgO/AhnZGigZ7AzFBZ+mhTptPeCxlYpOFk=";
  };

  # Build assets with npm
  assets = buildNpmPackage {
    pname = "${pname}-assets";
    inherit version src;
    sourceRoot = "${src.name}/assets";
    npmDepsHash = "sha256-D8C4ra2RYbHQdv4lILpnAra0+TBszh+bAW9iqUTfWBQ=";
    dontNpmBuild = true;
    installPhase = ''
      runHook preInstall
      cp -r . $out/
      runHook postInstall
    '';
  };

  # Fetch Mix dependencies using beamPackages.fetchMixDeps
  mixFodDeps = beamPackages.fetchMixDeps {
    pname = "${pname}-mix-deps";
    inherit src version;
    sha256 = "sha256-AzGYVTcESiTVmhDM3lSdg9EWzAe8+aBkerqcwCR2xQY=";
  };
in
  beamPackages.mixRelease {
    inherit pname version src mixFodDeps;

    nativeBuildInputs = [
      makeWrapper
      nodejs
    ];

    # Environment for production build
    MIX_ENV = "prod";

    # Clean up any existing build artifacts before Nix creates symlinks
    preConfigure = ''
      rm -rf deps _build assets
    '';

    # Setup pre-built assets before Mix compile
    preBuild = ''
      # Copy pre-built assets from npm package
      cp --no-preserve=mode -r ${assets} assets
      # Fix esbuild executable permissions
      chmod +x assets/node_modules/@esbuild/*/bin/esbuild 2&gt;/dev/null || true
      chmod +x assets/node_modules/.bin/* 2&gt;/dev/null || true
    '';

    # Build the release with assets
    postBuild = ''
      # Deploy Phoenix assets
      mix do deps.loadpaths --no-deps-check, assets.deploy
      mix do deps.loadpaths --no-deps-check, phx.digest priv/static
    '';

    # Install and create wrapper
    postInstall = ''
      # Create a wrapper script for easier execution
      mkdir -p $out/bin
      makeWrapper $out/bin/senegal $out/bin/senegal-server \
        --set MIX_ENV prod \
        --set PHX_SERVER true
    '';

    passthru = {
      inherit assets;
    };

    meta = with lib; {
      description = "Phoenix LiveView application packaging example";
      homepage = "https://github.com/your-org/senegal-phoenix";
      license = licenses.mit;
      maintainers = [];
      platforms = platforms.unix;
    };
  }
</code></pre>
<h1><a name="p-365656-final-modulenix-2" class="anchor" href="#p-365656-final-modulenix-2" aria-label="Heading link" rel="nofollow"></a>Final module.nix</h1>
<pre data-code-wrap="nix"><code class="lang-nix">{
  config,
  lib,
  pkgs,
  ...
}: let
  cfg = config.services.senegal-phoenix;
  senegalPhoenix = pkgs.callPackage ../pkgs/senegal-phoenix.nix {};
in {
  options.services.senegal-phoenix = {
    enable = lib.mkEnableOption "Senegal Phoenix - Example App";

    package = lib.mkOption {
      type = lib.types.package;
      default = senegalPhoenix;
      description = "The Senegal Phoenix package to use";
    };

    port = lib.mkOption {
      type = lib.types.port;
      default = 4000;
      description = "Port to listen on";
    };

    host = lib.mkOption {
      type = lib.types.str;
      default = "localhost";
      description = "The host to configure the router generation from";
    };

    environmentFile = lib.mkOption {
      type = lib.types.nullOr lib.types.path;
      default = null;
      description = ''
        Path to environment file containing configuration variables (sourced by systemd).
        Example file contents:
          DATABASE_URL=postgresql://user:pass@host/db
          SECRET_KEY_BASE=your-secret-key-here
          # MUST be set
          RELEASE_COOKIE=your-erlang-cookie-here
      '';
    };

    secretKeyBaseFile = lib.mkOption {
      type = lib.types.nullOr lib.types.path;
      default = null;
      description = "A file containing the Phoenix Secret Key Base";
    };

    databaseUrlFile = lib.mkOption {
      type = lib.types.nullOr lib.types.path;
      default = null;
      description = "A file containing the URL to connect to the database";
    };

    openAIKeyFile = lib.mkOption {
      type = lib.types.nullOr lib.types.path;
      default = null;
      description = "A file containing the OpenAI API key";
    };

    enableDistribution = lib.mkOption {
      type = lib.types.bool;
      default = false;
      description = ''
        Enable Erlang distribution for remote shell access and clustering.
        Requires RELEASE_COOKIE to be set in environmentFile for authentication.
        Provides 'senegal-connect' command for connecting to the running node.
      '';
    };

    user = lib.mkOption {
      type = lib.types.str;
      default = "senegal-phoenix";
      description = "User account under which the service runs";
    };

    group = lib.mkOption {
      type = lib.types.str;
      default = "senegal-phoenix";
      description = "Group account under which the service runs";
    };

    dataDir = lib.mkOption {
      type = lib.types.path;
      default = "/var/lib/senegal-phoenix";
      description = "Directory to store application data";
    };
  };

  config = lib.mkIf cfg.enable {
    users.users.${cfg.user} = {
      description = "Senegal Phoenix service user";
      group = cfg.group;
      home = cfg.dataDir;
      createHome = true;
      isSystemUser = true;
    };

    users.groups.${cfg.group} = {};

    systemd.services.senegal-phoenix = {
      description = "Senegal Phoenix - Child sponsorship management system";
      after = ["network.target"];
      wantedBy = ["multi-user.target"];

      serviceConfig = {
        Type = "exec";
        User = cfg.user;
        Group = cfg.group;
        WorkingDirectory = cfg.dataDir;
        Restart = "on-failure";
        RestartSec = "5s";

        # Environment file injection
        EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;

        # Security hardening
        NoNewPrivileges = true;
        PrivateTmp = true;
        ProtectSystem = "strict";
        ProtectHome = true;
        ReadWritePaths = [cfg.dataDir];

        # Load credentials securely
        LoadCredential = lib.filter (x: x != null) [
          (lib.optionalString (cfg.secretKeyBaseFile != null) "SECRET_KEY_BASE:${cfg.secretKeyBaseFile}")
          (lib.optionalString (cfg.databaseUrlFile != null) "DATABASE_URL:${cfg.databaseUrlFile}")
          (lib.optionalString (cfg.openAIKeyFile != null) "OPENAI_API_KEY:${cfg.openAIKeyFile}")
        ];
      };

      script = let
        credentialSetup = ''
          # Load individual credential files
          ${lib.optionalString (cfg.secretKeyBaseFile != null) ''
            export SECRET_KEY_BASE="$(&lt; $CREDENTIALS_DIRECTORY/SECRET_KEY_BASE)"
          ''}
          ${lib.optionalString (cfg.databaseUrlFile != null) ''
            export DATABASE_URL="$(&lt; $CREDENTIALS_DIRECTORY/DATABASE_URL)"
          ''}
          ${lib.optionalString (cfg.openAIKeyFile != null) ''
            export OPENAI_API_KEY="$(&lt; $CREDENTIALS_DIRECTORY/OPENAI_API_KEY)"
          ''}
        '';
      in ''
        ${credentialSetup}

        # Set node name with actual hostname for distribution
        ${lib.optionalString cfg.enableDistribution ''
          export RELEASE_NODE="senegal@$(hostname)"
        ''}

        # Run database migrations
        ${cfg.package}/bin/senegal eval "Senegal.Release.migrate()"

        # Start the Phoenix server
        ${cfg.package}/bin/senegal-server start
      '';

      environment = {
        # Phoenix configuration
        PHX_HOST = cfg.host;
        PORT = toString cfg.port;

        # Elixir/OTP configuration
        RELEASE_DISTRIBUTION =
          if cfg.enableDistribution
          then "sname"
          else "none";
        RELEASE_NODE = "senegal@localhost";

        # Application-specific defaults
        ECTO_IPV6 = "false";
      };
    };

    # Script for connecting to the BEAM node
    environment.systemPackages = lib.mkIf cfg.enableDistribution [
      (pkgs.writeShellScriptBin "senegal-connect" (let
        connectCommand = ''
          cd ${cfg.dataDir}
          ${lib.optionalString (cfg.environmentFile != null) ''
            set -a
            source ${cfg.environmentFile}
            set +a
          ''}
          exec ${cfg.package}/bin/senegal remote
        '';
      in ''
        if [ "$(whoami)" = "${cfg.user}" ]; then
          ${connectCommand}
        elif [ "$(id -u)" = "0" ]; then
          exec su -m ${cfg.user} -c "${connectCommand}"
        else
          echo "Must run as root or ${cfg.user} user. Try: sudo senegal-connect"
          exit 1
        fi
      ''))
    ];
  };
}
</code></pre>
<h1><a name="p-365656-releaseex-3" class="anchor" href="#p-365656-releaseex-3" aria-label="Heading link" rel="nofollow"></a>release.ex</h1>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Senegal.Release do
  @moduledoc """
  Used for executing DB release tasks when run in production without Mix installed.
  """
  @app :senegal

  def migrate do
    load_app()

    for repo &lt;- repos() do
      {:ok, _, _} = Ecto.Migrator.with_repo(repo, &amp;Ecto.Migrator.run(&amp;1, :up, all: true))
    end
  end

  def rollback(repo, version) do
    load_app()
    {:ok, _, _} = Ecto.Migrator.with_repo(repo, &amp;Ecto.Migrator.run(&amp;1, :down, to: version))
  end

  defp repos do
    Application.fetch_env!(@app, :ecto_repos)
  end

  defp load_app do
    Application.load(@app)
  end
end
</code></pre>
<p>Automatic notes (careful, might be inaccurate and not reflect latest changes to above files):</p>
<h1><a name="p-365656-nix-package-development-notes-4" class="anchor" href="#p-365656-nix-package-development-notes-4" aria-label="Heading link" rel="nofollow"></a>Nix Package Development Notes</h1>
<h2><a name="p-365656-objective-5" class="anchor" href="#p-365656-objective-5" aria-label="Heading link" rel="nofollow"></a>Objective</h2>
<p>Transform the Senegal Phoenix Elixir/Phoenix application into a Nix package for reproducible builds and deployment.</p>
<h2><a name="p-365656-approaches-tried-6" class="anchor" href="#p-365656-approaches-tried-6" aria-label="Heading link" rel="nofollow"></a>Approaches Tried</h2>
<h3><a name="p-365656-h-1-beampackagesfetchmixdeps-initial-attempt-7" class="anchor" href="#p-365656-h-1-beampackagesfetchmixdeps-initial-attempt-7" aria-label="Heading link" rel="nofollow"></a>1. beamPackages.fetchMixDeps (Initial Attempt)</h3>
<p><strong>Status</strong>: Failed due to Git dependency issues</p>
<p><strong>Method</strong>:</p>
<ul>
<li>Used <code>beamPackages.fetchMixDeps</code> to fetch all Mix dependencies</li>
<li>Used <code>beamPackages.mixRelease</code> for final package creation</li>
</ul>
<p><strong>Issues Encountered</strong>:</p>
<ul>
<li><strong>Git Dependencies</strong>: <code>fetchMixDeps</code> doesn’t handle Git dependencies well</li>
<li><strong>Heroicons Dependency</strong>: The heroicons dependency from GitHub caused lock mismatches</li>
<li><strong>Symlink Errors</strong>: Initial “ln: failed to create symbolic link ‘./deps’: File exists” errors</li>
</ul>
<p><strong>Key Fix</strong>:</p>
<ul>
<li>Added <code>preConfigure = ''rm -rf deps _build''</code> to clean build artifacts before Nix creates symlinks</li>
<li>Simplified heroicons dependency in <code>mix.exs</code> by removing <code>sparse: "optimized"</code> and <code>depth: 1</code> options</li>
</ul>
<p><strong>Final Error</strong>: Lock mismatch for heroicons Git dependency persisted despite hash updates</p>
<h3><a name="p-365656-h-2-mix2nix-approach-current-8" class="anchor" href="#p-365656-h-2-mix2nix-approach-current-8" aria-label="Heading link" rel="nofollow"></a>2. mix2nix Approach (Current)</h3>
<p><strong>Status</strong>: In progress, still has dependency lock issues</p>
<p><strong>Method</strong>:</p>
<ul>
<li>Generate <code>mix.nix</code> file using <code>mix2nix</code> tool</li>
<li>Handle Git dependencies manually (heroicons via <code>fetchFromGitHub</code>)</li>
<li>Use <code>mixNixDeps</code> instead of <code>mixFodDeps</code></li>
</ul>
<p><strong>Implementation</strong>:</p>
<pre data-code-wrap="nix"><code class="lang-nix"># Heroicons Git dependency (mix2nix doesn't support Git deps)
heroicons = fetchFromGitHub {
  owner = "tailwindlabs";
  repo = "heroicons";
  rev = "v2.1.1";
  hash = "sha256-4yRqfY8r2Ar9Fr45ikD/8jK+H3g4veEHfXa9BorLxXg=";
};

# Mix dependencies from generated mix.nix
mixNixDeps = import ./mix.nix {
  inherit lib beamPackages;
};
</code></pre>
<p><strong>Current Issues</strong>:</p>
<ul>
<li>Multiple dependency lock mismatches (finch, openai_ex, websock, bandit, swoosh, etc.)</li>
<li><code>mix.nix</code> generated dependencies don’t match <code>mix.lock</code> versions</li>
<li>Need <code>--no-deps-check</code> flag but still getting validation errors</li>
</ul>
<h2><a name="p-365656-key-learnings-9" class="anchor" href="#p-365656-key-learnings-9" aria-label="Heading link" rel="nofollow"></a>Key Learnings</h2>
<h3><a name="p-365656-git-dependencies-in-nix-10" class="anchor" href="#p-365656-git-dependencies-in-nix-10" aria-label="Heading link" rel="nofollow"></a>Git Dependencies in Nix</h3>
<ul>
<li><code>beamPackages.fetchMixDeps</code> has poor support for Git dependencies</li>
<li>Git dependencies need manual handling via <code>fetchFromGitHub</code></li>
<li>Mix dependency specifications with <code>sparse</code> and <code>depth</code> options confuse Nix tools</li>
</ul>
<h3><a name="p-365656-source-filtering-11" class="anchor" href="#p-365656-source-filtering-11" aria-label="Heading link" rel="nofollow"></a>Source Filtering</h3>
<ul>
<li>Using <code>src = ./.</code> can include unwanted build artifacts</li>
<li><code>lib.cleanSource</code> helps filter but may not be sufficient</li>
<li>Proper <code>.gitignore</code> patterns are crucial for clean Nix builds</li>
</ul>
<h3><a name="p-365656-mix-lock-file-synchronization-12" class="anchor" href="#p-365656-mix-lock-file-synchronization-12" aria-label="Heading link" rel="nofollow"></a>Mix Lock File Synchronization</h3>
<ul>
<li>Nix tools expect exact version matches between <code>mix.lock</code> and generated dependency files</li>
<li>Local development changes to dependencies can break Nix builds</li>
<li><code>--no-deps-check</code> flag needed to bypass validation in Nix context</li>
</ul>
<h2><a name="p-365656-resources-referenced-13" class="anchor" href="#p-365656-resources-referenced-13" aria-label="Heading link" rel="nofollow"></a>Resources Referenced</h2>
<ul>
<li><a href="https://curiosum.com/blog/packaging-elixir-application-with-nix" rel="noopener nofollow ugc">Packaging Elixir Applications with Nix</a></li>
<li><a href="https://raw.githubusercontent.com/NixOS/nixpkgs/refs/heads/master/pkgs/servers/pleroma/default.nix" rel="noopener nofollow ugc">Pleroma Package Example</a></li>
<li><a href="https://nix.dev/tutorials/working-with-local-files.html#union-explicitly-exclude-files" rel="noopener nofollow ugc">Nix Union/Exclude Files</a></li>
<li><a href="https://forum.elixirforum.com/t/locally-deploy-phoenix-liveview-using-nix/70831" rel="nofollow">Elixir Forum: Phoenix LiveView with Nix</a></li>
<li><a href="https://raw.githubusercontent.com/NixOS/nixpkgs/refs/heads/master/doc/languages-frameworks/beam.section.md" rel="noopener nofollow ugc">Nixpkgs BEAM Documentation</a></li>
</ul>
<h3><a name="p-365656-h-3-beampackagesfetchmixdeps-second-attempt-success-14" class="anchor" href="#p-365656-h-3-beampackagesfetchmixdeps-second-attempt-success-14" aria-label="Heading link" rel="nofollow"></a>3. beamPackages.fetchMixDeps (Second Attempt - SUCCESS!)</h3>
<p><strong>Status</strong>: <img src="https://forum.elixirforum.com/images/emoji/apple/white_check_mark.png?v=15" title=":white_check_mark:" class="emoji" alt=":white_check_mark:" loading="lazy" width="20" height="20"> SUCCESS! Working Nix package</p>
<p><strong>Key Changes</strong>:</p>
<ul>
<li><strong>Removed Git Dependencies</strong>: Cleaned heroicons Git dependency from mix.lock using <code>mix deps.clean --unused --unlock</code></li>
<li><strong>Switched to npm heroicons</strong>: Now using heroicons via npm package in assets/package.json instead of Git</li>
<li><strong>Simplified Asset Handling</strong>: Build assets as part of main build process, not separately</li>
<li><strong>Correct Wrapper Path</strong>: Fixed makeWrapper to use correct executable path</li>
</ul>
<p><strong>Implementation</strong>:</p>
<pre data-code-wrap="nix"><code class="lang-nix"># Uses beamPackages.fetchMixDeps for Mix dependencies
mixFodDeps = beamPackages.fetchMixDeps {
  pname = "${pname}-mix-deps";
  src = lib.cleanSource ./.;
  version = version;
  sha256 = "sha256-vtNELuwL0S1jyfpAKp+Z/356jf8Jq4Lx9eF69c/EYyI=";
  mixEnv = "prod";
};

# Assets built during main build process
preBuild = ''
  cd assets
  npm install
  cd ..
'';

postBuild = ''
  mix assets.deploy
'';
</code></pre>
<p><strong>Success Factors</strong>:</p>
<ol>
<li><strong>No Git Dependencies</strong>: All dependencies are now from Hex registry</li>
<li><strong>Clean mix.lock</strong>: Regenerated after removing Git dependencies</li>
<li><strong>npm heroicons</strong>: Switched from Git to npm package for heroicons</li>
<li><strong>Integrated Asset Build</strong>: Assets built within Phoenix build context, not separately</li>
</ol> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="365656" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/locally-deploy-phoenix-liveview-using-nix/70831/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-365656" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="365656"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="365837" data-post-id="365837">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Zurga" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Zurga/120/38832_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Zurga
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Nice to get it working!</p>
<p>I was doing some refactoring last night to make my script a bit more modular. The progress is on <a href="http://github.com/Zurga/phoenix_nix" class="inline-onebox" rel="noopener nofollow ugc">GitHub - Zurga/phoenix_nix · GitHub</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="365837" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/locally-deploy-phoenix-liveview-using-nix/70831/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-365837" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="365837"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="365929" data-post-id="365929">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Zurga" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Zurga/120/38832_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Zurga
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I updated the repo with some documentation.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="365929" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/locally-deploy-phoenix-liveview-using-nix/70831/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-365929" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="365929"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>