# Deploy

Elixir/Phoenix deployment patterns, Dockerfile, fly.toml, runtime.exs, mix release...

- Repository: https://github.com/oliver-kriska/claude-elixir-phoenix (572 stars)
- Category: DevOps
- License: MIT
- Last updated: 2026-10-30
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add oliver-kriska/claude-elixir-phoenix --skill deploy -g -a claude-code -y`
Codex: `npx skills add oliver-kriska/claude-elixir-phoenix --skill deploy -g -a codex -y`
Cursor: `npx skills add oliver-kriska/claude-elixir-phoenix --skill deploy -g -a cursor -y`
Gemini CLI: `npx skills add oliver-kriska/claude-elixir-phoenix --skill deploy -g -a gemini-cli -y`
Claude Code plugin marketplace: `/plugin marketplace add oliver-kriska/claude-elixir-phoenix`

## Description

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.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Elixir/Phoenix Deployment Reference

Quick reference for deploying Elixir/Phoenix applications.

## Iron Laws, Never Violate These

1. **Config at runtime, not compile time**, Secrets in `config.exs` get baked into the release binary. Use `runtime.exs` with env vars so secrets are resolved at boot
2. **Graceful shutdown ≥ 60 seconds**, Shorter timeouts kill in-flight requests and WebSocket connections mid-operation, causing data loss for users
3. **Health checks required**, Without startup/liveness/readiness endpoints, orchestrators can't distinguish a booting node from a dead one, leading to cascading restarts
4. **SSL verification for database**, Skipping `verify: :verify_peer` allows MITM attacks between your app and database; production data traverses the connection
5. **No CPU limits**, The BEAM scheduler assumes it owns all cores; cgroups CPU limits cause scheduler collapse where the VM thinks it has more cores than it can use, leading to latency spikes
6. **Guard optional service credentials**, `runtime.exs` runs whenever a
   release boots, including `eval`-based migration commands. Only require S3,
   Redis, and similar credentials when that integration is enabled

## Quick Configuration

### runtime.exs (Essential)

```elixir
if 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
```

### Guard Optional Services

The rest: https://github.com/oliver-kriska/claude-elixir-phoenix/blob/HEAD/plugins/elixir-phoenix/skills/deploy/SKILL.md
