Deploying an Elixir Release to Gigalixir

Deploying an Elixir Release to Gigalixir

Deploy a Phoenix 1.6 to Gigalixir using Elixir 1.12 Releases

I'll show you how to deploy a Phoenix 1.6 application, with Elixir 1.12 Release to gigalixir.com

I'll use the Elixir Release we did before.

Configure the app for Gigalixir

Edit the runtime.exs file and add the url: line to the Endpoint section:

  config :saturn, SaturnWeb.Endpoint,
    url: [host: System.get_env("APP_NAME") <> ".gigalixirapp.com", port: 443],
    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

Add the config for the buildpacks that Gigalixir uses to compile and deploy the application.

Create a file named elixir_buildpack.config on the root of the project and put this:

erlang_version=24.1.2
elixir_version=1.12.3

Create a phoenix_static_buildpack.config file in the root and put this:

node_version=14.15.4

Create a file in assets/package.json and put this:

{
    "scripts": {
        "deploy": "cd .. && mix assets.deploy && rm -f _build/esbuild"
    }
}

This one is to use npm to use mix to use esbuild to compile our assets and after deploying them, delete the intermediate files!

Create a .buildpacks file and put this:

https://github.com/HashNuke/heroku-buildpack-elixir
https://github.com/gjaldon/heroku-buildpack-phoenix-static
https://github.com/gigalixir/gigalixir-buildpack-releases.git

Ok, enough changes. I am creating a branch named gigalixir-deployment and committing all these changes to it:

git checkout -b gigalixir-deployment
git add .
git commit -m "Deploying to Gigalixir"
git push -u origin gigalixir-deployment

Gigalixir setup

Install the gigalixir CLI

brew tap gigalixir/brew
brew install gigalixir

Crete an account in Gigalixir and login

gigalixir signup
gigalixir login

Create a Gigalixir application:

export APP_NAME=$(gigalixir create)

Created app: harsh-some-cats.
Set git remote: gigalixir.

Verify your app is created:

gigalixir apps

[
  {
    "cloud": "gcp",
    "region": "v2018-us-central1",
    "replicas": 0,
    "size": 0.3,
    "stack": "gigalixir-20",
    "unique_name": "harsh-some-cats",
    "version": 2
  }
]

This command also creates a new remote in your git repo, pointing to gigalixir. Check it:

git remote -v

gigalixir    https://git.gigalixir.com/harsh-some-cats.git/ (fetch)
gigalixir    https://git.gigalixir.com/harsh-some-cats.git/ (push)

Provision a database

Let's create a database for our app. This is the free plan so is not suitable for production but it will be good for testing.

gigalixir pg:create --free

You can check if the database is running with this command:

gigalixir pg

Finally, let's see the environment variables that Gigalixir created for us:

gigalixir config

You should see something like this:

{
  "DATABASE_URL": "ecto://<some user>:<some password>@postgres-free-tier-v2020.gigalixir.com:5432/<some database name>",
  "POOL_SIZE": "2"
}

As you see DATABASE_URL and POOL_SIZE are automatically created. Our app also needs the SECRET_KEY_BASE, PORT and APP_NAME but those will be automatically provided when the app starts, we don't need to worry about them.

Deploy the application

To deploy to Gigalixir, we must push our master branch to the gigalixir remote. Gigalixir only builds the master branch and ignore others. We use gigalixir-deployment as our main branch, so we need to push our branch changes to the master branch on the gigalixir remote:

git push gigalixir gigalixir-deployment:master

This will start the building of the release on the gigalixir build servers.

You can see the status with gigalixir ps:

{
  "cloud": "gcp",
  "pods": [
    {
      "lastState": {},
      "name": "harsh-some-cats-77d577b7cd-2s9c2",
      "sha": "5dd02b3af6fc7958615b9ee2cbcd6af934845506",
      "status": "Healthy",
      "version": "4"
    }
  ],
  "region": "v2018-us-central1",
  "replicas_desired": 1,
  "replicas_running": 1,
  "size": 0.3,
  "stack": "gigalixir-20",
  "unique_name": "harsh-some-cats"
}

