How to self-host n8n using Docker

Last updated: May 11, 2026Ole Mai3 min read
bashcertbotdockersoftwareupCloud

n8n is a popular and open-source workflow automation tool, which you can self-host on a UpCloud Cloud server using Docker Compose and Caddy as a reverse proxy. This detailed tutorial ensures a smooth setup while highlighting best practices for security and maintenance.

What you need

Before starting, ensure you meet these requirements:

  • A VPS running Ubuntu 22.04 or 24.04

  • Root sudo SSH access to the server

  • A domain name you control (e.g. example.com)

  • DNS A-record pointed at your VPS IP

  • Ports 80 and 443 reachable from the internet

  • ~1 GB RAM minimum (2 GB recommended)

Need a server? Get $25 free credits on UpCloud — perfect for self-hosting.

Connect to your VPS & update packages

SSH into your VPS as root or a sudo user, then make sure all packages are up to date before installing anything.

Connect to your VPS & update packages
1# Connect from your local machine 2ssh root@YOUR_SERVER_IP 3 4# Update system packages 5apt update && apt -y upgrade

Tipp: Create a non-root sudo user for day-to-day use: adduser deploy && usermod -aG sudo deploy. This is a security best practice.

Install Docker CE & Docker Compose

Install Docker from the official Docker repository. This gives you the latest stable version plus the Compose plugin in one go.

Install Docker
1# Install prerequisites 2apt install -y ca-certificates curl gnupg lsb-release 3 4# Add Docker's official GPG key 5install -m 0755 -d /etc/apt/keyrings 6curl -fsSL https://download.docker.com/linux/ubuntu/gpg \ 7 | gpg --dearmor -o /etc/apt/keyrings/docker.gpg 8chmod a+r /etc/apt/keyrings/docker.gpg 9 10# Add Docker's repository 11echo \ 12 "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ 13 https://download.docker.com/linux/ubuntu \ 14 $(lsb_release -cs) stable" \ 15 | tee /etc/apt/sources.list.d/docker.list > /dev/null 16 17# Install Docker CE + Compose plugin 18apt update 19apt install -y docker-ce docker-ce-cli containerd.io \ 20 docker-buildx-plugin docker-compose-plugin
Verify Installation
1# Verify Docker is running 2docker --version 3docker compose version 4 5# (Optional) Run without sudo for your deploy user 6usermod -aG docker deploy

After adding your user to the docker group, log out and back in (or run newgrp docker) for the group change to take effect.

Configure the firewall

Open only the ports n8n needs. Keep SSH access open so you don't lock yourself out.

Configure the firewall
1# Allow SSH (critical — do this first!) 2ufw allow OpenSSH 3 4# Allow web traffic for Caddy 5ufw allow 80 # HTTP (Caddy redirects to HTTPS) 6ufw allow 443 # HTTPS 7 8# Enable the firewall 9ufw --force enable 10ufw status

Note: Always allow SSH before enabling UFW. Forgetting this locks you out of your server.

Point your domain to the VPS

In your domain registrar's DNS settings, create an A record for the subdomain you'll use for n8n:

DNS Record
1Type: A 2Host: n8n (or any subdomain you prefer) 3Value: YOUR_VPS_IP 4TTL: 3600

Tipp: This routes n8n.yourdomain.com to your VPS. DNS changes can take a few minutes to propagate globally. You can verify with dig n8n.yourdomain.com.

Clone the n8n Docker setup

The n8n team maintains an official Docker + Caddy compose setup. Clone it and create the persistent data volumes.

Clone the n8n Docker setup
1# Install git if not already present 2apt install -y git 3 4# Clone the official n8n Docker + Caddy repo 5git clone https://github.com/n8n-io/n8n-docker-caddy.git 6cd n8n-docker-caddy 7 8# Create persistent Docker volumes 9docker volume create caddy_data 10docker volume create n8n_data

Configure environment variables

Edit the .env file in the cloned directory and fill in your values:

Edit ENVs
1nano .env

Variable

Description & Example

DOMAIN_NAME

Your root domain

example.com

SUBDOMAIN

Subdomain for n8n

n8n

N8N_HOST

Full hostname

n8n.example.com

N8N_PROTOCOL

Always use https in production

https

N8N_PORT

Internal container port (do not expose directly)

5678

N8N_ENCRYPTION_KEY

Unique secret for encrypting credentials — generate with

openssl rand -hex 32

N8N_BASIC_AUTH_USER

Admin login username

admin

N8N_BASIC_AUTH_PASSWORD

Strong admin password — use a password manager

Note: Never commit the .env file to version control. Add it to .gitignore immediately.

Configure Caddy as a reverse proxy

Open the Caddyfile and replace the domain placeholder with your actual subdomain. Caddy handles TLS certificate provisioning automatically via Let's Encrypt.

Edit Caddyfile
1nano caddy_config/Caddyfile
Caddyfile
1n8n.example.com { 2 reverse_proxy n8n:5678 { 3 flush_interval -1 4 } 5}

Replace n8n.example.com with your actual hostname. Caddy will automatically obtain and renew an SSL certificate. No manual certbot configuration needed.

Launch n8n

Start all services in detached mode. Docker will pull the n8n and Caddy images, then start them in the background.

Launch n8n
1# Start n8n + Caddy in the background 2docker compose up -d 3 4# Watch logs to confirm everything started cleanly 5docker compose logs -f

After a minute, visit https://n8n.yourdomain.com in your browser. You should see the n8n login screen.

Tipp: Useful management commands below. Bookmark these.

Docker Management Commands
1# Stop all services 2docker compose down 3 4# Pull latest images and restart (for updates) 5docker compose pull && docker compose up -d 6 7# View running containers 8docker compose ps 9 10# Restart just n8n 11docker compose restart n8n

Enable Docker to start automatically on server reboot, so n8n comes back up without manual intervention.

Auto-start on reboot
1# Enable Docker daemon on boot 2systemctl enable docker 3 4# Ensure restart policy is set in docker-compose.yml 5# (the n8n-docker-caddy repo includes restart: unless-stopped by default) 6grep restart docker-compose.yml

Tipp: The official n8n compose file already sets restart: unless-stopped on all services, so containers will restart automatically after a reboot or crash.

Troubleshooting

In the following I want to show you a few common errors you might encounter and how to fix them.

Common issues

Common issues
1# SSL certificate not issuing 2Ensure ports 80 and 443 are open and DNS is propagated 3 Run: dig n8n.yourdomain.com 4 5# n8n not accessible after starting 6Check logs: docker compose logs caddy 7Check logs: docker compose logs n8n 8 9# Permission denied on docker command 10Add user to docker group: usermod -aG docker $USER 11Then log out and back in, or run: newgrp docker 12 13# Port already in use 14Check what's using port 80/443: ss -tlnp | grep ':80\|:443'