You’ve chosen to self-host n8n for privacy, cost savings, local access, persistent data, and reachable webhooks.
This guide explains running n8n in a cross-platform Docker container with persistent storage, basic authentication, and webhook access without certificate complexity.
If you’re new to n8n, read What Is N8n? first to understand what it does.
Prerequisites
Before starting, ensure you have:
- Docker installed: Download Docker Desktop for Windows, Mac, or Linux.
- Docker Compose: Included with Docker Desktop. On Linux, install it separately if needed.
- Basic terminal knowledge: You’ll run commands in a terminal or command prompt.
Step 1: Create a Project Directory
Create a directory for your n8n setup to stay organized and easily find your configuration.
mkdir n8n-self-host
cd n8n-self-hostThis directory stores your Docker Compose file and n8n data.
Step 2: Create Docker Compose Configuration
Create a docker-compose.yml in your project to define your n8n container with all settings.
services:
n8n:
image: n8nio/n8n:latest
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_BASIC_AUTH_ACTIVE=true
- N8N_BASIC_AUTH_USER=admin
- N8N_BASIC_AUTH_PASSWORD=changeme
- TZ=America/Los_Angeles
volumes:
- n8n_data:/home/node/.n8n
volumes:
n8n_data:Configuration explanation:
- Ports: Maps port 5678 from the container to your host machine.
- Authentication: Sets basic auth with username
adminand passwordchangeme. Change these immediately. - Volumes: Creates a Docker volume that persists your workflows and settings.
Optional: Add TZ=America/Los_Angeles (replace with your timezone) to the environment section if you need scheduled workflows to run in your local timezone. Without it, n8n defaults to UTC.
Important: Replace changeme with a strong password before starting the container.
Step 3: Start N8n
Start n8n using Docker Compose. This command reads your docker-compose.yml file and starts the container.
On Windows (PowerShell or Command Prompt):
docker compose up -dOn Mac or Linux:
docker compose up -dThe -d flag runs the container in detached mode, so it continues running in the background.
Wait about 30 seconds for n8n to start, then open your browser and go to http://localhost:5678.
Step 4: Log In and Verify
You should see the n8n login page. Enter your credentials:
- Username:
admin - Password:
changeme(or whatever you set in the Docker Compose file)
After logging in, you’ll see the n8n workflow editor. Your n8n instance is running locally.
Step 5: Configure Email (Optional)
To send emails from your n8n workflows (notifications, alerts, or workflow triggers), configure SMTP settings. If you’re running n8n on a Unix/Linux system, you can use your local mail setup configured with Gmail SMTP.
Option 1: Configure SMTP in n8n
Configure SMTP directly in n8n’s settings:
- In n8n, go to Settings → Community Nodes (or use the Email node directly in workflows)
- When using the Email Send node, configure these SMTP settings:
- SMTP Host:
smtp.gmail.com - SMTP Port:
465(SSL) or587(TLS) - SMTP User: Your Gmail address
- SMTP Password: Your Gmail App Password (not your regular password)
- Enable SSL/TLS: Yes
- SMTP Host:
Important: You’ll need a Gmail App Password. Enable 2FA on your Gmail account, then generate an App Password at Google Account Settings.
Option 2: Use Local Mail System
If you’ve configured your host system to send emails through Gmail SMTP (see How to Send System Emails from Unix/Linux to Gmail), you can use the system’s mail command from within n8n workflows using the Execute Command node. This approach uses your system’s mail configuration that you’ve already set up.
Note: For the Execute Command node to work, you may need to run the n8n container with access to the host’s mail system, or install mail utilities inside the container.
Step 6: Enable Webhook Access (Optional)
Use Cloudflare Tunnel to send webhooks to your local n8n without exposing your machine directly to the internet. It’s free and open-source.
Quick Tunnel (Temporary URL)
For testing, use a quick tunnel that generates a temporary URL:
- Install cloudflared: Download from Cloudflare Zero Trust.
- Create a tunnel: Run this command:
cloudflared tunnel --url http://localhost:5678This provides a temporary URL like https://random-words.trycloudflare.com that changes each time you restart the tunnel.
Persistent URL (Recommended)
For production use, create a named tunnel with a persistent URL:
Authenticate: Run
cloudflared tunnel loginand follow the prompts to authenticate with Cloudflare (free account required).Create a named tunnel:
cloudflared tunnel create n8n- Create a config file (
config.yml):
tunnel:
credentials-file: ~/.cloudflared/.json
ingress:
- hostname: n8n.yourdomain.com
service: http://localhost:5678
- service: http_status:404 Replace <TUNNEL_ID> with the ID shown when you created the tunnel, and n8n.yourdomain.com with your subdomain. The credentials file path uses ~ which works on Mac and Linux. On Windows, use the full path like C:\Users\YOUR_USERNAME\.cloudflared\<TUNNEL_ID>.json.
- Configure DNS (if using your own domain):
You can try the automated DNS route command:
cloudflared tunnel route dns n8n n8n.yourdomain.comIf this fails with an authentication error, manually create the DNS record in Cloudflare:
- Go to Cloudflare Dashboard
- Select your domain
- Go to DNS → Records
- Click Add record:
- Type:
CNAME - Name:
n8n(or your desired subdomain) - Target:
<TUNNEL_ID>.cfargotunnel.com(replace<TUNNEL_ID>with your actual tunnel ID) - Proxy status: Proxied (orange cloud icon)
- Click Save
- Type:
- Run the tunnel:
Start the tunnel with:
cloudflared tunnel --config config.yml runThis runs the tunnel in the foreground. To run it in the background, add & at the end (Mac/Linux) or use a process manager. The tunnel must be running for your n8n instance to be accessible from the internet.
Important: The tunnel process must stay running. If you close your terminal, the tunnel stops. To keep it running permanently:
- Mac/Linux: Use
screenortmuxto run it in a detached session - Windows: Run it in a separate PowerShell window or use a process manager
- All platforms: Set it up as a system service (systemd on Linux, launchd on macOS, Task Scheduler on Windows)
This creates a persistent URL that doesn’t change when you restart the tunnel.
Step 7: Stop and Start N8n
When you’re done working with n8n, stop the container:
docker compose stopTo start it again:
docker compose up -dYour workflows and data persist because they’re stored in the Docker volume.
Step 8: View Logs (Troubleshooting)
If something isn’t working, check the container logs:
docker compose logs -f n8nThe -f flag follows the logs in real time. Press Ctrl+C to stop following.
Common Issues and Solutions
Port 5678 is already in use:
Another application is using port 5678. Change the port mapping in docker-compose.yml:
ports:
- "8080:5678" # Use port 8080 insteadThen access n8n at http://localhost:8080.
Can’t access n8n after starting:
Wait a few more seconds for n8n to start fully. Check the logs with docker compose logs n8n to see if there are errors.
Forgot your password:
Stop the container, remove the volume, and start over:
docker compose down -v
docker compose up -dWarning: This deletes all workflows and data.
Webhooks not working:
Ensure Cloudflare Tunnel is running and pointing to the correct port. Check that n8n’s webhook URL matches your tunnel URL.
Cloudflare Tunnel error (Error 1033):
This means the tunnel isn’t running or isn’t connected. Verify:
- The tunnel process is running:
cloudflared tunnel info n8nshould show active connections - n8n is running:
docker compose psshould show the container as “Up” - DNS is configured: Check that the CNAME record exists in Cloudflare DNS
- The tunnel can reach n8n: Test
curl http://localhost:5678locally
If the tunnel shows “no active connections”, restart it: cloudflared tunnel --config config.yml run
Managing Your N8n Instance
Backup your data:
Your workflows are stored in the Docker volume. First, find your volume name:
docker volume ls | grep n8nThen back up the volume (replace VOLUME_NAME with the actual volume name):
docker run --rm -v VOLUME_NAME:/data -v $(pwd):/backup alpine tar czf /backup/n8n-backup.tar.gz -C /data .Restore from backup:
Replace VOLUME_NAME with the actual volume name to restore your backup:
docker run --rm -v VOLUME_NAME:/data -v $(pwd):/backup alpine tar xzf /backup/n8n-backup.tar.gz -C /dataUpdate n8n:
Pull the latest image and start the container again:
docker compose pull
docker compose up -dNext Steps
Your n8n instance is running locally with persistent storage. You can:
- Create workflows using the visual editor.
- Connect to external services using n8n’s 400+ integrations.
- Use webhooks with Cloudflare Tunnel for external access.
- Customize settings through the n8n interface.
For workflow ideas and examples, see What Is N8n?.
References
- n8n Docker Documentation - Official Docker installation guide
- n8n Docker Compose Examples - Official Docker Compose configurations
- Docker Desktop Documentation - Docker Desktop installation and usage
- Cloudflare Tunnel Documentation - Guide to Cloudflare Tunnel setup
- n8n API Reference - Official API documentation
- How to Send System Emails from Unix/Linux to Gmail - Guide to configuring Gmail SMTP for system emails

Comments #