When the build is finished, the app is deployed and started and you'll see log lines like these:

remote: Creating release.
remote: Starting zero-downtime rolling deploy.
remote: Please wait a minute for the new instance(s) to roll out and pass health checks.
remote: For troubleshooting, See:      http://gigalixir.readthedocs.io/en/latest/main.html#troubleshooting
remote: For help, contact:             help@gigalixir.com
remote: Try hitting your app with:     curl https://harsh-some-cats.gigalixirapp.com/
remote: Check your app logs with:      gigalixir logs -a harsh-some-cats
remote: Check deploy status with:      gigalixir ps -a harsh-some-cats
remote: Updated property [core/account].
To https://git.gigalixir.com/harsh-some-cats.git/
 * [new branch]      gigalixir-deployment -> master

You can open your app in your browser by running:

gigalixir open

And you'll see the familiar home screen:

Elixir release running on Gigalixir

Opening a remote console and running migrations

First we need to add our ssh public key so that we can connect securely:

gigalixir account:ssh_keys:add "$(cat ~/.ssh/id_rsa.pub)"

Opening a remote console

gigalixir ps:remote_console

Erlang/OTP 24 [erts-12.1.2] [source] [64-bit] [smp:8:1] [ds:8:1:10] [async-threads:1] [jit]

Interactive Elixir (1.12.3) - press Ctrl+C to exit (type h() ENTER for help)
iex(harsh-some-cats@10.56.18.206)1> ls
.bashrc           .profile          .profile.d        bin               erts-12.1.2
lib               releases          saturn.tar.gz

Running migrations

First, let's watch the logs:

gigalixir logs

Then, in another terminal, run:

gigalixir ps:migrate

Connection to v2018-us-central1.gcp.ssh.gigalixir.com closed.

You should see something like this:

2021-11-02T22:45:07.937626+00:00 harsh-some-cats[b'harsh-some-cats-77d577b7cd-2s9c2']: web.1  | 22:45:07.937 [info] Running SaturnWeb.Endpoint with cowboy 2.9.0 at :::4000 (http)
2021-11-02T22:45:07.938503+00:00 harsh-some-cats[b'harsh-some-cats-77d577b7cd-2s9c2']: web.1  | 22:45:07.938 [info] Access SaturnWeb.Endpoint at http://harsh-some-cats.gigalixirapp.com:443
2021-11-02T22:47:27.795085+00:00 harsh-some-cats[b'harsh-some-cats-77d577b7cd-2s9c2']: web.1  | 22:47:27.794 request_id=6ae142c1367400361510a08fb8000235 [info] GET /
2021-11-02T22:47:27.799510+00:00 harsh-some-cats[b'harsh-some-cats-77d577b7cd-2s9c2']: web.1  | 22:47:27.798 request_id=6ae142c1367400361510a08fb8000235 [info] Sent 200 in 4ms
2021-11-02T22:48:38.509918+00:00 harsh-some-cats[b'harsh-some-cats-77d577b7cd-2s9c2']: web.1  | 22:48:38.508 request_id=bbc52891b40f8bb8ec1c6e96b766c8fd [info] GET /
2021-11-02T22:48:38.509940+00:00 harsh-some-cats[b'harsh-some-cats-77d577b7cd-2s9c2']: web.1  | 22:48:38.509 request_id=bbc52891b40f8bb8ec1c6e96b766c8fd [info] Sent 200 in 1ms
2021-11-02T22:53:33.926744+00:00 harsh-some-cats[b'harsh-some-cats-77d577b7cd-2s9c2']: web.1  | 22:53:33.926 [info] Migrations already up

That's it.

Source code

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

About

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

Photo by Christina @ wocintechchat.com on Unsplash