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?]({{< ref "/blog/what-x/what-is-n8n/index.md" >}}) first to understand what it does.
## Prerequisites
Before starting, ensure you have:
* **Docker installed**: Download Docker Desktop for [Windows](https://www.docker.com/products/docker-desktop/), [Mac](https://www.docker.com/products/docker-desktop/), or [Linux](https://docs.docker.com/engine/install/).
* **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.
```bash
mkdir n8n-self-host
cd n8n-self-host
```
This 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.
```yaml
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 `admin` and password `changeme`. 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):**
```powershell
docker compose up -d
```
**On Mac or Linux:**
```bash
docker compose up -d
```
The `-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:
1. In n8n, go to **Settings** → **Community Nodes** (or use the Email node directly in workflows)
2. When using the **Email Send** node, configure these SMTP settings:
* **SMTP Host**: `smtp.gmail.com`
* **SMTP Port**: `465` (SSL) or `587` (TLS)
* **SMTP User**: Your Gmail address
* **SMTP Password**: Your Gmail App Password (not your regular password)
* **Enable SSL/TLS**: Yes
**Important**: You'll need a Gmail App Password. Enable 2FA on your Gmail account, then generate an App Password at [Google Account Settings](https://myaccount.google.com/apppasswords).
### 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](https://jeffbailey.us/blog/2022/04/16/how-do-i-send-emails-with-unix-and-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](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/install-and-setup/installation/).
* **Create a tunnel**: Run this command:
```bash
cloudflared tunnel --url http://localhost:5678
```
This 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 login` and follow the prompts to authenticate with Cloudflare (free account required).
* **Create a named tunnel**:
```bash
cloudflared tunnel create n8n
```
* **Create a config file** (`config.yml`):
```yaml
tunnel: <TUNNEL_ID>
credentials-file: ~/.cloudflared/<TUNNEL_ID>.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:
```bash
cloudflared tunnel route dns n8n n8n.yourdomain.com
```
If this fails with an authentication error, manually create the DNS record in Cloudflare:
1. Go to [Cloudflare Dashboard](https://dash.cloudflare.com)
2. Select your domain
3. Go to **DNS** → **Records**
4. 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**
* **Run the tunnel**:
Start the tunnel with:
```bash
cloudflared tunnel --config config.yml run
```
This 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 `screen` or `tmux` to 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:
```bash
docker compose stop
```
To start it again:
```bash
docker compose up -d
```
Your 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:
```bash
docker compose logs -f n8n
```
The `-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`:
```yaml
ports:
- "8080:5678" # Use port 8080 instead
```
Then 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:
```bash
docker compose down -v
docker compose up -d
```
**Warning**: 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:
1. The tunnel process is running: `cloudflared tunnel info n8n` should show active connections
2. n8n is running: `docker compose ps` should show the container as "Up"
3. DNS is configured: Check that the CNAME record exists in Cloudflare DNS
4. The tunnel can reach n8n: Test `curl http://localhost:5678` locally
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:
```bash
docker volume ls | grep n8n
```
Then back up the volume (replace `VOLUME_NAME` with the actual volume name):
```bash
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:
```bash
docker run --rm -v VOLUME_NAME:/data -v $(pwd):/backup alpine tar xzf /backup/n8n-backup.tar.gz -C /data
```
**Update n8n:**
Pull the latest image and start the container again:
```bash
docker compose pull
docker compose up -d
```
## Next 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?]({{< ref "/blog/what-x/what-is-n8n/index.md" >}}).
## References
* [n8n Docker Documentation](https://docs.n8n.io/hosting/installation/docker/) - Official Docker installation guide
* [n8n Docker Compose Examples](https://github.com/n8n-io/n8n-hosting/tree/main/docker-compose) - Official Docker Compose configurations
* [Docker Desktop Documentation](https://docs.docker.com/desktop/) - Docker Desktop installation and usage
* [Cloudflare Tunnel Documentation](https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/) - Guide to Cloudflare Tunnel setup
* [n8n API Reference](https://docs.n8n.io/api/api-reference) - Official API documentation
* [How to Send System Emails from Unix/Linux to Gmail](https://jeffbailey.us/blog/2022/04/16/how-do-i-send-emails-with-unix-and-gmail/) - Guide to configuring Gmail SMTP for system emails