# Deploy a Phoenix App on Render This guide walks through deploying a [Phoenix](https://phoenixframework.org) application on Render. The finished code for this example is available on [GitHub](https://github.com/render-examples/phoenix_hello). ## Getting started Create a new Phoenix app in the terminal. We don't need a database for this example, so pass the `--no-ecto` flag to `mix`: ```shell mix archive.install hex phx_new mix phx.new phoenix_hello --no-ecto # also fetch and install dependencies cd phoenix_hello ``` ## Create a build script We need to run a series of commands to build our app on every push to our Git repo, which we can accomplish with a build script. Create a script named `build.sh` at the root of your repo: ```bash #!/usr/bin/env bash # exit on error set -o errexit # Initial setup mix deps.get --only prod MIX_ENV=prod mix compile # Compile assets # Make sure tailwind and esbuild are installed MIX_ENV=prod mix assets.build # Build minified assets MIX_ENV=prod mix assets.deploy # Create server script, Build the release, and overwrite the existing release directory MIX_ENV=prod mix phx.gen.release MIX_ENV=prod mix release --overwrite ``` Make sure the script is executable before you commit it: ```shell chmod a+x build.sh ``` ## Update your app for Render Update `config/runtime.exs` to change the highlighted line below: ```elixir host = System.get_env("PHX_HOST") || "example.com" # highlight-line port = String.to_integer(System.get_env("PORT") || "4000") ``` to this: ```elixir host = System.get_env("RENDER_EXTERNAL_HOSTNAME") || "localhost" # highlight-line port = String.to_integer(System.get_env("PORT") || "4000") ``` Render populates `RENDER_EXTERNAL_HOSTNAME` for `config/runtime.exs`. > If you add a [custom domain](custom-domains) to your Render app, don't forget to change the host to your new domain. ## Build and test your release locally Compile your release locally by running `./build.sh`. The end of the output should look like this: ```shell{outputLines:2-23} ./build.sh * assembling phoenix_hello-0.1.0 on MIX_ENV=prod * using config/runtime.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. ```bash SECRET_KEY_BASE=`mix phx.gen.secret` _build/prod/rel/phoenix_hello/bin/server ``` > You might need to run `mix deps.get` locally to enable `phx.gen.secret`, because it's a dev dependency instead of a prod dependency. You should add/commit your `mix.lock` file before running this. > You might notice the start command is different from the output of `build.sh`. The `phx.gen.release` command in the build script creates a wrapper for launching your application that include setting the PHX_SERVER variable, so a webserver will start. You can also use the start command from the `build.sh` output, but you will need to set `PHX_SERVER` to `true` in the environment variables if you do. If everything looks good, push your changes to your repo. Next, let's deploy your app to Render! ## Deploy to Render 1. In the [Render Dashboard](https://dashboard.render.com), create a new *web service* and connect your Phoenix app's repo. 2. Set the following values during service creation: | Setting | Value | | ----------------- | ------------------------------------------ | | *Language* | `Elixir` | | *Build Command* | `./build.sh` | | *Start Command* | `_build/prod/rel/phoenix_hello/bin/server` | 3. Add the following environment variable to your web service: | Key | Value | | --- | --- | | `SECRET_KEY_BASE` | A sufficiently strong secret. You can generate one from your local project directory with the following command: ```shell{outputLines:2-2} mix phx.gen.secret ``` | That's it! Your Phoenix web service will be live at its `onrender.com` subdomain as soon as the deploy finishes. Read about [setting Elixir and Erlang/OTP versions](elixir-erlang-versions) for your app.