- README.md 2 weeks ago
Self-Hosting SSL enabled N8N on a Linux Server
This guide provides step-by-step instructions to self-host n8n, a free and open-source workflow automation tool, on a Linux server using Docker, Nginx, and Certbot for SSL with a custom domain name.
Step 1: Installing Docker
Update the Package Index:
sudo apt update
Install Docker:
sudo apt install docker.io
Start Docker:
sudo systemctl start docker
Enable Docker to Start at Boot:
sudo systemctl enable docker
Step 2: Starting n8n in Docker
Run the following command to start n8n in Docker. Replace your-domain.com with your actual domain name:
sudo docker run -d --restart unless-stopped -it \
--name n8n \
-p 5678:5678 \
-e N8N_HOST="your-domain.com" \
-e WEBHOOK_TUNNEL_URL="https://your-domain.com/" \
-e WEBHOOK_URL="https://your-domain.com/" \
-v ~/.n8n:/root/.n8n \
n8nio/n8n
Or if you are using a subdomain, it should look like this:
sudo docker run -d --restart unless-stopped -it \
--name n8n \
-p 5678:5678 \
-e N8N_HOST="subdomain.your-domain.com" \
-e WEBHOOK_TUNNEL_URL="https://subdomain.your-domain.com/" \
-e WEBHOOK_URL="https://subdomain.your-domain.com/" \
-v ~/.n8n:/root/.n8n \
n8nio/n8n
This command does the following:
- Downloads and runs the n8n Docker image.
- Exposes n8n on port 5678.
- Sets environment variables for the n8n host and webhook tunnel URL.
- Mounts the n8n data directory for persistent storage.
After executing the command, n8n will be accessible on your-domain.com:5678.
Step 3: Installing Nginx
Nginx is used as a reverse proxy to forward requests to n8n and handle SSL termination.
Install Nginx:
sudo apt install nginx
Step 4: Configuring Nginx
Configure Nginx to reverse proxy the n8n web interface:
Create a New Nginx Configuration File:
sudo nano /etc/nginx/sites-available/n8n.conf
Paste the Following Configuration:
server {
listen 80;
server_name your-domain.com; // subdomain.your-domain.com if you have a subdomain
location / {
proxy_pass http://localhost:5678;
proxy_http_version 1.1;
chunked_transfer_encoding off;
proxy_buffering off;
proxy_cache off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s; # allow up to 1 hour for long-running n8n workflows
proxy_send_timeout 3600s; # allow up to 1 hour for large incoming payloads or slow triggers
}
}
Replace your-domain.com with your actual domain.
Enable the Configuration:
sudo ln -s /etc/nginx/sites-available/n8n.conf /etc/nginx/sites-enabled/
If you see the error saying /etc/nginx/sites-enabled/ doesn't exist. Create it by running: sudo mkdir /etc/nginx/sites-enabled/
Test the Nginx Configuration and Restart:
sudo nginx -t
sudo systemctl restart nginx
Step 5: Setting up SSL with Certbot
Certbot will obtain and install an SSL certificate from Let's Encrypt.
Install Certbot and the Nginx Plugin:
sudo apt install certbot python3-certbot-nginx
Obtain an SSL Certificate:
sudo certbot --nginx -d your-domain.com
// If you have a subdomain then it will be subdomain.your-domain.com
Follow the on-screen instructions to complete the SSL setup. Once completed, n8n will be accessible securely over HTTPS at your-domain.com.
IMPORTANT: Make sure you follow the above steps in order. Step 5 will modify your /etc/nginx/sites-available/n8n.conf file to something like this: image
How to update n8n:
You can follow the instructions here to update the version: https://docs.n8n.io/hosting/installation/docker/#updating
Important: Take a backup of ~/.n8n:/home/node/.n8n To create a backup, you can copy ~/.n8n:/home/node/.n8n to your local or another directory on the same VM even before deleting the container. And then, after updating and spinning up a new container, if you see the data getting lost, you can replace ~/.n8n:/home/node/.n8n with the one you saved earlier.
Ensure that your n8n instance is using a persistent volume or a mapped directory for its data storage. This is crucial because the workflows, user accounts, and configurations are stored in the database file (typically database.sqlite), which should be located in a directory that remains intact even when the container is removed. In your docker-compose.yml, you should have something like this:
volumes:
- ~/.