plugins/elixir-phoenix/skills/deploy/SKILL.md
Elixir/Phoenix deployment patterns — Dockerfile, fly.toml, runtime.exs, mix release, rel/ overlays. Use when configuring Fly.io, Docker, CI/CD, health checks, or production migrations.
npx skillsauth add oliver-kriska/claude-elixir-phoenix deployInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Quick reference for deploying Elixir/Phoenix applications.
config.exs get baked into the release binary. Use runtime.exs with env vars so secrets are resolved at bootverify: :verify_peer allows MITM attacks between your app and database; production data traverses the connectionruntime.exs runs whenever a
release boots, including eval-based migration commands. Only require S3,
Redis, and similar credentials when that integration is enabledif config_env() == :prod do
database_url = System.get_env("DATABASE_URL") || raise "DATABASE_URL is required"
secret_key_base = System.get_env("SECRET_KEY_BASE") || raise "SECRET_KEY_BASE is required"
host = System.get_env("PHX_HOST") || raise "PHX_HOST is required"
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_peer]
config :my_app, MyAppWeb.Endpoint,
url: [host: host, 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,
server: true
end
Keep core boot secrets such as DATABASE_URL and SECRET_KEY_BASE required.
Gate credentials for optional integrations behind the same feature switch that
enables the integration:
s3_config =
if System.get_env("STORAGE_BACKEND") == "s3" do
[
access_key_id:
System.get_env("S3_ACCESS_KEY") ||
raise("S3_ACCESS_KEY is required when STORAGE_BACKEND=s3"),
secret_access_key:
System.get_env("S3_SECRET_KEY") ||
raise("S3_SECRET_KEY is required when STORAGE_BACKEND=s3")
]
else
[]
end
config :my_app, :s3_config, s3_config
This lets release tasks that do not use S3 start without S3 credentials while still failing fast when S3 is selected.
def call(%{path_info: ["health", "readiness"]} = conn, _opts) do
case Ecto.Adapters.SQL.query(MyApp.Repo, "SELECT 1", []) do
{:ok, _} -> send_resp(conn, 200, ~s({"status":"ok"})) |> halt()
{:error, _} -> send_resp(conn, 503, ~s({"status":"error"})) |> halt()
end
end
| Need | Use | |------|-----| | Simple, managed | Fly.io | | Enterprise, existing K8s | Kubernetes | | Custom infrastructure | Docker + your orchestrator |
| Resource | Recommendation | |----------|----------------| | CPU | NO LIMITS (BEAM scheduler issues) | | Memory | Set limits (256Mi-512Mi typical) | | Graceful shutdown | ≥ 60 seconds |
server: true in endpoint configPhoenix 1.8 uses esbuild + tailwind (no Node.js required):
config/config.exs under :esbuild and :tailwindmix assets.deploy builds for productionmix assets.setup installs binaries on first runconfig/config.exsFor detailed patterns, see:
${CLAUDE_SKILL_DIR}/references/docker-config.md - Multi-stage Dockerfile, best practices${CLAUDE_SKILL_DIR}/references/flyio-config.md - fly.toml, clustering, commandstools
Compatibility alias for the Elixir/Phoenix plugin's LiveView assigns audit. Invoke explicitly with /lv:assigns.
development
Trace Elixir call trees from entry points via mix xref. Use when debugging data flow, planning signature changes, or understanding how a bug reaches code.
tools
Compatibility alias for the Elixir/Phoenix plugin's N+1 query checker. Invoke explicitly with /ecto:n1-check.
tools
Compatibility alias for the Elixir/Phoenix plugin's Ecto constraint debugger. Invoke explicitly with /ecto:constraint-debug.