Deploying a Phoenix App with Elixir on Deployxa: A Complete Guide | Deployxa

Phoenix is the leading Elixir web framework, known for real-time features and performance. Here is how to deploy a Phoenix app on Deployxa.

← Back to Dispatch Articles
Engineering Log

Deploying a Phoenix App with Elixir on Deployxa: A Complete Guide

Phoenix is the leading Elixir web framework, known for real-time features and performance. Here is how to deploy a Phoenix app on Deployxa.

Deploying a Phoenix App with Elixir on Deployxa

Phoenix is the leading Elixir web framework, known for its real-time features (via LiveView and Channels) and excellent performance (via the Erlang VM). It is a favorite of teams building realtime apps (chat, collaboration, dashboards) and high-traffic APIs. But deploying Phoenix has traditionally required writing a Dockerfile (to compile the Elixir code and run it with the Erlang VM), configuring the release, and handling the database connection. Deployxa's zero-config engine eliminates all of that, detecting Phoenix from your mix.exs and configuring the deployment. Here is how to deploy a Phoenix app on Deployxa.

The direct answer is that Deployxa auto-detects Phoenix from your mix.exs (which includes phoenix). It configures the build and start commands: the build command is mix deps.get && mix compile && mix release, the start command is _build/prod/rel/myapp/bin/myapp start, and the runtime is Elixir 1.16 with Erlang 26. You do not write a Dockerfile, you do not configure the release manually, and you do not manage the Erlang VM. The platform handles all of it, just as it does for Spring Boot and Flask apps.

Why Phoenix Is a Great Choice for Realtime Apps

