Deploying an Elixir Release using Docker on Render.com

Deploying an Elixir Release using Docker on Render.com

Deploy a Phoenix 1.6 app using Elixir Releases and Docker on Render.com

I'm going to show you how to deploy our Elixir Release to render.com. We'll use our Docker image.

Prepare Elixir Release for deploying to render.com

We only need to do a single change to our runtime.exs file. Add the url: line to the

  config :saturn, SaturnWeb.Endpoint,
    url: [host: System.get_env("RENDER_EXTERNAL_HOSTNAME") || "localhost", port: 80],
    http: [
      # Enable IPv6 and bind on all interfaces.
      # Set it to  {0, 0, 0, 0, 0, 0, 0, 1} for local network only access.
      # See the documentation on https://hexdocs.pm/plug_cowboy/Plug.Cowboy.html
      # for details about using IPv6 vs IPv4 and loopback vs public addresses.
      ip: {0, 0, 0, 0, 0, 0, 0, 0},
      port: String.to_integer(System.get_env("PORT") || "4000")
    ],
    secret_key_base: secret_key_base

I am creating a branch named render-deployment and committing all these changes to it:

git checkout -b render-deployment
git add .
git commit -m "Config for render.com"
git push -u origin render-deployment

Create and configure your render.com account

Create an account in render.com and log in. We are going to create two services, one for the database and one for the Elixir Release. We must be sure that both services are created in the same region so that they share the same private network and can communicate and establish connections using their assigned network names. If we fail to do this, you'll see errors in the logs saying that the database domain name is non-existant (:nxdomain error).

For this article, I'm going to put both in the Oregon, USA region. Be sure to use the same one.

Create the Database

Create a database service by clicking the New + button on the dashboard:

Create a new Database

Select one name for this service (I'm using Saturn DB) and ensure the Oregon, USA region is selected. Leave the other fields to their defaults and select the Free plan. Then click the Create Database to provision this service.

Configure Database

In the next page you'll see the details of the database. We need to copy one value from here, the connection string that we'll use for the DATABASE_URL environment variable when we create the Elixir Release service.

Click the copy button on the Internal Connection String

Copy Internal Connection String

Create the Web Service

Let's create a Web Service with the New + button:

Create a Web Service

You'll need to connect your GitHub or GitLab account:

Connect your GitHub or GitLab account

and select the repository you want to deploy:

Select repository to deploy

Let's configure it. Set a name for your service (I'm using Saturn here). You'll see that the Dockerfile was detected and the Environment is preselected to Docker. Ensure you're using the Oregon, USA region, otherwise both services won't be able to connect each other. Select the branch you want to deploy (in my case is render-deployment) and select the Free plan.

Configure Web Service

We need to add a couple of environment variables.

Create environment variables

Create a DATABASE_URL and paste the value you copied from the Internal Connection String field in the Database service config page.

Then add another named SECRET_KEY_BASE. Run this command on the terminal and use the result as the value for it:

mix phx.gen.secret

Environment variables created

You can now create the Web Service. You'll see the status of the provisioning and when it is ready you'll see a green Live button and a line on the logs saying that the Endpoint is listening for requests:

Provisioning Web Service

If you click on the URL generated for your Web Service you'll see your Elixir Release app running on Render.com infrastructure:

Elixir Release running on render.com

Running Migrations and connecting to the running instance

This is something I couldn't do so far. The UI render provides has no way to connect to the running container. One way to run the migrations would be:

  1. Build the Elixir Release locally as shown here
  2. Copy the External Connection String from the database configuration page
  3. Set a DATABASE_URL environment variable to that value
  4. Run the _build/prod/rel/saturn/bin/saturn eval "Saturn.Release.migrate" command

Source code

The source code for the saturn project is open source under the MIT license. Use the render-deployment branch.

About

I'm Miguel Cobá. I write about Elixir, Elm, Software Development, and eBook writing.

Photo by Mueen Agherdien on Unsplash