This repository contains a Docker Compose setup to run n8n workflow automation on a Raspberry Pi with PostgreSQL as the database backend.
- Raspberry Pi 4 (4GB RAM minimum, 8GB recommended)
- 32GB+ SD card (64GB+ recommended)
- Stable power supply
- Raspberry Pi OS (64-bit recommended) or compatible Linux distribution
- Docker installed
- Docker Compose installed
On Raspberry Pi OS, run:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.shsudo usermod -aG docker $USER
newgrp dockerDocker Compose is usually included with modern Docker installations. Verify with:
docker compose versionIf not installed:
sudo apt-get update
sudo apt-get install docker-compose-plugincd /home/pi
git clone <repository-url> n8n-setup
cd n8n-setupOr copy the files to your desired directory.
Copy the example environment file:
cp env.example .envEdit .env and set the following required values:
- POSTGRES_PASSWORD: Set a strong password for PostgreSQL
- N8N_BASIC_AUTH_PASSWORD: Set a password for n8n web interface access
- N8N_ENCRYPTION_KEY: Generate a strong encryption key (minimum 32 characters)
Generate an encryption key:
openssl rand -hex 32Update WEBHOOK_URL if you plan to access n8n from other devices on your network:
# Replace with your Raspberry Pi's IP address
WEBHOOK_URL=http://192.168.1.100:5678docker compose up -dThis will:
- Pull the required Docker images (ARM-compatible versions)
- Create network and volumes
- Start PostgreSQL database
- Start n8n application
Check that containers are running:
docker compose psCheck logs:
docker compose logs -fOpen your web browser and navigate to:
http://localhost:5678
Or if accessing from another device on your network:
http://<raspberry-pi-ip>:5678
Login with the credentials set in .env:
- Username: Value of
N8N_BASIC_AUTH_USER(default:admin) - Password: Value of
N8N_BASIC_AUTH_PASSWORD
ngrok allows you to expose your n8n instance to the internet, enabling external webhook access and remote management.
- Create ngrok Account: Sign up at https://ngrok.com (free tier available)
- Get Auth Token:
- Go to https://dashboard.ngrok.com/get-started/your-authtoken
- Copy your authtoken
-
Add ngrok Token to
.env:NGROK_AUTHTOKEN=your_ngrok_auth_token_here
-
Optional Settings (in
.env):# Static domain (requires paid ngrok plan) NGROK_DOMAIN=your-static-domain.ngrok-free.app # Region selection (us, eu, ap, au, sa, jp, in) NGROK_REGION=us # ngrok web interface port NGROK_WEB_PORT=4040
Start all services including ngrok:
# Start with ngrok profile
docker compose --profile ngrok up -d
# Or start normally, then start ngrok separately
docker compose up -d
docker compose --profile ngrok up -d ngrokOption 1: ngrok Dashboard (Recommended)
- Access the ngrok dashboard:
http://localhost:4040 - Find your public HTTPS URL (e.g.,
https://abc123.ngrok-free.app)
Option 2: ngrok API
curl http://localhost:4040/api/tunnels | jq -r '.tunnels[0].public_url'Option 3: ngrok Logs
docker compose logs ngrokAfter getting your ngrok URL, update WEBHOOK_URL in .env:
# For free tier (URL changes on restart)
WEBHOOK_URL=https://abc123.ngrok-free.app
# For paid tier with static domain
WEBHOOK_URL=https://your-static-domain.ngrok-free.appThen restart n8n to apply the change:
docker compose restart n8nYou can now access n8n from anywhere:
https://your-ngrok-url.ngrok-free.app
Note: ngrok free tier shows an interstitial warning page on first access. Users need to click "Visit Site" to proceed.
View ngrok Status:
docker compose ps ngrok
docker compose logs ngrokStop ngrok:
docker compose --profile ngrok stop ngrokRestart ngrok:
docker compose --profile ngrok restart ngrokngrok not starting:
- Verify
NGROK_AUTHTOKENis set correctly in.env - Check logs:
docker compose logs ngrok - Ensure n8n service is running:
docker compose ps n8n
Can't access ngrok URL:
- Verify ngrok is running:
docker compose ps ngrok - Check ngrok dashboard for errors:
http://localhost:4040 - Ensure firewall allows outbound connections
URL changes on restart (Free Tier):
- This is normal for ngrok free tier
- Consider upgrading to paid plan for static domains
- Or use ngrok API to dynamically update webhook URLs
# All services
docker compose logs -f
# Specific service
docker compose logs -f n8n
docker compose logs -f postgresdocker compose stopdocker compose startdocker compose restartdocker compose downdocker compose down -vdocker compose pull n8n
docker compose up -ddocker compose exec postgres pg_dump -U n8n n8n > backup_$(date +%Y%m%d_%H%M%S).sqldocker run --rm \
-v n8n-setup_n8n_data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/n8n_data_backup_$(date +%Y%m%d_%H%M%S).tar.gz /dataCreate a backup script:
#!/bin/bash
BACKUP_DIR="/home/pi/backups/n8n"
mkdir -p "$BACKUP_DIR"
# Database backup
docker compose exec -T postgres pg_dump -U n8n n8n | gzip > "$BACKUP_DIR/db_$(date +%Y%m%d_%H%M%S).sql.gz"
# Data volume backup
docker run --rm \
-v n8n-setup_n8n_data:/data \
-v "$BACKUP_DIR":/backup \
alpine tar czf "/backup/n8n_data_$(date +%Y%m%d_%H%M%S).tar.gz" /data
# Keep only last 7 days
find "$BACKUP_DIR" -name "*.gz" -mtime +7 -deleteMake it executable and add to cron:
chmod +x backup.sh
crontab -e
# Add: 0 2 * * * /home/pi/n8n-setup/backup.shcat backup_YYYYMMDD_HHMMSS.sql | docker compose exec -T postgres psql -U n8n n8ndocker run --rm \
-v n8n-setup_n8n_data:/data \
-v $(pwd):/backup \
alpine sh -c "cd / && tar xzf /backup/n8n_data_backup_YYYYMMDD_HHMMSS.tar.gz"docker compose psdocker compose logs n8n
docker compose logs postgres
docker compose logs ngrokdf -h
docker system dfdocker compose restartdocker compose stop n8n
docker compose rm -f n8n
docker compose up -d n8n- Check memory usage:
free -h - Check CPU:
htop - Reduce PostgreSQL connections if needed
- Consider limiting n8n execution concurrency
- Verify PostgreSQL is healthy:
docker compose ps postgres - Check logs:
docker compose logs postgres - Verify credentials in
.env - Test connection manually:
docker compose exec postgres psql -U n8n -d n8n
- Change Default Passwords: Always use strong passwords in
.env - Generate Encryption Key: Use a strong, randomly generated encryption key
- Firewall: If exposing to network, configure firewall:
sudo ufw allow 5678/tcp
- HTTPS: For production, use a reverse proxy (nginx/traefik) with SSL certificates
- Backups: Regular backups protect against data loss
- Updates: Keep Docker images updated regularly
For production use, consider setting up nginx or traefik as a reverse proxy with SSL certificates (Let's Encrypt).
This setup is provided as-is. Please refer to n8n's license for usage terms.