← Back to Guides
Profile image for Daniel Cosby
Published 18th December 2024

Deploy your Phoenix Elixir application on Northflank

What is Phoenix?

Phoenix is a web development framework to build rich, interactive web applications, with components and concepts likened to Ruby on Rails or Python's Django. It is written in Elixir, a functional programming language.

Phoenix has great support for Docker, allowing you to create releases for your Phoenix app with a single command to generate database migrations and a production-ready Dockerfile.

This guide will take you through setting up a new realtime, interactive Phoenix HTML application with PostgreSQL, and building and deploying it on Northflank. You can also use Phoenix to build static websites, headless services, or deploy your application with a MySQL database instead. See Phoenix's up and running guide for more configuration options.

We'll also look at more advanced Northflank features that you can use to grow your project into production - scale up your resources, manage releases, and configure your workflow with infastructure-as-code (IaC), templates and release flows.

Requirements & resources

You should sign up for an account on Northflank if you haven't already, and link a version control system provider such as GitHub, GitLab, or Bitbucket.

If you don't have it already, install Elixir on your machine.

You'll also need to install and run PostgreSQL for local development. Linux users should install inotify-tools for live reloading.

Getting started with Phoenix

If you already have a Phoenix application you'd like to deploy, you can skip to the next section.

Phoenix includes an application generator which makes it easy to get started on a new project. It will generate all the files required to begin creating an application or website that integrates with a PostgreSQL database.

  1. Open a shell and navigate to the directory where you want to create your new project
  2. Run mix archive.install hex phx_new to install the Phoenix application generator
  3. Run mix phx.new hello to create a new Phoenix application and install the dependencies.
  4. Open your new Phoenix project in your preferred IDE and find the config/dev.exs file. It should contain the configuration below. Update the values here to reflect your local PostgreSQL connection details:
config :hello, Hello.Repo,
  username: "postgres",
  password: "postgres",
  hostname: "localhost",
  database: "hello_dev",
  stacktrace: true,
  show_sensitive_data_on_connection_error: true,
  pool_size: 10
  1. In the shell in your Phoenix project, run mix ecto.create. This will create your database, as long as the Postgres user has the necessary permissions.

  2. Run mix phx.server to start your development server with live reloading. You can view it in your web browser at http://localhost:4000.

    Mix commands to generate and start a new Phoenix project

Create a Phoenix Dockerfile with Mix

Phoenix comes with built-in functionality to make containerising your application as simple as possible. You can run the shell command mix phx.gen.release --docker in your Phoenix project to create a new release and generate a production-ready Dockerfile in your project. Your Dockerfile should look something like this.

If you have Docker installed locally you can run docker build . to build your image.

Build and deploy your Phoenix application on Northflank

Building and deploying your Phoenix application on Northflank is as easy as developing it locally, if not easier!

To deploy your Phoenix app to Northflank you will create:

  • A PostgreSQL addon
  • A secret group
  • A combined service

You'll need to push your Phoenix project to a Git repsoitory, such as on GitHub. Provided you have linked your VCS provider to your Northflank team, your repository should be private. Your repository will look something like this.

The repository of a Phoenix project showing the generated Dockerfile

Create a Northflank project

First you'll create a Northflank project to contain the resources for your Phoenix application.

Resources in projects can securely communicate with each other, and you can deploy projects in different regions to make sure they're close to you or your users. You can also choose to deploy into Northflank's managed cloud, or bring your own cloud provider account.

Select project from the create new menu in your Northflank team, call it Phoenix and select a region close to you.

Create a PostgreSQL addon

The default Phoenix application expects Postgres. Northflank allows you to create a managed, stateful Postgres instance that is scalable and highly-available, created in minutes with backups, disaster recover, and logs and metrics available at your fingertips.

  1. In your new project create an addon

  2. Select PostgreSQL, call it Phoenix data, and select the most recent version

  3. Disable TLS, as the template Phoenix application is not configured to use TLS.

  4. You can deploy with the default compute plan, which is 0.5vCPU and 1GB memory, but if you need more resources for production select another plan

  5. Click create addon

    Creating a PostgreSQL addon on Northflank

Your Postgres addon will begin provisioning and scaling up, which may take a minute.

Create a secret group

