> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sevalla.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> These are the docs for Sevalla, a platform for deploying applications, databases, static sites, object storage and load balancers. The dashboard is at https://app.sevalla.com.
> Bold text in steps is an exact dashboard label.
> To act on a Sevalla account, prefer the Sevalla MCP server (https://mcp.sevalla.com/mcp, see https://docs.sevalla.com/ai-agents/overview.md), then the Sevalla CLI (https://docs.sevalla.com/developer-tools/cli.md), then the REST API (https://api-docs.sevalla.com, OpenAPI spec at https://api.sevalla.com/v3/openapi.json).
> Every page index is at https://docs.sevalla.com/llms.txt.

# Deploy Elixir applications

> How Elixir applications build and run on Sevalla with Ingot: Mix releases, Elixir and Erlang/OTP versions, the PORT variable, migrations, clustering and Dockerfiles.

An Elixir application runs on Sevalla as an [application](https://docs.sevalla.com/applications/overview.md): Sevalla builds a Mix release from your Git repository, a self-contained folder with the compiled code and its own copy of the Erlang runtime, and runs it as processes. The web process serves HTTP with Phoenix or Plug, background workers run job queues, and jobs run Ecto migrations before each deployment.

## Framework guides

> **[Phoenix](https://docs.sevalla.com/guides/elixir/phoenix.md)**
>
> Deploy Phoenix 1.8 with Ecto and PostgreSQL, migrations in a job, and LiveView over WebSockets.

## How Elixir applications run on Sevalla

| Part | On Sevalla |
| - | - |
| Build | [Ingot](https://docs.sevalla.com/applications/builds/ingot.md), Sevalla's builder, by default. It recognizes an Elixir application by `mix.exs` and always builds a release in the `prod` environment: `mix deps.get --only prod`, `mix deps.compile`, `mix compile`, then `mix release`. Umbrella projects build from the root. |
| Package manager | Mix and Hex, from `mix.lock`. Ingot fetches the dependencies with `mix.exs`, `mix.lock` and `config/` alone, so that layer is reused while only code changes. Without `mix.lock`, the build log warns that versions can change. |
| Elixir and Erlang/OTP versions | Elixir 1.20 with Erlang/OTP 29, Ingot's default line, unless the project sets another. See [Pin the Elixir version](#pin-the-elixir-version). |
| Assets | When `mix.exs` defines an `assets.deploy` alias, as Phoenix does, Ingot runs `mix compile && mix assets.deploy`. npm packages in `assets/package.json` are installed with `npm ci` when `assets/package-lock.json` exists, `npm install` otherwise. |
| Image | The release runs on Debian slim, the release the Elixir image is built on (`debian:trixie-slim` for Elixir 1.20), with root certificates, time zone data, OpenSSL and the SCTP library, and `LANG=C.UTF-8`. Elixir, Mix and Hex aren't in the image. |
| Start command | `/app/bin/<app> start`, where `<app>` is the `app:` name in `mix.exs`. For Phoenix, Ingot sets `PHX_SERVER=true`, so the release serves HTTP. A start command that runs `mix` fails the build, because Mix isn't in the image. See [Set the start command](https://docs.sevalla.com/applications/builds/ingot.md#set-the-start-command). |
| Port | Sevalla sets `PORT` to the web process's port, `8080` by default. Phoenix's `config/runtime.exs` reads it. |
| Configuration | `config/runtime.exs` runs each time the release starts, so read environment variables there. `config/config.exs` and `config/prod.exs` run during the build, and the build log warns when they read an environment variable, because its build-time value is then fixed in the image. |
| Migrations | A job with the start policy **Before deployment** that runs `/app/bin/migrate`, the script `mix phx.gen.release` adds. Ingot recommends it when `rel/overlays/bin/migrate` exists, or `/app/bin/<app> eval <Module>.migrate` when `lib/<app>/release.ex` defines `migrate`. Ingot never runs migrations itself. |
| Background work | A background worker process from the same image, or jobs that run inside the web process, such as Oban queues. |
| Scheduled tasks | A cron job that runs a function in the release with `/app/bin/<app> eval`. |
| Clustering | Not available. Instances don't form an Erlang cluster: the web process's internal hostname resolves to one service address, not to each instance, so `DNSCluster` can't find the other instances. See [Run more than one instance](https://docs.sevalla.com/guides/elixir/phoenix.md#run-more-than-one-instance). |
| Databases | PostgreSQL, MySQL, MariaDB, Redis or Valkey on Sevalla, reached over an [internal connection](https://docs.sevalla.com/databases/connect.md#connect-an-application) that adds the connection details as environment variables. Ecto accepts the `postgres://` URL in `DB_URL`; rename it to `DATABASE_URL` for Phoenix. |
| Files | The filesystem resets on every deployment. Keep uploads in [object storage](https://docs.sevalla.com/object-storage/overview.md), or attach a [disk](https://docs.sevalla.com/applications/disks.md). |
| Other build strategies | A [Dockerfile](https://docs.sevalla.com/applications/builds/dockerfile.md), or another [build strategy](https://docs.sevalla.com/applications/builds/overview.md), on the application's **Settings** tab |

Every process (web, worker, cron job and job) runs from the same image, each with its own start command. See [Processes](https://docs.sevalla.com/applications/processes.md).

## Pin the Elixir version

Ingot builds on Elixir 1.20 with Erlang/OTP 29, its default line, unless the project sets a version. It takes the Elixir version from the first of these that's set:

1. The `INGOT_ELIXIR_VERSION` environment variable, or `versions.elixir` in `ingot.json`.
2. The `elixir` line of `.tool-versions`, then mise's configuration. The suffix of an asdf version such as `1.20.4-otp-29` names the Erlang/OTP release it was compiled for and doesn't change the Elixir version.
3. The `elixir` requirement in `mix.exs`.

A requirement such as `"~> 1.20"` in `mix.exs` allows 1.20 and later 1.x lines: Ingot builds on its default line when the requirement allows it, otherwise on the newest maintained line that does. `"~> 1.20.0"` keeps the build on the 1.20 line. A line builds on the official image of its newest release, such as `elixir:1.20-otp-29`, so every new build picks up its fixes. An exact release, such as `1.20.4-otp-29` in `.tool-versions`, stays on that release, and the build log warns that its image won't receive security rebuilds. The build plan's **Elixir** row shows the version and where it came from.

The Erlang/OTP release comes with the Elixir image: the newest one that has an official image for that Elixir version. If you pin `erlang` in `.tool-versions` or mise's configuration, or in the `-otp-` suffix, Ingot compares it with the image's:

* An older release builds, with a warning such as `Erlang/OTP 28 is pinned in .tool-versions, but the Elixir 1.20 image comes with OTP 29`.
* A newer release fails the build, for example `Erlang/OTP 30 is pinned in .tool-versions, but the Elixir 1.20 image comes with OTP 29`: require a newer Elixir or pin an older Erlang/OTP.

Version files are read from the build path, then from each folder above it up to the repository root. See [Set the language version](https://docs.sevalla.com/applications/builds/ingot.md#set-the-language-version).

## Build with a Dockerfile

A Dockerfile for an Elixir application on Sevalla builds the release in the official `elixir` image of the line you develop with, then copies only the release into `debian:trixie-slim`, the Debian release that image is built on, with the libraries the Erlang runtime loads and a `/bin/sh` for start commands and the web terminal. Phoenix generates one with `mix phx.gen.release --docker`; the [Phoenix guide](https://docs.sevalla.com/guides/elixir/phoenix.md#deploy-with-a-dockerfile) shows it adapted for Sevalla, running as a numeric non-root user with the release's script as process 1, which handles `SIGTERM` itself.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.