Skip to content

Command Palette

Search for a command to run...

Operations

Docker runtime

Run app instances as containers under the zero-downtime proxy, while one host stays one server on the dashboard.

One host, one agent

The docker runtime keeps a single Phelix agent on the host, exactly as on a bare VPS - one agent_id, one apps.json - but instead of executing each app as a host process, it builds an image per app and runs each instance as a container. One host therefore stays one server on the dashboard no matter how many app containers it runs.

The proxy still owns the single public port and routes to each container's published loopback port; a version rollback restarts the recorded image (myapp:v11) instead of a binary.

One host, one agent = one server
┌─ VPS — ONE Phelix agent = ONE server on the dashboard ─────────────┐│  phelix monitor        (host process, systemd — as today)          ││  phelix proxy  :8080 ─┐                                            ││                       ├─→ 127.0.0.1:49215  ← docker: billing:v3    ││                       ├─→ 127.0.0.1:49216  ← docker: auth:v7       ││                       └─→ 127.0.0.1:49217  ← docker: user:v2       │└────────────────────────────────────────────────────────────────────┘

Requirements

  • Phelix runs on the host (the normal systemd install) with a reachable Docker daemon. Do not run Phelix itself inside a container for this model unless you deliberately mount the Docker socket (see Security).
  • Each app must read PORT - the same PORT contract as native apps. Phelix injects PORT into the container and publishes it to an ephemeral host port bound to 127.0.0.1.
  • The docker runtime rides the zero-downtime topology, so the app needs a zero-downtime strategy - blue-green, rolling, canary, or progressive. The classic stop-start path is native-only.

Enable the docker runtime

Set the runtime in the app's project configuration:

phelix.yamlyaml
name: billingport: 8080deploy:  runtime: docker        # run instances as containers instead of host processes  strategy: blue-green   # required: classic is native-onlyhealth:  endpoints:    - name: default      path: /health      interval: 10s      retries: 3      mode: auto

phelix init writes this for you when you pick the docker runtime (or pass --runtime docker); it defaults strategy to blue-green so the file is valid. Flip a single command to docker without editing the file:

Terminal
PHELIX_RUNTIME=docker phelix rebuild billing

Precedence is PHELIX_RUNTIME env → phelix.yaml deploy.runtime → native.

Deploy and roll back

Terminal
# One-time on the hostphelix proxy                     # zero-downtime proxy (auto-started by rebuild too) # Build an image (myapp:vN) and roll it out with zero downtimephelix rebuild billing --blue-green # Roll back to the previous image, zero downtimephelix rollback billing

Phelix generates a multi-stage Dockerfile if the project has none (the same generator phelix dockerize uses; a user-provided Dockerfile is always respected), builds billing:v<N>, records it in versions.json, then runs it with the phelix.managed, phelix.app, and phelix.slot labels.

Step by step

  1. Initialise and choose the docker runtime
    phelix init --name billing --port 8080 --runtime docker --yes writes deploy.runtime: docker with deploy.strategy: blue-green. The port here is the public port the proxy binds.
  2. Make the app read PORT
    The one hard requirement: Phelix runs the container with PORT set and maps it to a private host port the proxy dials. Run phelix doctor to check.
  3. Provide a Dockerfile - or let Phelix generate one
    No Dockerfile: Phelix generates a multi-stage one on the first deploy and never overwrites it. Your own Dockerfile is used as-is. It only needs to start the app as ENTRYPOINT/CMD and bind the PORT variable - no EXPOSE or hardcoded port.
  4. Create the app with phelix build
    phelix build billing creates the app and goes straight through the container path: build billing:v1, run it on a private loopback port, health-check it, then point the proxy at it. Only Docker is required on the host.
  5. Ship a change with phelix rebuild
    phelix rebuild billing builds billing:v2, health-checks it, and switches over. The old container keeps serving until the new one is healthy.
  6. Roll back if needed
    phelix rollback billing returns to the previous image with zero downtime; --to v1 targets a specific version.

Instance identity & cleanup

  • Every container Phelix starts carries a phelix.managed=true label plus the app and slot. Liveness and shutdown verify the container id + label (never a recycled host PID), so a live container is never mistaken for dead and Phelix never signals a container it did not create.
  • Secrets reach the container through a 0600 --env-file, never as -e on the command line, so decrypted values never appear in docker inspect or the host process table.
  • If a deploy crashes after docker run but before recording the instance, the orphaned container is reclaimed the next time phelix monitor starts - only phelix.managed containers that no deploy state references are removed.

Security