Deploying Elixir to Render.com
Tags: tipstricks
Published: 2021-05-26 17:43:48

---
title: Deploying Elixir to Render.com
published: true
date: 2021-05-04 23:26:17 UTC
tags: TipsTricks
canonical_url: https://mrmurphy.dev/deploying-elixir-to-render-com/
---

I've deployed a few different Elixir services to the hosting platform [https://render.com](http://render.com) and found their provided documentation to be lacking for real-world Phoenix apps. Especially if you're using Live View. Here's an augmentation to their guide with the extra steps you might be missing.

## Initial Setup

Follow the official guide: [https://render.com/docs/deploy-phoenix](https://render.com/docs/deploy-phoenix) but don't deploy your service yet. You'll need to make some changes:

## Add Evars

Add some new evars:

- `ELIXIR_VERSION` = `1.10.3` or whatever version you like. But the default version is older and breaks the build for new Elixir apps
- `DATABASE_URL` = The connection string for the database you'll be using

## Migrations

After, do these things. **MAKE SURE YOU REPLACE** <app\_name> **WITH YOUR APP NAME** :

- Add a new script for running migrations (`./build_and_migrate.sh`):

```
#!/usr/bin/env bash
# exit on error
set -o errexit

./build.sh

# Run migrations
_build/prod/rel/<app_name>/bin/<app_name> eval "Render.Release.migrate"
```

- Make that new script executable.
- Make a module in your application for running migrations (`lib/<app_name>_web/render_release.ex`):

```
defmodule Render.Release do
  @moduledoc """
    Responsible for custom release commands
  """
  @app :<app_name>

  def migrate do
    # Allows the migration script to connect to a database using SSL.
    Application.ensure_all_started(:ssl)

    for repo <- repos() do
      {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :up, all: true))
    end
  end

  def rollback(repo, version) do
    # Allows the migration script to connect to a database using SSL.
    Application.ensure_all_started(:ssl)

    {:ok, _, _} = Ecto.Migrator.with_repo(repo, &Ecto.Migrator.run(&1, :down, to: version))
  end

  defp repos do
    Application.load(@app)
    Application.fetch_env!(@app, :ecto_repos)
  end
end
```

- Change the deploy command for your render app to be `./build_and_migrate.sh` instead of `./build.sh`

## Using a Database that Requires SSL

Unless you're using a private database on Render, you'll want to connect to your PG instance using SSL. To do that, you've got to

- Uncomment the line in `releases.exs` that says `ssl: true` for your app's repo:

```
...
config :<app_name>, <AppName>.Repo,
  ssl: true, <-- this line, it's commented by default.
  url: database_url,
```

And then

- Add the `:ssl` application to `extra_applications` in `mix.exs`:

```
def application do
    [
      mod: {<AppName>.Application, []},
      extra_applications: [:logger, :runtime_tools, :ssl] <-- added :ssl to the end of this list.
    ]
  end
```

# Troubleshooting

If you run into an issue with Phoenix Live View breaking and reloading the page every few seconds, you might have enabled `force_ssl` in your endpoint, and it could be trying to redirect your web socket traffic to an `https` scheme. Which is strange. I ran into this once, and haven't found a great workaround for it.

## PgBouncer

If your database does pooling using `pg_bouncer` then open up `releases.exs` and add `prepare: :unnamed` to your repo config.

```
config :<app_name>, <AppName>.Repo,
  ssl: true,
  url: database_url,
  pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
  prepare: :unnamed <-- this line!
```