DigitalOcean
1-click Droplet from the DO Marketplace.
Deploy n8n on a DigitalOcean Droplet (via the Marketplace 1-Click Docker image or your own Compose file) or on the App Platform for a more PaaS-like experience.
Pros
- 1-click Marketplace image
- Great docs
- Managed Postgres available
- Snapshots & backups built-in
Cons
- Bandwidth caps on smaller plans
- Managed DB adds cost
Prerequisites
- DigitalOcean account with billing set up
- A domain with DNS you control
- Comfort with SSH or the DO App Platform UI
Step-by-step guide
Step 1
Create a Droplet
Pick the Docker Marketplace image, 2GB+ RAM, and your closest region.
Step 2
SSH in & install Compose
The Docker Marketplace image ships Docker pre-installed; add the Compose plugin if missing.
apt update && apt install docker-compose-plugin -yStep 3
Deploy the stack
Reuse the standard Postgres + n8n + Caddy docker-compose.yml.
services: postgres: image: postgres:16 restart: unless-stopped environment: POSTGRES_USER: n8n POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: n8n volumes: [ pgdata:/var/lib/postgresql/data ] n8n: image: n8nio/n8n:latest restart: unless-stopped depends_on: [ postgres ] ports: [ "5678:5678" ] environment: DB_TYPE: postgresdb DB_POSTGRESDB_HOST: postgres DB_POSTGRESDB_DATABASE: n8n DB_POSTGRESDB_USER: n8n DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD} N8N_HOST: ${N8N_HOST} N8N_PROTOCOL: https N8N_PORT: 5678 WEBHOOK_URL: https://${N8N_HOST}/ N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY} GENERIC_TIMEZONE: Europe/Berlin volumes: [ n8n_data:/home/node/.n8n ] caddy: image: caddy:2 restart: unless-stopped ports: [ "80:80", "443:443" ] volumes: - ./Caddyfile:/etc/caddy/Caddyfile - caddy_data:/data - caddy_config:/config volumes: { pgdata: {}, n8n_data: {}, caddy_data: {}, caddy_config: {} }Step 4
Point DNS & verify HTTPS
Add an A record to the Droplet's IP; Caddy auto-provisions the certificate on first request.
Scaling & queue mode
For higher throughput, switch to queue mode: set EXECUTIONS_MODE=queue, add a Redis instance, and run one or more separate `n8n worker` containers alongside the main process. The main instance handles the editor UI and webhooks while workers pull jobs from Redis. Scale worker replicas horizontally as load grows, and use a managed Postgres (with read replicas if needed) once execution volume is high.
Backup & upgrade
Back up the Postgres database (pg_dump on a cron schedule, or your provider's managed snapshot feature) and the n8n_data volume (contains binary data & config). Before upgrading, snapshot both, read the release notes for breaking changes, pull the new image tag, then `docker compose up -d`. Roll back by restoring the previous image tag + database snapshot if anything fails.
Security checklist
- Always run behind HTTPS (Caddy/Traefik/Nginx + Let's Encrypt) — never expose port 5678 directly.
- Set a strong, permanent N8N_ENCRYPTION_KEY and back it up (losing it breaks stored credentials).
- Use Postgres, not the default SQLite, for anything beyond local testing.
- Enable N8N_BASIC_AUTH or an SSO/proxy layer if the instance is reachable from the internet.
- Restrict inbound firewall rules to 80/443 (and SSH from your IP only).
- Keep the n8n image pinned and update on a schedule instead of always using :latest in production.
Cost breakdown
- Basic Droplet (2GB)$12/mo
- Managed Postgres (optional)from $15/mo
Troubleshooting & FAQ
+Can I use SQLite instead of Postgres?
n8n defaults to SQLite, which works for testing but isn't recommended for production: no concurrent writers, harder backups, and risk of corruption under load. Use Postgres for anything real.
+My webhooks return 404 / don't trigger — why?
WEBHOOK_URL must match the public HTTPS URL exactly (including trailing slash), and the workflow must be activated (not just saved) for production webhook URLs to work.
+How do I move from DigitalOcean to another host later?
Export workflows/credentials with the n8n CLI (`n8n export:workflow --all` / `export:credentials --all`) or the REST API, restore the Postgres dump on the new host, then import.
+Do I lose data if the container restarts?
No, as long as n8n_data and the Postgres volume are mounted as named Docker volumes (not ephemeral container storage), your data persists across restarts and image updates.