Skip to content

Getting Started with EPD ​

Deploy any application to one server or a fleet of servers with zero downtime, automatic Let's Encrypt SSL, and a shared Traefik proxy.

This guide will take you from zero to a live production deployment in under 5 minutes.


Prerequisites ​

Before starting, ensure you have:

  1. A Linux Server (VPS):

    • Any clean Linux VPS (Ubuntu 22.04/24.04, Debian 11/12, Fedora, Arch, etc.)
    • An open SSH port (22) with root or passwordless sudo access (or password to allow EPD to configure it).
    • Public ports 80 (HTTP) and 443 (HTTPS) accessible from the internet.
    • A DNS A record pointing your domain to the server's public IP address.
  2. Local Machine:

    • Linux or macOS (or Windows via WSL2).
    • Standard ssh client.
    • Docker installed locally (if deploying in Docker mode to build images).

No Server Yet?

If you don't have a server, you can provision one in 30 seconds using the built-in Hetzner Cloud integration:

bash
epd hetzner create my-server --setup

1. Install EPD ​

Install epd using the zero-dependency standalone installer (requires no Node.js or Bun runtime), or via your favorite package manager:

bash
curl -fsSL https://raw.githubusercontent.com/FabioPlunser/epd/main/install.sh | bash
bash
bun install -g @fabioplunser/epd
bash
npm install -g @fabioplunser/epd
bash
pnpm add -g @fabioplunser/epd
bash
npx @fabioplunser/epd --help

Verify installation:

bash
epd --version

2. Shell Autocompletion (Optional) ​

Enable instant tab-completion for all commands, flags, and destination overlays:

bash
eval "$(epd completion zsh)"
bash
source <(epd completion bash)
bash
epd completion fish | source

3. Initialize Your Project ​

Navigate to your application's root directory:

bash
cd my-app
epd init

epd init will inspect your project:

  • Automatically detects your runtime (Node.js, Bun, Python, Go, Ruby, or static).
  • Detects whether you already have a Dockerfile.
  • Prompts for your server IP, domain name, and ACME SSL email.
  • Generates a tailored epd.yml config file (and an optimized starter Dockerfile if needed).

GitHub Actions Starter

Run epd init --ci or epd gh-action to also generate a ready-to-run GitHub Actions workflow (.github/workflows/deploy.yml).


4. Configure epd.yml ​

Open epd.yml in your editor. Here is a typical single-server configuration:

yaml
# Application name (used for container naming and routing isolation)
name: my-app
mode: docker

# Docker image name (built locally, or pulled from registry)
image: my-app

# SSH connection details
ssh:
  user: root

# Server & Routing
servers:
  web:
    hosts: [203.0.113.10]
    port: 3000
    domains: [app.example.com]

# Shared Traefik Proxy & Automatic SSL
proxy:
  email: admin@example.com

# Health check probe before switching live traffic
healthcheck:
  path: /health
  timeout: 30

# Environment variables & secrets
env:
  clear:
    NODE_ENV: production
  secret:
    - DATABASE_URL
yaml
# Run code directly under PM2 without Docker on the host
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"]

ssh:
  user: root

servers:
  web:
    hosts: [203.0.113.10]
    replicas: 2
    port: 3000
    domains: [app.example.com]

proxy:
  email: admin@example.com

Secrets Setup ​

Any secret declared under env.secret is resolved automatically from your local shell or .env file:

bash
# In your local .env or current shell:
export DATABASE_URL="postgres://user:password@host/dbname"

When you deploy, epd securely uploads secrets into a root-owned 0600 file on the remote server without saving secrets in git or container image layers.


5. Pre-flight Checks (epd doctor) ​

Run epd doctor to verify your local tools, secrets, and server reachability before deploying:

bash
epd doctor

epd doctor confirms:

  • Local Bun/Node, Docker engine, and clean git state
  • SSH client and key permissions (0600)
  • epd.yml syntax and .env secret availability
  • Remote server SSH reachability, passwordless sudo, Docker health, and free disk space

6. Run Server Setup ​

Run epd setup once for each new server:

bash
epd setup

Automated SSH & Server Onboarding: ​

  • Password Prompt: If your server only has password login enabled, epd setup prompts for the server password once.
  • Key Installation: It installs your public key (~/.ssh/id_ed25519.pub) to ~/.ssh/authorized_keys.
  • Passwordless Sudo: Configures /etc/sudoers.d/epd automatically so future commands run non-interactively.
  • Docker & Traefik: Installs Docker and starts Traefik reverse proxy with Let's Encrypt SSL.
  • Initial Deploy: Builds your image, boots slot blue, verifies health checks, and registers routes.

7. Deploy Updates with Zero Downtime ​

Whenever you commit changes or want to deploy an update:

bash
epd deploy

Want to preview the deployment plan without changing anything on the servers? Run a dry run:

bash
epd deploy --dry-run

epd deploy executes a zero-downtime blue/green swap:

  1. Builds the latest container image (or syncs process code).
  2. Starts the new version in the idle slot (e.g., green).
  3. Probes the internal health check endpoint until healthy.
  4. Atomically updates Traefik's dynamic routing to direct incoming requests to the new slot.
  5. Drains in-flight connections to the previous slot (blue) before gracefully stopping it.

Rollback Anytime

If an issue occurs after deployment, revert instantly to the previous version with:

bash
epd rollback

This re-activates the previous slot in seconds without rebuilding or re-uploading!


8. Inspect & Monitor ​

Use epd CLI commands to check your application's health and operations:

bash
# Check running containers, active slots, and route status
epd status

# Stream live container logs
epd logs -f

# Real-time multi-server CPU, memory, and container monitor
epd top

# Inspect Let's Encrypt SSL/TLS certificates and days to expiry
epd ssl

# Toggle zero-downtime 503 maintenance page
epd maintenance on -m "Upgrading database. Back in 10 minutes."
epd maintenance off

# Create compressed database / volume backups
epd backup db

# Open an interactive shell inside a running replica
epd shell

Next Steps ​

Now that your application is live, explore additional capabilities:

Released under the MIT License.