Phoenix requires a connection string to access the Postgres database, as well as a secret key base to generate secrets for encrypting and signing data (for example for cookies and tokens).

Create a secret group to provide this environment variable to your application, and link your addon's connection details. These secrets are securely encrypted and injected during builds and deployments on container startup.

You can add more secrets here later for all your environment variables, secrets, and secret files. Secret groups can be inherited by multiple services and jobs to reduce duplication.

  1. In your Northflank project create a new secret group and call it Phoenix secrets. You can leave the default configuration for now.

  2. Click add variable and enter SECRET_KEY_BASE as the key 3and click the key button in the editor. Generate a secret value with a length of at least 64 and copy and paste it to the value field.

  3. Next, in the linked addons section, click show addons and then click configure on your PostgreSQL addon

  4. Click the POSTGRES_URI to link the connection string to the secret group, and add DATABASE_URL as an alias by clicking the add button

  5. Click create secret group to make these environment variables available to resources in your project

    Creating a secret group for environment variables on Northflank

Create a combined service

Next you'll create a combined service to build your application from your Git repository and deploy it in a single service.

A combined service gives you continuous integration and deployment out of the box. When you create a combined service you'll select a Git repository and branch from your linked VCS. When you push changes to that branch your combined service will automatically pull your repository, run a Docker build, push to the Northflank container registry, and finally completes a rolling restart on the Northflank cloud.

  1. In your Northflank project create a new combined service and name it Phoenix

  2. Select your repository from the drop-down list and choose the main branch

  3. Choose Dockerfile as the build type

  4. Click add port in Networking. Enter 4000 for the port,HTTP as the protocol. Enable publicly expose this port to the internet and name it app so you can view the website when it's deployed.

  5. Click create service

    Creating a combined service to build and deploy an application on Northflank

    A combined service overview on Northflank

Manage your combined service

Once you’ve created your combined service, you’ll be redirected to its dashboard. Here, you’ll notice that a new build has been triggered. Once the build completes, it will automatically deploy. You can access your application at the code.run domain provided by Northflank, which is displayed prominently in the header.

A new Phoenix project deployed on Northflank

From the combined service overview, you can monitor the progress of builds, check the status of deployed containers, and scale, pause and restart your service. Access more configuration options and deployment information from the sidebar.

Observability, scaling and resource management

To troubleshoot or inspect build and runtime containers, click on the build or deployment to view real-time logs and metrics, healthchecks, shell access.

These tools are invaluable for diagnosing issues, maintaining uptime, and ensuring your service has the necessary resources to meet demand.

On the resources page you can increase compute resources, which is the vCPU and memory allocated to each container, and scale the number of containers horizontally running simultaneously to handle increased demand. You can even enable autoscaling to handle this automatically, based on RPS, CPU and memory usage. By leveraging these features you can optimize your application’s performance and maintain reliability under varying load conditions.

Deploy and release Phoenix with infrastructure as code

You can implement an infrastructure as code approach to managing your deployments and infrastructure with Northflank templates. You can define reproducible workflows to create and update resources, run your release processs, and create ephemeral preview environments to deploy pull requests for review.

This part of the guide will take you through the steps to create a template for your Phoenix project so, and how you can run releases in a single click.

Create a template for your Phoenix project

  1. Create a new template in your team, name it Phoenix and open the visual editor
  2. The template will have a project and workflow nodes predefined. Enter the name Phoenix for your project, and select a region, and save node.
  3. Drag an addon node from the nodes panel on the right into the sequential workflow that has a project ID.
    1. Give it a name and select the latest version
    2. Disable TLS
    3. Click save node
  4. Drag a secret group node and drop it directly below the addon in the template.
    1. Give it a name, add the SECRET_KEY_BASE variable and enter ${args.SECRET_KEY_BASE} as the value. This will be explained later.
    2. Click show addons and configure the addon from the template with DATABASE_URL as the alias for POSTGRES_URI. 3. Click save node
  5. Drag an await condition node below the secret group node in the template.
    1. Choose addon for the resource kind
    2. Select the reference to your addon node in the resource field
    3. Set it to wait until the resource is running and save node
  6. Drag a combined service node directly underneath the secret group node in the template.
    1. Give it a name and select your Phoenix application's Git repository. Choose the branch you want to build.
    2. Select Dockerfile as the build type
    3. Scroll down to the networking section and click add port. Enter 4000, select HTTP as the protocol, and enable publicly expose this port to the internet.
    4. Click save node
  7. Navigate to the template settings and edit the argument overrides. Enter SECRET_KEY_BASE as the key, then click the key button in the editor. Generate a secret value with a length of at least 64 and copy and paste it to the value field. This will provide your secret securely without saving it in the template code, making it accessible via the arguments object: "${args.SECRET_KEY_BASE}".
  8. Finally click create template to save your template in your team

