- Quickstarts
- Phoenix
Deploy a Phoenix App with Mix Releases
This guide helps you deploy a Phoenix application packaged with Mix releases introduced in Elixir 1.9.
The finished code for this example is available at https://github.com/render-examples/phoenix_hello.
If you'd like to use Distillery, check out our guide to Phoenix Deployment with Distillery.Getting Started
Create a new Phoenix app in the terminal. We don’t need a database for this example, so we’re passing the --no-ecto
flag to mix
.
mix archive.install hex phx_new
mix phx.new phoenix_hello --no-ecto # also fetch and install dependencies
cd phoenix_hello
Configure Mix Releases
Create runtime configuration needed for Mix releases.
-
Rename
config/prod.secret.exs
toconfig/releases.exs
. -
Change
use Mix.Config
in your newconfig/releases.exs
file toimport Config
. -
Uncomment the following line in
config/releases.exs
:config :phoenix_hello, PhoenixHelloWeb.Endpoint, server: true # uncomment me!
-
Finally, update
config/prod.exs
to delete the lineimport_config "prod.secret.exs"
at the bottom.
If you’re migrating an existing app to Mix releases, make sure to update assets/package.json
to use a version of node-sass
compatible with Node 14 (the current LTS release):
"devDependencies": {
...
"node-sass": "^4.14.1", ...
}
Create a Build Script
We need to run a series of commands to build our app on every push to our Git repo, and we can accomplish this with a build script. Create a script called build.sh
at the root of your repo:
#!/usr/bin/env bash
# exit on error
set -o errexit
# Initial setup
mix deps.get --only prod
MIX_ENV=prod mix compile
# Compile assets
npm install --prefix ./assets
npm run deploy --prefix ./assets
mix phx.digest
# Build the release and overwrite the existing release directory
MIX_ENV=prod mix release --overwrite
Make sure the script is executable before checking it into Git:
chmod a+x build.sh
Update Your App for Render
Update config/prod.exs
to change the highlighted line below.
config :phoenix_hello, PhoenixHelloWeb.Endpoint,
url: [host: "example.com", port: 80], cache_static_manifest: "priv/static/cache_manifest.json"
to this:
config :phoenix_hello, PhoenixHelloWeb.Endpoint,
url: [host: System.get_env("RENDER_EXTERNAL_HOSTNAME") || "localhost", port: 80], cache_static_manifest: "priv/static/cache_manifest.json"
Render populates RENDER_EXTERNAL_HOSTNAME
for config/prod.exs
.
Build and Test Your Release Locally
Compile your release locally by running ./build.sh
. The output should look like this:
* assembling phoenix_hello-0.1.0 on MIX_ENV=prod
* using config/releases.exs to configure the release at runtime
* skipping elixir.bat for windows (bin/elixir.bat not found in the Elixir installation)
* skipping iex.bat for windows (bin/iex.bat not found in the Elixir installation)
Release created at _build/prod/rel/phoenix_hello!
# To start your system
_build/prod/rel/phoenix_hello/bin/phoenix_hello start
Once the release is running:
# To connect to it remotely
_build/prod/rel/phoenix_hello/bin/phoenix_hello remote
# To stop it gracefully (you may also send SIGINT/SIGTERM)
_build/prod/rel/phoenix_hello/bin/phoenix_hello stop
To list all commands:
_build/prod/rel/phoenix_hello/bin/phoenix_hello
Test your release by running the following command and navigating to http://localhost:4000.
SECRET_KEY_BASE=`mix phx.gen.secret` _build/prod/rel/phoenix_hello/bin/phoenix_hello start
If everything looks good, push your changes to your repo. You can now deploy your app in production! 🎉
Deploy to Render
-
Create a new Web Service on Render, and give Render permission to access your Phoenix repo.
-
Set the following values during creation:
Setting Value Runtime Elixir
Build Command ./build.sh
Start Command _build/prod/rel/phoenix_hello/bin/phoenix_hello start
Also add the following environment variables to your web service:
Key Value SECRET_KEY_BASE
A sufficiently strong secret. Generate it locally by running mix phx.gen.secret
That’s it! Your Phoenix web service built with Mix releases will be live on your Render URL as soon as the build finishes.
Read about customizing Elixir and Erlang/OTP versions for your app.