Part 9 · 1 chapters · ~8 min
In Production: What Elixir Is Paired With
mix releases and runtime configuration, Docker and Fly.io or Kubernetes deployment, libcluster for node discovery, distributed Erlang and its security (cookies, TLS distribution), Oban for durable jobs, Postgres with PgBouncer (and prepared statement caveats), telemetry, OpenTelemetry and PromEx, Sentry, hot code upgrades versus rolling deploys, and WebSocket-aware load balancing.
10
A Phoenix stack
code
# config/runtime.exs: read at boot, not compile time
config :ledger, Ledger.Repo, url: System.fetch_env!("DATABASE_URL"), pool_size: String.to_integer(System.get_env("POOL_SIZE", "10")),
prepare: :unnamed # needed behind PgBouncer in transaction mode
# libcluster on Kubernetes
config :libcluster, topologies: [k8s: [strategy: Cluster.Strategy.Kubernetes.DNS, config: [service: "ledger-headless", application_name: "ledger"]]]
# Oban: enqueue in the same transaction as the business write
Ecto.Multi.new()
|> Ecto.Multi.insert(:payout, Payout.changeset(attrs))
|> Oban.insert(:submit, fn %{payout: p} -> Ledger.Workers.SubmitPayout.new(%{payout_id: p.id}) end)
|> Repo.transaction()Hot code upgrades, a famous BEAM feature, let a running system load new code without restarting; most teams use ordinary rolling deploys instead because upgrades are complex to prepare. Distributed Erlang trusts all connected nodes completely: keep clusters on private networks and use TLS distribution where needed.
IN PRODUCTION: WHAT ELIXIR IS PAIRED WITH
a typical Phoenix deployment
swipe the figure sideways, or tap expand for full screen
1/4
releases
mix release builds a self-contained package including the BEAM; configuration comes from runtime.exs and environment variables at boot (Config course).
self-contained releasesruntime.exs