Install n8n on Ubuntu
This guide explains how to manually install n8n on Ubuntu from the command line, run it as a systemd service, place it behind Nginx, and optionally protect the web interface with a browser username and password using Nginx Basic Authentication.
This is the manual equivalent of an automated deployment and is useful for customers who want full control over the installation.
What this setup will do
- Install required packages
- Install Node.js 22
- Install a specific version of n8n globally with npm
- Create a dedicated system user for n8n
- Create an n8n environment file
- Create a systemd service for n8n
- Configure Nginx as a reverse proxy
- Optionally enable browser login protection with Nginx Basic Auth
- Show exactly where to disable browser login access later if needed
Requirements
Before starting, make sure you have the following:
- An Ubuntu server
- Root or sudo access
- A domain name already pointing to the server
- Ports 80 and 443 open in the firewall
- A chosen n8n version
- A strong encryption key for n8n
In the examples below, replace these values with your own:
yourdomain.comn8n/var/lib/n8n5678Africa/JohannesburgYOUR_STRONG_RANDOM_ENCRYPTION_KEYadminuserStrongBrowserPassword123!
1) Determine the server IP
This is mainly for confirmation. Your domain should already point to the server.
hostname -I
Or:
ip route get 1 | awk '{print $(NF-2); exit}'
2) Install base packages
Update package lists and install the required dependencies:
sudo apt update
sudo apt install -y curl make gcc g++ ca-certificates gnupg nginx apache2-utils certbot python3-certbot-nginx
These packages are used for Node.js installation, Nginx, browser authentication, and SSL certificate provisioning.
3) Add the NodeSource repository for Node.js 22
Create the keyring directory if needed:
sudo mkdir -p /etc/apt/keyrings
sudo chmod 755 /etc/apt/keyrings
Add the NodeSource setup for Node.js 22:
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -
Then refresh apt:
sudo apt update
4) Install Node.js
sudo apt install -y nodejs
Confirm installation:
node -v
npm -v
5) Create the n8n group and user
Create the system group:
sudo groupadd --system n8n
Create the system user:
sudo useradd --system \
--gid n8n \
--home-dir /var/lib/n8n \
--create-home \
--shell /usr/sbin/nologin \
n8n
Set correct ownership and permissions on the n8n home directory:
sudo mkdir -p /var/lib/n8n
sudo chown n8n:n8n /var/lib/n8n
sudo chmod 750 /var/lib/n8n
6) Install a specific version of n8n globally
Install the version you want. Example:
sudo npm install -g n8n@2.11.3
Confirm it is installed:
n8n --version
If you prefer the latest version instead:
sudo npm install -g n8n
7) Create the n8n environment file
Create the environment file:
sudo nano /etc/n8n.env
Paste the following and adjust it to your environment:
N8N_HOST=yourdomain.com
N8N_PORT=5678
N8N_PROTOCOL=http
NODE_ENV=production
WEBHOOK_URL=https://yourdomain.com/
N8N_PROXY_HOPS=1
GENERIC_TIMEZONE=Africa/Johannesburg
TZ=Africa/Johannesburg
N8N_SECURE_COOKIE=true
N8N_ENCRYPTION_KEY=YOUR_STRONG_RANDOM_ENCRYPTION_KEY
# Keep local storage in the n8n user's home
N8N_USER_FOLDER=/var/lib/n8n
# Optional hardening
N8N_PUBLIC_API_DISABLED=true
Then apply secure permissions:
sudo chown root:n8n /etc/n8n.env
sudo chmod 640 /etc/n8n.env
/etc/n8n.env.8) Create the systemd service
Create the service file:
sudo nano /etc/systemd/system/n8n.service
Paste the following:
[Unit]
Description=n8n workflow automation
After=network.target
[Service]
Type=simple
User=n8n
Group=n8n
EnvironmentFile=/etc/n8n.env
WorkingDirectory=/var/lib/n8n
ExecStart=/usr/bin/env n8n start
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Reload systemd and start the service:
sudo systemctl daemon-reload
sudo systemctl enable n8n
sudo systemctl start n8n
Check status:
sudo systemctl status n8n
View live logs:
journalctl -u n8n -f
9) Create the browser login credentials for Nginx
If you want to protect the n8n web interface with a browser username and password, create an htpasswd file:
sudo htpasswd -c /etc/nginx/.htpasswd-n8n adminuser
You will be prompted to enter the password.
To add more users later, omit the -c so the file is not overwritten:
sudo htpasswd /etc/nginx/.htpasswd-n8n anotheruser
10) Configure Nginx as reverse proxy
Create the Nginx site configuration file:
sudo nano /etc/nginx/sites-available/n8n
Paste the following configuration:
server {
listen 80;
server_name yourdomain.com;
client_max_body_size 20M;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Host $host;
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 Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Browser login protection
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd-n8n;
}
}
Enable the site:
sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/n8n
Test and reload Nginx:
sudo nginx -t
sudo systemctl reload nginx
At this point, browsing to http://yourdomain.com should prompt for a username and password before showing n8n.
11) Enable HTTPS with Certbot
Once the site is reachable over HTTP, obtain and apply an SSL certificate:
sudo certbot --nginx -d yourdomain.com
Follow the prompts to complete the SSL setup.
How browser login protection works
The browser login prompt is not controlled by n8n itself. It is controlled by Nginx Basic Authentication.
The feature is enabled by these two lines inside the Nginx location / block:
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd-n8n;
If these lines are present, users will be prompted for a browser username and password before they can access the n8n web interface.
How to disable browser login protection
To disable the browser login prompt, edit the Nginx site configuration file:
sudo nano /etc/nginx/sites-available/n8n
Find these lines:
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd-n8n;
Either remove them completely or comment them out like this:
# auth_basic "Restricted Access";
# auth_basic_user_file /etc/nginx/.htpasswd-n8n;
Then test and reload Nginx:
sudo nginx -t
sudo systemctl reload nginx
/etc/nginx/sites-available/n8nThat is the main file where browser login access is enabled or disabled.
How to re-enable browser login protection later
If you want to turn it back on later, edit the same file again:
sudo nano /etc/nginx/sites-available/n8n
Add these lines back inside the location / block:
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd-n8n;
Then test and reload Nginx:
sudo nginx -t
sudo systemctl reload nginx
Full Nginx example with browser login enabled
server {
listen 80;
server_name yourdomain.com;
client_max_body_size 20M;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Host $host;
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 Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd-n8n;
}
}
Full Nginx example with browser login disabled
server {
listen 80;
server_name yourdomain.com;
client_max_body_size 20M;
location / {
proxy_pass http://127.0.0.1:5678;
proxy_http_version 1.1;
proxy_set_header Host $host;
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 Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Useful commands
Restart n8n
sudo systemctl restart n8n
View n8n logs
journalctl -u n8n -f
Restart Nginx
sudo systemctl restart nginx
Test Nginx configuration
sudo nginx -t
Check listening ports
sudo ss -tulpn | grep -E '5678|80|443'
Troubleshooting
n8n service fails to start
Check the logs:
journalctl -u n8n -n 100 --no-pager
Common causes include:
- Invalid syntax in
/etc/n8n.env - Wrong ownership or permissions on
/var/lib/n8n - Node.js or n8n not installed correctly
- Invalid or missing
N8N_ENCRYPTION_KEY
Browser login prompt does not appear
Confirm the following lines exist in the Nginx configuration:
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd-n8n;
Also verify the password file exists:
ls -l /etc/nginx/.htpasswd-n8n
Then reload Nginx:
sudo nginx -t && sudo systemctl reload nginx
Browser login prompt appears but credentials fail
Reset the user password:
sudo htpasswd /etc/nginx/.htpasswd-n8n adminuser
Then reload Nginx:
sudo systemctl reload nginx
Site works locally but not through the domain
Check the following:
- The domain points to the correct server IP
- Ports 80 and 443 are open
- Nginx is running
- Certbot completed successfully
Summary
To manually install n8n on Ubuntu:
- Install required packages
- Install Node.js 22
- Install n8n globally with npm
- Create the n8n user and storage folder
- Create
/etc/n8n.env - Create
/etc/systemd/system/n8n.service - Configure Nginx reverse proxy
- Optionally protect browser access using htpasswd
- Issue SSL using Certbot
The place to enable or disable browser login access is:
/etc/nginx/sites-available/n8n
The exact lines that control it are:
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd-n8n;
Remove or comment out those lines to disable browser login protection.

