Deploying Elixir, Phoenix apps on NodeChef - A complete step by step guide.

Deploying Elixir, Phoenix apps on NodeChef involves running a single command [nc deploy] after you complete the process of creating your application from the dashboard and configuring environment variables. You can also deploy by uploading your project folder from the dashboard if preferred over using the NodeChef CLI.

The below steps provide a complete guide on hosting your Elixir, Phoenix apps on the NodeChef bare metal cloud platform

Step 1. Create your application from the dashboard

Create a NodeChef account and verify your account by clicking on the link emailed to you after you completed the sign up form. Log into your acount. On the dashboard, click on Deployments. You will be presented with the Deploy app form. Enter a name for your app, select the 256 or 512 RAM container size and then select the desired database. You can change the RAM capacity of your container at anytime. You can freely experiment with container sizes as NodeChef charges by the hour. Choose between the US-East or EU-West data center and then click on the Launch Cluster button.

Create Elixir,Phoenix app on NodeChef

Step 2. Prepare your Phoenix app to run in the NodeChef environment

Every new Phoenix project ships with a config file config/prod.secret.exs which stores configuration. On NodeChef you can read configuration values from environment variables.

First, let’s make sure our secret key is loaded from NodeChef’s environment variables instead of config/prod.secret.exs by adding a secret_key_base line in config/prod.exs (remember to add a comma to the end of the preceding line):

config :hello, HelloWeb.Endpoint, load_from_system_env: true, url: [host: "", port: 80], cache_static_manifest: "priv/static/cache_manifest.json", secret_key_base: Map.fetch!(System.get_env(), "SECRET_KEY_BASE")

Then, we’ll add the production database configuration to config/prod.exs if applicable. If you selected to create a database in Step 1, NodeChef automatically sets the environment variable "DATABASE_URL" on your executing containers.

# Configure your database config :hello, Hello.Repo, adapter: Ecto.Adapters.Postgres, url: System.get_env("DATABASE_URL"), pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"), ssl: true

Now, let’s tell Phoenix to use our NodeChef URL and enforce SSL. You can find the NodeChef URL assigned to your app by clicking on App actions → Browse. You can then copy the hostname portion of the URL.

url: [scheme: "https", host: "", port: 443], force_ssl: [rewrite_on: [:x_forwarded_proto]],

Finally, we need to decrease the timeout for the websocket transport in lib/hello_web/channels/user_socket.ex:

defmodule HelloWeb.UserSocket do use Phoenix.Socket ... ## Transports transport :websocket, Phoenix.Transports.WebSocket, timeout: 45_000 ... end

This ensures that any idle connections are closed by Phoenix before they reach NodeChef’s 60-second timeout window.

Lastly, we’ll need to create a Procfile (a text file called “Procfile” in the root of our project’s folder) with the following line:

web: MIX_ENV=prod mix phx.server

Step 3. Setting up environment variables

You can set environment variables using a JSON file or from the dashboard. To set environment variables from the dashboard, on the task manager, find and click on App actions → Environment variables. You can then set all your environment variables and save your changes.

Create Environment variables on NodeChef

To set environment variables using a JSON file, create a file in the root of your project's folder with an example name envdev.json. You can then set your environment variables as seen below:

{ POOL_SIZE: 18, SECRET_KEY_BASE: "xvafzY4y01jYuzLm3ecJqo008dVnU3CN4f+MamNd1Zue4pXvfvUjbiXT8akaIF53" }

Step 4. Deploy the app

NodeChef provides two simple ways to deploy your app: By using the NodeChef CLI to upload your project or by using an intuitive dashboard to upload your project.

  • Using the NodeChef CLI.

    You will first need to install the NodeChef CLI. The CLI is written in Node.js and you need to have Node.js installed to proceed. After installing Node.js and from the command prompt or terminal, use the below command to install the NodeChef CLI.

    npm install -g nodechef-cli

    To deploy Phoenix apps, CD to your project folder and run the below command to deploy.

    nc deploy -i phoenix-hello-world -bp elixir,phoenix-static

    If you are deploying an Elixir app you do not have to include the phoenix-static buildpack, use the below command instead:

    nc deploy -i elixir-hello-world -bp elixir

    If you are using a JSON file to set your environment variables, include it with the deploy command using the -e option as seen below:

    nc deploy -i elixir-hello-world -bp elixir -e envdev.json

  • Using the dashboard

    Log into your account. From the dashboard, navigate to Deployments → Deployed Apps. Locate your app. Under ‘Actions Column, click on Cluster Actions. Then click on Deploy app code from the Cluster Actions drop down.

    Elixir, Phoenix static buildpack selection Deploy Elixir, Phoenix app

Troubleshooting compilation Errors

Occasionally, an application will compile locally, but not on NodeChef. The compilation error on NodeChef will look something like this:

== Compilation error on file lib/postgrex/connection.ex == could not compile dependency :postgrex, "mix compile" failed. You can recompile this dependency with "mix deps.compile postgrex", update it with "mix deps.update postgrex" or clean it with "mix deps.clean postgrex" ** (CompileError) lib/postgrex/connection.ex:207: Postgrex.Connection.__struct__/0 is undefined, cannot expand struct Postgrex.Connection (elixir) src/elixir_map.erl:58: :elixir_map.translate_struct/4 (stdlib) lists.erl:1353: :lists.mapfoldl/3 (stdlib) lists.erl:1354: :lists.mapfoldl/3

This has to do with stale dependencies which are not getting recompiled properly. It’s possible to force NodeChef to recompile all dependencies on each deploy, which should fix this problem. The way to do it is to add a new file called elixir_buildpack.config at the root of the application. The file should contain this line: