What is Render?
Render is a Platform as a Service (PaaS) cloud hosting solution that can host web applications, static websites and databases (currently PostgreSQL). Render provides free TLS certificates and supports deploying directly from Git.
What you need for this guide
The only thing you need to follow this guide is a working Phoenix 1.7 application. Throughout this guide, <APP_NAME>
is the initial application name and <MODULE_NAME>
is the base module name for your application.
Finding your application name (<APP_NAME>
) and module name (<MODULE_NAME>
)
NOTE: You can get the application name and module name from config/config.exs as shown below:
Create a new Phoenix application if you need a simple application to deploy
If you need more information or want some troubleshooting information, refer to the Up and Running Guide
Create a build script
When preparing an application for deployment, there are three main steps:
- Handling of your application secrets
- Compiling your application assets
- Starting your server in production
In order to assemble a release on Render, we need a build script. I’ve used the build script provided by Render and simplified it a bit.
Make sure that the script is executable before checking it into Git by running chmod a+x build.sh
on the command line.
You no longer need to follow any of the instructions in the Configure Mix Releases section or the Update your App for Render section in the Render documentation. The config/runtime.exs file generated by mix phx.gen
now uses configuration options via environment variables that make deployment on Render much simpler than in previous Phoenix releases.
Create a web Service on Render
Create a new Web Service on Render and connect it to your GitHub or GitLab repository. The values that you need to get right during creation are. Please make sure to replace <APP_NAME>
with your own application name. I’ve described how to find your application name earlier in this guide:
Setting | Value |
---|---|
Runtime | Elixir |
Build Command | ./build.sh |
Start Command | _build/prod/rel/<APP_NAME>/bin/<APP_NAME> start |
NOTE: You’ll need a paid instance type for your web service if you want to run a Pre-Deploy Command which is needed to run Ecto migrations on deployment.
Set environment variables
The last section when you are creating a Web Service are the Environment Variables. You need to set these two Environment Variables:
Name of Variable | Value |
---|---|
PHX_SERVER | true |
PORT | 4000 |
SECRET_KEY_BASE | Run mix phx.gen.secret from the command line and use the generated value here |
DATABASE_URL | Create a PostgreSQL database on Render and copy the value of the Internal Database URL once the database has been created. You can follow this guide with the free instance type. |
Click the “Create Web Service” button.
Specify an Elixir and Erlang version
It’s good practice to set the Elixir version that your application requires, usually the version that you’ve been developing on. Without this, Render will use a default version for Elixir (and Erlang), which can cause unexpected problems in the future.
Set the Elixir version your application expects in your Environment variables:
Name of Variable | Value |
---|---|
ELIXIR_VERSION | Run ‘elixir -v’ on your command line to find out the Elixir version you’re developing on |
ERLANG_VERSION | Don’t set this value; Render automatically downloads an Erlang runtime that’s compatible with your chosen Elixir version |
You can get a list of all supported Elixir versions on Render here.
Checkpoint 1: Deploy Phoenix application
You should now be able to visit the URL provided by Render to view your deployed Phoenix application.
Run Ecto migrations on every deploy
NOTE: A paid tier web service instance type is needed from this point onwards.
Create a module that allows you to run database tasks like migration or rollback when the application is running in production without Mix installed:
Go to your web service’s settings on Render and set a Pre-Deploy command:
Setting | Value |
---|---|
Pre-Deploy Command | _build/prod/rel/<APP_NAME>/bin/<APP_NAME> eval "<MODULE_NAME>.Release.migrate" |
Now commit the module to your code repository to trigger a new deploy. From now on, pending Ecto migrations will run before every deploy.
Checkpoint 2: Run Ecto migrations before every deployment
Your application should now connect to a PostgreSQL database and run migrations before every new deployment.
Add a custom domain
Follow Render’s guide to adding a custom domain in order to add your custom domain to point to the newly created web service on Render. Once the DNS records have been verified and an SSL certificate has been generated, you should be able to visit your application on your custom domain.
Fix LiveViews
There is one last issue which shows up only when you use Phoenix LiveViews AND use a custom domain on Render.
Let’s build a simple LiveView from scratch to see the issue.
Add a live Route
Create a LiveView module
Start the server with mix phx.server
and visit https://localhost:4000/test to see a simple rendered LiveView. Commit to your code repository to trigger a deployment on Render.
Now visit the same URL on your newly deployed web service and you should see an alert at the top right that says “We can’t find the internet Attempting to reconnect”. All you have to do to fix this is to add a single line to runtime.exs:
You also need to configure your application to use proxy headers in prod.exs:
You should now be able to use LiveView on Phoenix applications deployed to Render!
Troubleshooting
-
bash: ./build.sh: No such file or directory
in the deploy logs when deploying on Render.Make sure you check in and push build.sh to your code respository. Make sure that build.sh is in the root of the application directory. (Read Create a build script)
-
(RuntimeError) environment variable DATABASE_URL is missing.
in the deploy logs when deploying on Render.This guide assumes that you’re going to connect to a database. Make sure you create a PostgreSQL database on Render and set the DATABASE_URL environment variable as described above.
NOTE: The free instance type is deleted after a month, so make sure that it’s still up and running if you see this error once you’ve deployed the application a while ago.
-
”We can’t find the internet Attempting to reconnect” in a red alert box in the top right when visiting a LiveView URL.
You’ll also see Phoenix LiveView constantly refreshing. This only happens when you use a custom domain on Render. (Read Fix LiveViews to fix this issue)
-
(UndefinedFunctionError) function App.Release.migrate/0 is undefined (module App.Release is not available)
in the deploy logs when deploying on Render.Make sure to use your application’s
<MODULE_NAME>
in release.ex. (Read Run Ecto migrations on every deploy) -
(ArgumentError) could not fetch application environment :ecto_repos for application :deploy_to_render because the application was not loaded nor configured
in the deploy logs when deploying on Render.Make sure to use your application’s
<APP_NAME>
in release.ex. (Read Run Ecto migrations on every deploy)
Reference
- Render website
- Guide to getting up and running with Phoenix
- Guide to deploying a Phoenix Elixir with releases
- Render’s guide to deploy a Phoenix application with releases on Render
- Render’s guide to adding a custom domain
- Render’s guide to configuring DNS
- Render’s docs on port binding
- Render’s docs on setting your Elixir and Erlang Versions
- Render’s list of supported Elixir versions