Inicio / Elixir / Phoenix Framework: Web en Tiempo Real / Deploy y Producción

Deploy y Producción

Releases, Docker, Fly.io, Gigalixir y hot upgrades.

Avanzado
🔒 Solo lectura
📖

Estás en modo lectura

Puedes leer toda la lección, pero para marcar progreso, hacer ejercicios y ganar XP necesitas una cuenta Pro.

Desbloquear por $9/mes

Deploy y Producción en Phoenix

Introducción

Phoenix ofrece múltiples estrategias de deploy gracias a Mix Releases y la BEAM VM. Desde contenedores Docker hasta plataformas especializadas como Fly.io, el ecosistema facilita llevar aplicaciones a producción.

Mix Release

Las releases empaquetan la aplicación en un binario autónomo:

# mix.exs
def project do
  [
    app: :my_app,
    releases: [
      my_app: [
        include_executables_for: [:unix],
        steps: [:assemble, :tar]
      ]
    ]
  ]
end

Generar y ejecutar una release:

# Compilar assets y crear release
MIX_ENV=prod mix assets.deploy
MIX_ENV=prod mix release

# Ejecutar
_build/prod/rel/my_app/bin/my_app start

Runtime Config

La configuración en producción se lee en tiempo de ejecución:

# config/runtime.exs
import Config

if config_env() == :prod do
  database_url = System.fetch_env!("DATABASE_URL")
  secret_key_base = System.fetch_env!("SECRET_KEY_BASE")

  config :my_app, MyApp.Repo,
    url: database_url,
    pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
    ssl: true,
    ssl_opts: [verify: :verify_none]

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

Docker Multistage

Dockerfile optimizado con build multietapa:

# Dockerfile
FROM hexpm/elixir:1.16.1-erlang-26.2.2-debian-bookworm-20240130-slim AS build

RUN apt-get update && apt-get install -y build-essential git nodejs npm
WORKDIR /app

ENV MIX_ENV=prod
COPY mix.exs mix.lock ./
RUN mix deps.get --only prod && mix deps.compile

COPY assets/ assets/
COPY lib/ lib/
COPY priv/ priv/
COPY config/ config/

RUN mix assets.deploy && mix compile && mix release

# --- Runtime ---
FROM debian:bookworm-slim AS runtime

RUN apt-get update && apt-get install -y libssl3 libstdc++6 locales \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY --from=build /app/_build/prod/rel/my_app ./

ENV LANG=es_ES.UTF-8
EXPOSE 4000
CMD ["bin/my_app", "start"]

Deploy en Fly.io

Fly.io es ideal para apps Phoenix con soporte nativo:

# Instalar flyctl e inicializar
fly launch

# fly.toml generado
[env]
  PHX_HOST = "mi-app.fly.dev"
  PORT = "8080"

[http_service]
  internal_port = 8080
  force_https = true

[[services.ports]]
  handlers = ["http"]
  port = 80

[[services.ports]]
  handlers = ["tls", "http"]
  port = 443

Comandos de deploy:

# Crear base de datos
fly postgres create --name mi-app-db
fly postgres attach mi-app-db

# Configurar secretos
fly secrets set SECRET_KEY_BASE=$(mix phx.gen.secret)
fly secrets set DATABASE_URL=postgres://...

# Deploy
fly deploy

# Ejecutar migraciones
fly ssh console -C "/app/bin/my_app eval 'MyApp.Release.migrate()'"

Gigalixir

Plataforma PaaS especializada en Elixir:

# Instalar CLI y crear app
pip install gigalixir
gigalixir create -n mi-app

# Configurar
gigalixir config:set SECRET_KEY_BASE=$(mix phx.gen.secret)
gigalixir pg:create --free

# Deploy via git
git remote add gigalixir https://git.gigalixir.com/mi-app.git
git push gigalixir main

# Migraciones
gigalixir run mix ecto.migrate

CI/CD con GitHub Actions

Pipeline automatizado de testing y deploy:

# .github/workflows/ci.yml
name: CI/CD
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_PASSWORD: postgres
        ports: ["5432:5432"]
    steps:
      - uses: actions/checkout@v4
      - uses: erlef/setup-beam@v1
        with:
          elixir-version: "1.16"
          otp-version: "26"
      - run: mix deps.get
      - run: mix test

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: superfly/flyctl-actions/setup-flyctl@master
      - run: flyctl deploy --remote-only
        env:
          FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}

Clustering con libcluster

Conectar nodos BEAM para distribución:

# mix.exs
{:libcluster, "~> 3.3"}

# config/runtime.exs
config :libcluster,
  topologies: [
    fly6pn: [
      strategy: Cluster.Strategy.DNSPoll,
      config: [
        polling_interval: 5_000,
        query: System.get_env("FLY_APP_NAME") <> ".internal",
        node_basename: System.get_env("FLY_APP_NAME")
      ]
    ]
  ]

# application.ex
children = [
  {Cluster.Supervisor, [topologies, [name: MyApp.ClusterSupervisor]]},
  MyApp.Repo,
  MyAppWeb.Endpoint
]

Monitoring con Telemetry

Instrumentación y métricas en producción:

defmodule MyAppWeb.Telemetry do
  use Supervisor
  import Telemetry.Metrics

  def metrics do
    [
      summary("phoenix.endpoint.start.system_time", unit: {:native, :millisecond}),
      summary("phoenix.router_dispatch.stop.duration", unit: {:native, :millisecond}),
      counter("phoenix.endpoint.stop.duration"),
      summary("my_app.repo.query.total_time", unit: {:native, :millisecond}),
      last_value("vm.memory.total", unit: :byte),
      last_value("vm.total_run_queue_lengths.total")
    ]
  end
end

Resumen

El deploy de Phoenix abarca Mix Releases para binarios autónomos, Docker multistage para contenedores, plataformas como Fly.io y Gigalixir, CI/CD automatizado con GitHub Actions, clustering con libcluster para distribución y monitoring con Telemetry. La BEAM VM garantiza alta disponibilidad y hot code upgrades en producción.

🔒

Ejercicio práctico disponible

Deploy y configuración de producción

Desbloquear ejercicios
// Deploy y configuración de producción
// Desbloquea Pro para acceder a este ejercicio
// y ganar +50 XP al completarlo

function ejemplo() {
    // Tu código aquí...
}

¿Te gustó esta lección?

Con Pro puedes marcar progreso, hacer ejercicios, tomar quizzes, ganar XP y obtener tu constancia.

Ver planes desde $9/mes