Skip to content

Quick Start — Elixir

Deploy an Elixir app (Phoenix, Plug, plain OTP) from git push to a live HTTPS URL in 5 minutes.

Prerequisites

  • An Elixir project with mix.exs
  • Elixir 1.16+ + Erlang/OTP 26+ on your machine (elixir --version)
  • The paas CLI:
    curl -fsSL https://get.di2amp.com/install.sh | sh
    paas --version
    

Scaffold (if you don't have a project yet — Phoenix)

mix archive.install hex phx_new --force
mix phx.new hello_paas --no-ecto --no-live --no-mailer --no-tailwind
cd hello_paas
mix deps.get
git init && git add -A && git commit -m "init"

For a minimal Plug-only project:

mix new hello_paas --sup && cd hello_paas
cat >> mix.exs <<'EOF'
  defp deps do
    [{:plug_cowboy, "~> 2.7"}]
  end
EOF
# Edit lib/hello_paas/application.ex to start a Cowboy listener on PORT
mix deps.get
git init && git add -A && git commit -m "init"

Step 1 — Authenticate

paas login

Verify:

$ paas whoami
octave@paas.local (member of: paas-default)

Step 2 — Create the app

paas apps create hello-paas

Output:

✓ Created app hello-paas
  URL:    https://hello-paas.runtime.di2amp.com
  Region: eu-fr-1
  Plan:   free
  Git:    https://git.di2amp.com/octave/hello-paas.git

Step 3 — Configure for production + add a Procfile

In config/runtime.exs (Phoenix), bind on PORT:

import Config

if config_env() == :prod do
  port = String.to_integer(System.get_env("PORT") || "4000")
  config :hello_paas, HelloPaasWeb.Endpoint,
    http: [ip: {0, 0, 0, 0}, port: port],
    server: true,
    secret_key_base: System.fetch_env!("SECRET_KEY_BASE")
end

Procfile:

# Procfile
web: mix phx.server
release: mix release

The Paketo Erlang buildpack auto-detects mix.exs. For better cold start, generate a release with mix release and run the binary:

# Procfile (release-mode, faster boot)
web: _build/prod/rel/hello_paas/bin/hello_paas start
release: _build/prod/rel/hello_paas/bin/hello_paas eval "HelloPaas.Release.migrate"

Commit:

git add Procfile config/runtime.exs && git commit -m "configure for paas"

Step 4 — Push to deploy

git push paas main

Live build logs:

remote: ─────── PaaS Build ───────
remote: → Detected: erlang/elixir (paketo-buildpacks/elixir)
remote: → Installing Erlang/OTP 26.2.5
remote: → Installing Elixir 1.16.3
remote: → Running: mix deps.get --only prod
remote: → Running: MIX_ENV=prod mix release
remote: → Image:    registry.di2amp.com/octave/hello-paas:abc1234
remote: → Image size: 67 MB (BEAM + release tree, ERTS embedded)
remote: → SBOM:     ✓ generated, 24 packages
remote: → CVE scan: ✓ 0 critical, 0 high
remote:
remote: ─────── PaaS Deploy ───────
remote: → Process types: web
remote: → Replicas:      1/1 ready
remote: → Rollout:       v1 → v2 (canary 10% → 100%)
remote: → Health:        / returns 200 OK
remote: → URL:           https://hello-paas.runtime.di2amp.com
remote:
remote: ✓ Deployed in 84s

PaaS automatically generates a SECRET_KEY_BASE env var for new Phoenix apps.

Step 5 — Verify the app is live

$ curl https://hello-paas.runtime.di2amp.com/
<!DOCTYPE html><html>... Phoenix welcome page ...</html>

Dashboard runtime status:

https://ma30.di2amp.com/runtime/dashboard/apps/hello-paas

Next steps

Add a managed PostgreSQL

paas addons create database --type postgres --plan free --name db

DATABASE_URL is injected. Phoenix config/runtime.exs:

config :hello_paas, HelloPaas.Repo,
  url: System.fetch_env!("DATABASE_URL"),
  pool_size: 10

Run migrations on every deploy

# Procfile
web: _build/prod/rel/hello_paas/bin/hello_paas start
release: _build/prod/rel/hello_paas/bin/hello_paas eval "HelloPaas.Release.migrate"

Tail logs

paas logs --tail

Cluster nodes (libcluster)

PaaS injects POD_IP + POD_NAMESPACE. Use libcluster's Kubernetes strategy:

config :libcluster,
  topologies: [
    paas: [
      strategy: Cluster.Strategy.Kubernetes,
      config: [
        mode: :hostname,
        kubernetes_node_basename: "hello_paas",
        kubernetes_selector: "paas-app=hello-paas"
      ]
    ]
  ]

Scale processes

paas ps:scale web=3

See also