Skip to main content

Install n8n on Ubuntu

This guide explains how to install and configure n8n on an Ubuntu 24.04 LTS server. n8n is an open-source workflow automation tool: it lets you connect services (APIs, databases, webhooks) and automate tasks via a visual node-based interface, in no-code or low-code.

Deployment uses Docker and Docker Compose, with Nginx as reverse proxy and Let's Encrypt for HTTPS.

Order a Server

To host your n8n instance, HostMyServers offers several suitable options:

Prerequisites

  • SSH access as root or user with sudo
  • Ubuntu 24.04 LTS system
  • A domain name (e.g. n8n.yourdomain.com) with an A record pointing to the server's public IP
  • Ports 80 (HTTP) and 443 (HTTPS) accessible

Required Configuration

ComponentMinimumRecommended
RAM1 GB2-4 GB
CPU1 core2 cores
Storage5 GB10 GB
Network100 Mbps1 Gbps
Default port

n8n listens on port 5678 internally. Nginx reverse-proxies to this port; public access is over HTTPS on 443.

Connect to the Server

Connect via SSH to your server:

ssh user@server_ip_address

System Update

Update the package list before starting:

sudo apt update
sudo apt upgrade -y

Install Docker and Docker Compose

n8n is deployed in a container. If Docker is not installed yet, follow the steps below to add the official Docker repository and install the engine and Docker Compose plugin.

Required packages and Docker GPG key

sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Add Docker repository

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update

Install Docker and Docker Compose

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

Use Docker without sudo (optional)

To run Docker commands without sudo, add your user to the docker group:

sudo usermod -aG docker $USER
newgrp docker

Verify installation:

docker --version
docker compose version

n8n Directory Structure

Create a dedicated directory for n8n, with folders for persistent data and local files:

mkdir -p ~/n8n
cd ~/n8n
mkdir n8n-data
mkdir local-files

The n8n container runs as UID 1000. Set ownership so data is persisted correctly:

sudo chown -R 1000:1000 n8n-data local-files

Docker Compose Configuration for n8n

Create the docker-compose.yml file in ~/n8n (replace n8n.yourdomain.com with your domain):

cd ~/n8n
nano docker-compose.yml

Content:

services:
n8n:
image: n8nio/n8n:latest
container_name: n8n
restart: unless-stopped
ports:
- "5678:5678"
environment:
- N8N_HOST=n8n.yourdomain.com
- N8N_PORT=5678
- N8N_PROTOCOL=https
- WEBHOOK_URL=https://n8n.yourdomain.com
- N8N_EDITOR_BASE_URL=https://n8n.yourdomain.com
- GENERIC_TIMEZONE=Europe/Paris
- N8N_USER_FOLDER=/home/node/.n8n
volumes:
- ./n8n-data:/home/node/.n8n
- ./local-files:/files
networks:
- n8n-network

networks:
n8n-network:
driver: bridge
VariableDescription
N8N_HOSTPublic domain name for n8n
N8N_PROTOCOLProtocol (https in production)
WEBHOOK_URLBase URL for webhooks (must be HTTPS)
N8N_EDITOR_BASE_URLEditor URL (same as public access)
GENERIC_TIMEZONETimezone (e.g. Europe/Paris, UTC)
Replace domain

Adapt n8n.yourdomain.com in all environment variables to your actual domain.

Install and Configure Nginx

Nginx acts as reverse proxy: it receives HTTPS requests and forwards them to the n8n container on port 5678. The configuration includes WebSocket support and timeouts suited to long-running workflows.

Install Nginx

sudo apt install -y nginx

Create virtual host for n8n

Create a configuration file (replace n8n.yourdomain.com with your domain):

sudo nano /etc/nginx/sites-available/n8n.conf

Content:

server {
listen 80;
listen [::]:80;
server_name n8n.yourdomain.com;

location / {
proxy_pass http://localhost:5678;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_buffering off;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
}
}

Enable the site and test configuration:

sudo ln -s /etc/nginx/sites-available/n8n.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Firewall Configuration

Open HTTP and HTTPS ports for web access and Let's Encrypt validation:

sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw reload

TLS Certificate with Certbot (Let's Encrypt)

Certbot obtains and renews a TLS certificate for your domain and updates Nginx for HTTPS.

Install Certbot and Nginx plugin

sudo apt install -y certbot python3-certbot-nginx

Obtain certificate for your domain

Replace n8n.yourdomain.com with your domain and admin@example.com with your email:

sudo certbot --nginx -d n8n.yourdomain.com --email admin@example.com --agree-tos --non-interactive

Certbot updates the Nginx virtual host for HTTPS and configures automatic renewal.

Test renewal

sudo certbot renew --dry-run

Success confirms that automatic renewal is configured.

Start n8n

With Nginx and the certificate in place, start the n8n container:

cd ~/n8n
docker compose up -d

Verify the container is running:

docker compose ps

Check logs to confirm startup:

docker logs n8n

You should see a line like: n8n ready on https://n8n.yourdomain.com.

Access and Initial Setup

  1. Open a browser and go to: https://n8n.yourdomain.com
  2. Create the admin account: email, name and password.
  3. You reach the n8n workflow editor: you can create workflows from templates or from scratch, connect services (Google, Slack, databases, webhooks, etc.) and chain them visually.
Webhooks

n8n workflows can expose webhooks. The base URL used is the one set in WEBHOOK_URL (e.g. https://n8n.yourdomain.com). Ensure the domain and HTTPS certificate are correct so external calls work.

n8n Container Management

CommandDescription
docker logs -f n8nFollow logs in real time
docker compose downStop and remove container
docker compose restartRestart container
docker compose pull && docker compose up -dUpdate image and restart

Update n8n

To move to the latest image version:

cd ~/n8n
docker compose pull
docker compose up -d

Data in n8n-data is preserved.

Directory Structure

PathDescription
~/n8n/n8n project directory
~/n8n/docker-compose.ymlDocker Compose configuration
~/n8n/n8n-data/n8n data (workflows, credentials, etc.)
~/n8n/local-files/Local files accessible from File nodes
/etc/nginx/sites-available/n8n.confNginx configuration (reverse proxy)

Troubleshooting

Container won't start

  • Check logs: docker logs n8n
  • Ensure n8n-data and local-files have ownership 1000:1000: ls -la ~/n8n
  • Ensure port 5678 is not already in use: ss -tlnp | grep 5678

502 Bad Gateway in browser

  • Verify container is running: docker compose ps
  • Verify n8n is listening on 5678: curl -I http://127.0.0.1:5678
  • Check Nginx logs: sudo tail -f /var/log/nginx/error.log

Webhooks not receiving requests

  • Verify WEBHOOK_URL and N8N_EDITOR_BASE_URL in docker-compose.yml use your domain with HTTPS.
  • Restart the container after any variable change: docker compose up -d --force-recreate

Long workflows timing out

The Nginx config already includes proxy_read_timeout 300s. For even longer runs, increase this in /etc/nginx/sites-available/n8n.conf then reload Nginx: sudo systemctl reload nginx.

References