Self-Host n8n Using Docker

n8n is a powerful, open-source workflow automation tool. In this guide, you’ll learn how to self-host n8n using Docker and securely expose it to the internet using Cloudflare Tunnel β€” without opening any ports or needing a reverse proxy.


🧰 Prerequisites

Make sure you have the following ready:

  • A VPS/server (Ubuntu/Debian preferred)
  • A domain connected to Cloudflare
  • Docker & Docker Compose installed
  • A free Cloudflare account
  • cloudflared CLI installed

1. πŸ“ Setup Project Directory

Create a directory for your n8n:

mkdir -p n8n-docker
cd n8n-docker
mkdir local-files

Inside the n8n-docker directory, create an .env file to customize your n8n details

vi .env
# DOMAIN_NAME and SUBDOMAIN together determine where n8n will be reachable

# The top level domain to serve from
DOMAIN_NAME=example.dev

# The subdomain to serve from
SUBDOMAIN=n8n

# The above example serve n8n at: https://n8n.example.dev

# Optional timezone to set which gets used by Cron and other scheduling nodes
# New York is the default value if not set
GENERIC_TIMEZONE=Asia/Jakarta

# The email address to use for the TLS/SSL certificate creation
[email protected]

2. πŸ“ Create docker-compose.yml

Create a docker-compose.yml file with the following content:

services:
  traefik:
    image: "traefik"
    restart: always
    command:
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=${SSL_EMAIL}"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - traefik_data:/letsencrypt
      - /var/run/docker.sock:/var/run/docker.sock:ro

  n8n:
    image: docker.n8n.io/n8nio/n8n
    restart: always
    ports:
      - "127.0.0.1:5678:5678"
    labels:
      - traefik.enable=true
      - traefik.http.routers.n8n.rule=Host(`${SUBDOMAIN}.${DOMAIN_NAME}`)
      - traefik.http.routers.n8n.tls=true
      - traefik.http.routers.n8n.entrypoints=web,websecure
      - traefik.http.routers.n8n.tls.certresolver=mytlschallenge
      - traefik.http.middlewares.n8n.headers.SSLRedirect=true
      - traefik.http.middlewares.n8n.headers.STSSeconds=315360000
      - traefik.http.middlewares.n8n.headers.browserXSSFilter=true
      - traefik.http.middlewares.n8n.headers.contentTypeNosniff=true
      - traefik.http.middlewares.n8n.headers.forceSTSHeader=true
      - traefik.http.middlewares.n8n.headers.SSLHost=${DOMAIN_NAME}
      - traefik.http.middlewares.n8n.headers.STSIncludeSubdomains=true
      - traefik.http.middlewares.n8n.headers.STSPreload=true
      - traefik.http.routers.n8n.middlewares=n8n@docker
    environment:
      - N8N_HOST=${SUBDOMAIN}.${DOMAIN_NAME}
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - NODE_ENV=production
      - WEBHOOK_URL=https://${SUBDOMAIN}.${DOMAIN_NAME}/
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
    volumes:
      - n8n_data:/home/node/.n8n
      - ./local-files:/files

volumes:
  n8n_data:
  traefik_data:

3. πŸš€ Start n8n container

docker compose up -d

Verify it’s running:

docker ps

Gambar docker ps n8n

4. 🌐 Configure Cloudflare Tunnel

  • login to your cloudflare dashboard
  • navigate to Zero Trust > Networks > Tunnel
  • create a tunnel
  • enter and type a name for the tunnel
  • choose the environment you were using, then install and run the cloudflared connector on your VPS/server
  • setup sub domain for the n8n and point it to the backend service which running the n8n

Gambar cloudflare tunnel n8n

Verify the tunnel status it’s Healthy

5. βœ… Access n8n dashboard

Now open your browser and navigate to:

https://n8n.yourdomain.com

Gambar dashboard n8n


πŸ›‘οΈ Security Tips

  • Always enable Basic Auth for n8n
  • Use HTTPS (secured by Cloudflare Tunnel)

🧩 Wrapping Up

With this guide, you’ve deployed n8n securely and efficiently using Docker and Cloudflare Tunnel. Whether you’re building automations for yourself, your team, or a client β€” you now have a scalable and secure foundation.

This setup is great for personal automation, private workflows, or even small production use cases. And because you’re using Docker, keeping things up to date is easy and clean.


🀝 Let’s Connect

If you have suggestions, questions, or just want to say hi, I’d love to hear from you.

Feel free to reach out β€” I’m always happy to help fellow builders:

If you found this helpful, consider sharing it or giving it a star wherever you found it β€” it really helps!

Thanks for stopping by. See you in the next post! ✌️