Skip to content

Secrets & Environment Management

Learn how epd securely manages environment variables, protects production secrets from git, and supports multi-environment staging overlays.


The Core Principle

epd ensures secrets are:

  • Never committed to git.
  • Never baked into Docker image layers.
  • Never printed in shell histories or CI logs.
  • Saved as restricted root-owned 0600 files on the host server.

1. Declaring Variables in epd.yml

Separate non-sensitive public configuration from private credentials:

yaml
env:
  # Public, non-sensitive variables (safe to commit to git)
  clear:
    NODE_ENV: production
    PORT: "3000"
    LOG_LEVEL: info

  # Sensitive secrets (read from your local environment or .env at deploy time)
  secret:
    - DATABASE_URL
    - STRIPE_SECRET_KEY
    - JWT_SECRET

2. How Secret Resolution Works

When you run epd deploy:

  1. epd reads each secret named in env.secret from:
    • Your local shell environment (export DATABASE_URL=...)
    • .env or .env.local in your project root
    • Destination-specific files like .env.staging (when using -d staging)
  2. epd securely uploads these key-value pairs to /var/lib/epd/apps/<app>/env on the remote server with chmod 0600.
  3. During startup:
    • Docker Mode: Mounted securely into containers via --env-file.
    • Process Mode: Loaded into PM2 process environments.

Missing Secrets

If a variable listed in env.secret is not found in your environment or .env file, epd halts deployment with a helpful error before modifying any remote state.


3. Service-Specific Environments

You can also override environment variables for a specific server service:

yaml
servers:
  web:
    hosts: [203.0.113.10]
    port: 3000
    env:
      clear:
        SERVICE_NAME: web-frontend

  worker:
    hosts: [203.0.113.10]
    command: bun run worker.ts
    env:
      clear:
        CONCURRENCY: "10"
      secret:
        - REDIS_PASSWORD

4. Multi-Environment Overlays (Staging vs. Production)

Manage multiple environments without duplicating configuration files:

bash
# Deploys using epd.yml + merges epd.staging.yml + loads .env.staging
epd deploy -d staging

In epd.staging.yml:

yaml
# Only specify fields you want to override for staging:
servers:
  web:
    hosts: [staging-server-ip]
    domains: [staging.example.com]

env:
  clear:
    NODE_ENV: staging

Next Steps

Released under the MIT License.