Install any skill in seconds. Free to start, no credit card required.
Get Started Free →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.
.claude/skills/oliver-kriska-deploy/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 31% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 24% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 26% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 41% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 20% | 0% |
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 arelease boots, including eval-based migration commands. Only require S3, Redis, and similar credentials when that integration is enabled
elixirif 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:
elixirs3_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.
elixirdef 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:
references/docker-config.md - Multi-stage Dockerfile, best practicesreferences/flyio-config.md - fly.toml, clustering, commands| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 18,879 | 16,770 | -11% | 1 | 1 | 0% | 3,436 | 4,491 | +31% | 0 | 0 | — |
case-02 | fail→pass | 14,665 | 10,397 | -29% | 1 | 1 | 0% | 2,502 | 3,093 | +24% | 0 | 0 | — |
case-03 | fail→pass | 13,848 | 10,761 | -22% | 1 | 1 | 0% | 2,730 | 3,438 | +26% | 0 | 0 | — |
case-04 | pass→pass | 19,516 | 18,465 | -5% | 1 | 1 | 0% | 3,467 | 4,645 | +34% | 0 | 0 | — |
case-05 | pass→pass | 14,672 | 12,106 | -17% | 1 | 1 | 0% | 2,350 | 3,198 | +36% | 0 | 0 | — |
case-06 | pass→pass | 16,720 | 6,205 | -63% | 1 | 1 | 0% | 2,516 | 2,338 | -7% | 0 | 0 | — |
case-07 | fail→pass | 15,238 | 13,222 | -13% | 1 | 1 | 0% | 2,599 | 3,676 | +41% | 0 | 0 | — |
case-08 | pass→pass | 11,719 | 9,556 | -18% | 1 | 1 | 0% | 1,980 | 2,862 | +45% | 0 | 0 | — |
case-09 | pass→pass | 4,365 | 3,925 | -10% | 1 | 1 | 0% | 695 | 1,918 | +176% | 0 | 0 | — |
case-10 | pass→pass | 13,306 | 10,466 | -21% | 1 | 1 | 0% | 2,432 | 3,179 | +31% | 0 | 0 | — |
case-11 | pass→pass | 10,682 | 7,268 | -32% | 1 | 1 | 0% | 1,938 | 2,596 | +34% | 0 | 0 | — |
case-20 | pass→pass | 12,053 | 11,680 | -3% | 1 | 1 | 0% | 2,615 | 3,840 | +47% | 0 | 0 | — |
case-12 | pass→pass | 11,316 | 7,450 | -34% | 1 | 1 | 0% | 1,738 | 2,503 | +44% | 0 | 0 | — |
case-13 | pass→pass | 23,725 | 7,878 | -67% | 1 | 1 | 0% | 1,805 | 2,378 | +32% | 0 | 0 | — |
case-14 | fail→pass | 12,240 | 5,489 | -55% | 1 | 1 | 0% | 1,893 | 2,266 | +20% | 0 | 0 | — |
case-15 | pass→pass | 12,106 | 4,137 | -66% | 1 | 1 | 0% | 2,214 | 2,088 | -6% | 0 | 0 | — |
case-16 | pass→pass | 10,871 | 6,947 | -36% | 1 | 1 | 0% | 1,883 | 2,429 | +29% | 0 | 0 | — |
case-17 | pass→pass | 11,567 | 8,200 | -29% | 1 | 1 | 0% | 1,961 | 2,666 | +36% | 0 | 0 | — |
case-18 | pass→pass | 6,994 | 2,993 | -57% | 1 | 1 | 0% | 1,180 | 1,723 | +46% | 0 | 0 | — |
case-19 | pass→pass | 5,732 | 4,173 | -27% | 1 | 1 | 0% | 1,009 | 2,021 | +100% | 0 | 0 | — |
case-21 | pass→pass | 12,588 | 12,534 | -0% | 1 | 1 | 0% | 2,413 | 3,631 | +50% | 0 | 0 | — |
case-22 | pass→pass | 19,661 | 18,250 | -7% | 1 | 1 | 0% | 2,918 | 4,097 | +40% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +23 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.