n8n VPS Install Plan

Johnny n8n Install Plan (VPS, Docker, Security, Backups)

For: James / AgentsOPS / FreshFlip Date: 2026-02-05 Status: DRAFT v0 (approve infra choices before provisioning)

Goal: a production-safe self-hosted n8n that’s easy to upgrade, backed up, and locked down.


Optional (later): separate VPS for Postgres if workloads grow.


2) Core components


3) Security checklist (do these on day 1)

3.1 Secrets

Must set: - N8N_ENCRYPTION_KEY (32+ chars; do not lose) - N8N_USER_MANAGEMENT_DISABLED=false (use built-in users)

Store in .env with strict permissions or a secret manager.

3.2 Network

3.3 n8n hardening

3.4 Webhook hygiene


4) Docker Compose (example)

Note: This is a starting template. Confirm proxy choice (Caddy vs Traefik) before using.

Create a folder: /opt/n8n with: - docker-compose.yml - .env - caddy/Caddyfile (if using Caddy)

4.1 .env (example)

# n8n
N8N_HOST=automations.agentsops.net
N8N_PROTOCOL=https
WEBHOOK_URL=https://automations.agentsops.net/
N8N_ENCRYPTION_KEY=REPLACE_WITH_LONG_RANDOM_SECRET
GENERIC_TIMEZONE=America/New_York

# postgres
POSTGRES_DB=n8n
POSTGRES_USER=n8n
POSTGRES_PASSWORD=REPLACE_WITH_STRONG_PASSWORD

4.2 docker-compose.yml (example)

services:
  postgres:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data

  n8n:
    image: n8nio/n8n:latest
    restart: unless-stopped
    depends_on:
      - postgres
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_DATABASE: ${POSTGRES_DB}
      DB_POSTGRESDB_USER: ${POSTGRES_USER}
      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}

      N8N_HOST: ${N8N_HOST}
      N8N_PROTOCOL: ${N8N_PROTOCOL}
      WEBHOOK_URL: ${WEBHOOK_URL}
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}

      # retention / hygiene
      EXECUTIONS_DATA_PRUNE: "true"
      EXECUTIONS_DATA_MAX_AGE: "168"

    volumes:
      - n8n_data:/home/node/.n8n

  caddy:
    image: caddy:2
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
      - caddy_data:/data
      - caddy_config:/config
    depends_on:
      - n8n

volumes:
  postgres_data:
  n8n_data:
  caddy_data:
  caddy_config:

4.3 caddy/Caddyfile (example)

automations.agentsops.net {
  reverse_proxy n8n:5678
}

5) Backups (minimum viable, but real)

5.1 What to back up

5.2 Backup approach

5.3 Restore test (required)

Once per month: - Restore DB dump to a staging instance - Verify at least 1 workflow executes successfully


6) Upgrade plan


7) Monitoring / alerts (simple but effective)


8) Decisions needed from James

  1. Domain/subdomain to dedicate to n8n.
  2. Proxy preference: Caddy (simple) vs Traefik (more flexible).
  3. Backup destination (S3 bucket, Drive, etc.).
  4. Whether we want a second instance for staging.