Deployment Modes: Docker vs. Process
epd supports two distinct deployment runtimes configured via the top-level mode field: Docker and Process (PM2).
Both modes share the exact same blue/green zero-downtime guarantees, Traefik SSL routing, health checks, and instant rollbacks.
Quick Comparison
| Feature | Docker Mode (mode: docker) | Process Mode (mode: process) |
|---|---|---|
| Best For | Multi-language apps, containers, microservices | Ultra-low RAM VPS, Bun/Node/Python apps |
| Server Requirements | Docker Engine installed | Node.js/Bun, PM2, and rsync |
| Container Overhead | Minimal (~20-40MB per container) | Zero container overhead |
| Build Location | Local machine or CI runner | Remote server (or pre-built artifact) |
| Image Registry | Optional (can stream over SSH) | None needed |
| Process Manager | Docker Engine daemon | PM2 process supervisor |
1. Docker Mode (Default)
In Docker mode, your application is packaged as an OCI/Docker container image.
yaml
name: my-app
mode: docker
image: ghcr.io/my-org/my-app
servers:
web:
hosts: [203.0.113.10]
port: 3000
domains: [app.example.com]How It Works:
epdbuilds an image locally (using BuildKit / buildx) tagged with the current commit SHA.- Registry or SSH Stream:
- If
registry:is specified,epdpushes the image to your registry (e.g. GitHub Packages or Docker Hub), and servers pull it. - If no registry is specified,
epdstreams the image directly to each server over SSH usingdocker save | gzip | ssh ... docker load.
- If
- Containers run on a shared Docker bridge network (
epd). - Replicas communicate with Traefik using internal container names:
http://epd-<app>-<service>-<slot>-<replica>:<port>
Custom Docker Build Configuration
yaml
build:
dockerfile: docker/Dockerfile.prod
context: .
platform: linux/amd64
args:
NODE_ENV: production
API_URL: https://api.example.com2. Process Mode (No Docker on Server)
If you don't want or can't run Docker on your servers (for example, on a tiny 512MB or 1GB VPS), mode: process runs your code natively using PM2.
yaml
name: my-app
mode: process
process:
install: bun install --frozen-lockfile
build: bun run build
start: bun run start
exclude:
- ".git"
- "node_modules"
- ".env"
- "dist"
- "*.log"
servers:
web:
hosts: [203.0.113.10]
replicas: 2
port: 3000
domains: [app.example.com]How It Works:
epduploads your code viarsyncinto/var/lib/epd/apps/<app>/releases/<version>/.- Runs the
installandbuildcommands directly on the server. - Starts each replica under
pm2with an assigned unique localhost port (e.g.,20101,20102). - Traefik (running as a native binary managed by PM2) automatically routes traffic from ports 80/443 to the healthy PM2 replica ports.
Runtime Examples
yaml
mode: process
process:
install: bun install --frozen-lockfile
build: bun run build
start: bun run startyaml
mode: process
process:
install: npm ci --omit=dev
build: npm run build
start: npm run startyaml
mode: process
process:
install: pip install -r requirements.txt
start: python -m uvicorn main:app --host 127.0.0.1 --port $PORTyaml
mode: process
process:
build: go build -o server .
start: ./serverNext Steps
- Understand the Blue/Green Lifecycle
- Read about Multi-Site Hosting
- Learn how to manage Secrets & Environment