deployment-gotchas
Deployment Gotchas
Not a deployment guide — these are the 7 things that break every first Phoenix deploy. Every rule maps to a real production incident pattern.
RULES — Follow these with no exceptions
- Use
runtime.exsfor secrets and URLs —config.exs/prod.exsare compiled into the release and cannot read env vars at boot - Run migrations via release commands (
bin/migrate) —mixis not available in production releases - Set
PHX_HOSTandPHX_SERVER=true— without these, URL generation breaks and the server won't start - Run
mix assets.deploybefore building the release — forgetting this means no CSS/JS in production - Never hardcode secrets — use
System.get_env!/1inruntime.exs(the!crashes on boot if missing, which is what you want) - Add a
/healthendpoint that queries the database — load balancers need it, and a 200-only check hides DB connection failures - Use
config :logger, level: :infoin production —:debuglogs query parameters including user data
1. runtime.exs vs config.exs
The incident: App deploys fine but uses the wrong database URL. DATABASE_URL was set correctly in the environment, but the release ignores it.
More from j-morgan6/elixir-phoenix-guide
oban-essentials
MANDATORY for ALL Oban work. Invoke before writing workers or enqueuing jobs.
1phoenix-json-api
MANDATORY for ALL JSON API work. Invoke before writing API controllers, pipelines, or JSON responses.
1ecto-essentials
MANDATORY for ALL database work. Invoke before modifying schemas, queries, or migrations.
1otp-essentials
MANDATORY for ALL OTP work. Invoke before writing GenServer, Supervisor, Task, or Agent modules.
1code-quality
Automated code quality detection — duplication, complexity, unused functions. Invoke when analyzing or refactoring Elixir code.
1phoenix-uploads
MANDATORY for file upload features. Invoke before implementing upload or file serving functionality.
1