You can run the template and it will proceed through each node in sequence, creating the project, and then the addon and secret group. The await condition node will pause the template until the addon is ready, so that when the Phoenix application is deployed it can immediately connect to the database.

If your project already exists and you run the template it will patch any resources with the same names, and change any configuration values to those in the template, such as number of instances, compute plan, or secret values. You can use this to update your projects.

You can also use arguments and set overrides for your template, both to provide secrets securely and to use your template to deploy different environments or configurations of your project.

A template to create a Phoenix project on Northflank

Run releases

Phoenix has built-in tools to easily manage releases using Docker.

You can generate releases with the command mix phx.gen.release --docker, which creates a Dockerfile for your release that includes any required database migrations. This will create a release for the environment (set by the build argument of MIX_ENV).

This will then provide you with different commands to start your containers in your built image. For example, for the prod environment:

# To start your system
    /app/bin/app start

    # To start your system with the Phoenix server running
    /app/bin/server

    # To run migrations
    /app/bin/migrate

To run migrations you could add a job using your built image to run /app/bin/migrate, or use a command override to run a migration before starting your application:

CMD ["sh", "-c", "/app/bin/migrate && /app/bin/server"]

To share your built image between your deployment and a job, you'll need to build it using a build service, rather than a combined service, which we'll cover in the next section. You can also learn more about running migrations on Northflank here.

Manage releases with release flows

Using a combined service is a convenient and simple way to build and deploy quickly. But what if you have a more complex workflow to manage your releases? Perhaps you need to back up your database before running migrations, and want to make sure you don't deploy a new release to production if the migration fails.

You can programmatise your release workflows using a Northflank pipeline with release flows. These allow you to manage your resources for different environments, and to create release workflows as templates.

Instead of using a combined service, you'll need to build and deploy your application in separate build and deployment services. You can use one build service to deploy to multiple jobs and services, and promote images from one deployment to another.

A release flow for your Phoenix application might consist of:

  1. An addon backup node to back up your database

  2. A job to run your migration against the database for this environment

  3. A promote deployment node to move your deployed image from one stage to the next

    A release flow for a Phoenix environment

Deploy your Phoenix application into AWS, GCP, Azure with BYOC

You can integrate your cloud account with Northflank to deploy into other cloud providers, such as GCP, AWS, or Azure.

This will let you deploy Northflank-managed clusters into your chosen cloud provider and fine-tune your infrastructure and networking to suit your requirements.

You can deploy the same workloads and projects across any cloud provider, manually or using templates, without having to change a single configuration detail.

Develop locally using your Northflank addon

You can securely access your resources using the Northflank CLI, without exposing them to the public.

Install the Northflank CLI with the following commands:

npm i -g @northflank/cli
# or
yarn global add @northflank/cli

You can now copy the forward addon command from your addon's overview, and run the command in a terminal on your machine, it looks something like this:

sudo northflank forward addon --projectId [project-name] --addonId [addon-name]

You'll need to enter your password as the forward command is run with root privileges so that it can write to your hosts file. While running, you'll be able to access your addon the same as deployments inside your Northflank project.

After running the command you'll be able to access your Northflank addon using the connection details shown in the addon overview, and provide these to any tools or applications on your local machine.

Deploy your Phoenix application on Northflank for free

Northflank allows you to deploy your code and databases within minutes. Sign up for a Northflank account and create a free project to get started.

  • Deployment of Docker containers
  • Create your own stateful workloads
  • Persistent volumes
  • Observe & monitor with real-time metrics & logs
  • Low latency and high performance
  • Backup, restore and fork databases
Share this article with your network
X