Three reasons explain why Phoenix is a great choice for realtime apps. First, its LiveView feature lets you build realtime, interactive UIs without writing JavaScript, which is a significant productivity boost. For apps that need realtime features (chat, collaboration, dashboards), LiveView is hard to beat. Second, its Channels feature (built on the Erlang VM's process model) handles millions of concurrent WebSocket connections, which makes Phoenix ideal for high-concurrency realtime apps. Third, its performance is excellent. The Erlang VM is designed for high-concurrency, fault-tolerant systems, which means Phoenix apps are fast and reliable. For more on realtime features, see our article on running long-lived WebSockets in Node.js and Go.

The Architecture: Phoenix + Erlang VM + Container

Here is how Deployxa deploys a Phoenix app.

The Phoenix container

The ingestion service detects Phoenix from your mix.exs. It configures the build and start commands:

  • Build command: mix deps.get && mix compile && mix release
  • Start command: _build/prod/rel/myapp/bin/myapp start
  • Runtime: Elixir 1.16 with Erlang 26

The release configuration

Phoenix releases are self-contained packages that include the compiled code, the Erlang VM, and all dependencies. The release is configured via config/runtime.exs, which reads environment variables at runtime.

The reverse proxy

Traefik v3 routes traffic from your custom domain to the Phoenix container, with automatic SSL via Let's Encrypt.

Step-by-Step: Deploying a Phoenix App

Here is the exact workflow for a typical Cursor-generated Phoenix app.

Step 1: Create your Phoenix app

mix phx.new my_app
cd my_app
mix deps.get

Step 2: Configure runtime.exs

# config/runtime.exs
import Config

if config_env() == :prod do
  database_url = System.get_env("DATABASE_URL") ||
    raise "DATABASE_URL is not set"

  secret_key_base = System.get_env("SECRET_KEY_BASE") ||
    raise "SECRET_KEY_BASE is not set"

  config :my_app, MyApp.Repo,
    url: database_url,
    pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")

  config :my_app, MyAppWeb.Endpoint,
    server: true,
    url: [host: System.get_env("PHX_HOST") || "localhost", port: 443, scheme: "https"],
    http: [ip: {0, 0, 0, 0}, port: String.to_integer(System.get_env("PORT") || "4000")],
    secret_key_base: secret_key_base
end

Step 3: Create a simple controller

# lib/my_app_web/controllers/page_controller.ex
defmodule MyAppWeb.PageController do
  use MyAppWeb, :controller

  def index(conn, _params) do
    json(conn, %{message: "Hello, World!"})
  end

  def health(conn, _params) do
    json(conn, %{status: "ok"})
  end
end

Step 4: Add routes

# lib/my_app_web/router.ex
defmodule MyAppWeb.Router do
  use MyAppWeb, :router

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/", MyAppWeb do
    pipe_through :api
    get "/", PageController, :index
    get "/health", PageController, :health
  end
end

Step 5: Push to GitHub

git init
git add .
git commit -m "phoenix app"
git remote add origin https://github.com/yourname/my_app.git
git push -u origin main

Step 6: Connect to Deployxa

In the Deployxa dashboard, connect your repository. Deployxa auto-detects Phoenix:

[ingest] Detected Elixir project
[ingest] Framework: phoenix
[ingest] Runtime: elixir 1.16, erlang 26
[ingest] Build command: mix deps.get && mix compile && mix release
[ingest] Start command: _build/prod/rel/my_app/bin/my_app start
[ingest] Port: $PORT

Step 7: Configure environment variables

In the Deployxa dashboard, add:

  • DATABASE_URL: your Postgres connection string (e.g., ecto://user:pass@host:5432/myapp)
  • SECRET_KEY_BASE: a strong secret (generate with mix phx.gen.secret)
  • PHX_HOST: your app's domain (e.g., myapp.com)

The pre-flight scanner will warn you if any are missing. For more on environment variables, see our article on the vibe coder's guide to environment variables.

Step 8: Deploy

Click Deploy. The build compiles the Elixir code and creates a release, the container starts the release, and your app is live within 60 to 90 seconds.

Step 9: Add a custom domain

Add a custom domain in the Deployxa dashboard. SSL is provisioned automatically.

Step 10: Verify with deployxa doctor

Run deployxa doctor to verify health. The 14-point readiness engine checks SSL, DNS, environment variables, health endpoints, and container status.

Common Pitfalls and Troubleshooting

The first pitfall is the PORT environment variable. Phoenix apps typically listen on port 4000 by default, but Deployxa assigns a dynamic port via the PORT environment variable. The fix is to set http: [ip: {0, 0, 0, 0}, port: String.to_integer(System.get_env("PORT") || "4000")] in runtime.exs. The second pitfall is the SECRET_KEY_BASE. Phoenix requires a strong secret key base in production, which AI assistants often leave as a default or weak value. The fix is to generate a strong secret with mix phx.gen.secret and set it as the SECRET_KEY_BASE environment variable. The third pitfall is the database URL format. Phoenix uses Ecto, which uses a different URL format from other frameworks (e.g., ecto:// instead of postgresql://). The fix is to use the Ecto format in your DATABASE_URL environment variable. The fourth pitfall is the release configuration. Phoenix releases need to be configured via config/runtime.exs (not config/prod.exs), because runtime.exs is evaluated at runtime (when environment variables are available). The fix is to put your environment-variable-dependent configuration in runtime.exs. The fifth pitfall is the Erlang cookie. Phoenix releases use an Erlang cookie for clustering, which needs to be set consistently across all instances. The fix is to set the ERL_AFLAGS environment variable with the cookie (e.g., -setcookie my-cookie).

Performance: Phoenix vs Node.js vs Go

Phoenix, Node.js, and Go are three leading choices for realtime apps. Phoenix (via the Erlang VM) handles millions of concurrent WebSocket connections, which makes it ideal for high-concurrency realtime apps. Node.js handles thousands of concurrent connections (via the event loop), which is sufficient for most apps. Go handles tens of thousands of concurrent connections (via goroutines), which is between Phoenix and Node.js. For high-concurrency realtime apps, Phoenix is the best choice. For apps that need the Node.js ecosystem, Node.js is the better choice. For apps that need maximum performance and efficiency, Go is the better choice. Deployxa supports all three equally, with the AutoRepairService and the zero-config engine handling each framework automatically. For more on performance, see our article on SPA vs SSR hardware sizing. For more on realtime features, see our article on running long-lived WebSockets.

Advanced Phoenix Patterns

Beyond the basics, Phoenix apps benefit from several advanced patterns. The first is LiveView. LiveView lets you build realtime, interactive UIs without writing JavaScript, which is a significant productivity boost. The second is Channels. Channels (built on the Erlang VM's process model) handle millions of concurrent WebSocket connections, which makes Phoenix ideal for high-concurrency realtime apps. The third is Ecto. Ecto is Phoenix's database wrapper, which provides a DSL for queries and migrations. The fourth is Phoenix Presence. Presence tracks which users are online, which is useful for chat apps and collaboration tools. The fifth is testing. Phoenix has excellent testing support (via ExUnit), which makes it easy to write unit and integration tests. For more on testing, see our article on the testing void. For more on Phoenix deployment, see our articles on deploying a Ruby on Rails app and deploying a Flask app with Gunicorn.

Conclusion: Phoenix Without the Configuration

Phoenix is the leading Elixir web framework, and deploying it should be as simple as pushing to Git. Deployxa's zero-config engine makes it so: no Dockerfile, no release configuration, no Erlang VM management. Stop configuring releases and start shipping.

Ready to deploy your Phoenix app? Drag your project to Deployxa Drop for an instant live preview, or install the CLI with npm i -g @deployxa/cli and deploy from your terminal. For more on framework deep-dives, see our articles on deploying a Spring Boot app and deploying an Express app with PM2. Learn about deploying a Ruby on Rails app and deploying a Flask app with Gunicorn in our companion articles. Explore our free developer tools to speed up your workflow.

Ready to deploy with Deployxa?

Deploy your apps globally with automatic SSL and AI diagnostics.

Start Free Now