Configuration options for mix phx.gen.release?

I’m working on adding Phoenix to an app that has previously operated without a web-server. I’m having trouble getting the release to run after deployment however.

I’ve noticed that mix phx.gen.release does not seem to look at the path option that are set in my mix.exs:

  defp releases do
    [
      my_app: [
        include_executables_for: [:unix],
        steps: [:assemble, :tar],
        overlays: ["envs/", "priv/", "config/"]
        path: "_build/rel"
      ]
    ]
  end

We peg all release builds to a single directory for simplicity: all variations in our app are runtime variants, so the compiled artifact is identical between environments so there’s no need to keep them separate, and this is referenced in Terraform to stop and start the systemctl service.

So I have 2 questions here…

  1. Is the mix phx.gen.release step necessary? Locally, I can set PHX_SERVER to true and run my release with the only mix release – Phoenix works (although I’m having trouble making this work on prod).
  2. Is there a path option that phx.gen.release can use? I’d like to keep the existing binary executable so we don’t need to refactor our terraform. If I omit the path option, things work, but the phx.gen.release creates 2 artifacts:
  • _build/dev/rel/my_app/bin/server
  • _build/dev/rel/my_app/bin/my_app

If you manually set the PHX_SERVER env variable you can get rid of the files in rel/overlay and shouldn’t see the additional server binary. All it does is set the env variable for you and then delegate to my_app binary.

Thanks, that makes sense. Things are working locally. However, on prod, I’m getting this error:

Failed to start Ranch listener MyAppWeb.Endpoint.HTTP in :ranch_tcp:listen([cacerts: :..., key: :..., cert: :..., port: 80]) for reason :eacces (permission denied)

presumably because listening on port numbers smaller than 1024 require root permissions.

What are the best practices for Phoenix to make this work?

Depends on the OS. Systemd can afaik allow services to bind to those ports. I usually just have a reverse proxy in front, given many of my servers host not just one website.