How to install N8N
PHP Developer, Laravel Lover ❤️, Entrepreneur, Founder @ Bee Delivery
Sign up for DigitalOcean using my link and get $200 for your projects, valid for 60 days! Click here: GET $200
This tutorial is available as a video on YouTube: https://www.youtube.com/watch?v=KZh9Wodsa40
Updating the Operating System
Step 1 - Update the operating system.
sudo apt update && sudo apt upgrade -y
Installing Node and NPM
On the official Node.js website, you can download the latest binaries as shown in the figure below. As of this writing, the LTS (long time support) version is 22.22.0. We'll use it in this tutorial.
Step 2 - Use the command below in your terminal to download the binaries.
curl -o node.tar.xz https://nodejs.org/dist/v22.22.0/node-v22.22.0-linux-x64.tar.xz
Step 3 - Use the command below to extract the package and enter the folder.
tar -xf node.tar.xz && cd node-v22.22.0-linux-x64
Step 4 - With the command below, we'll copy the files to make them available globally.
sudo cp -R * /usr/local/
Done! After this, Node should be available for use. Run the commands below to verify.
node -v && npm -v && cd ..
If everything is correct, you should see something like shown in the figure.

PostgreSQL Installation
Step 5 - Install PostgreSQL
sudo apt install postgresql postgresql-contrib -y
Step 6 - Check if the service is active:
sudo systemctl status postgresql
Step 7 - Switch to the administrative postgres user:
sudo -i -u postgres
Step 8 - Open the PostgreSQL prompt:
psql
Step 9 - Now execute the SQL commands:
⚠️ Don't forget to replace with your own secure password.
-- Create a new user
CREATE ROLE n8n_user WITH LOGIN PASSWORD 'put-your-super-strong-password-here';
-- Create database
CREATE DATABASE n8n_db OWNER n8n_user;
-- Grant permissions to the user on the database
GRANT ALL PRIVILEGES ON DATABASE n8n_db TO n8n_user;
GRANT ALL ON SCHEMA public TO n8n_user;
ALTER SCHEMA public OWNER TO n8n_user;
Step 10 - Now disconnect from the database
\q
Step 11 - Disconnect from the postgres user
exit
N8N Installation
Step 12 - Install N8N
npm install n8n -g
Step 13 - Create a specific user for n8n:
sudo adduser --system --group --home /home/n8n n8n
Step 14 - Configure the directory where n8n will store files and credentials.
sudo mkdir -p /home/n8n/.n8n
sudo chown -R n8n:n8n /home/n8n/.n8n
Step 15 - Generate a new encryption key with the command below, we'll use it next.
openssl rand -base64 48
Step 16 - Create a .env file for the service (centralizes configs and makes it easy to maintain):
sudo nano /home/n8n/.n8n/.env
Step 17 - Copy the content below into the .env file you just created.
# ===== Core =====
N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
N8N_USER_FOLDER=/home/n8n/.n8n
N8N_HOST=YOUR-SERVER-IP
N8N_PORT=5678
# If exposing publicly, define BASE_URL (https://your-domain):
# N8N_EDITOR_BASE_URL=https://your-domain
# WEBHOOK_URL=https://your-domain/
N8N_RUNNERS_ENABLED=true
N8N_SECURE_COOKIE=false
# ===== Database (Postgres) =====
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=127.0.0.1
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n_db
DB_POSTGRESDB_USER=n8n_user
DB_POSTGRESDB_PASSWORD=put-your-super-strong-password-here
# Pool (optional, improves stability)
DB_POSTGRESDB_POOL_SIZE=10
# ===== Security (adjust according to your scenario) =====
# Basic Auth for editor
#N8N_BASIC_AUTH_ACTIVE=true
#N8N_BASIC_AUTH_USER=admin
#N8N_BASIC_AUTH_PASSWORD=another-super-strong-password
# Encryption key for credentials
N8N_ENCRYPTION_KEY=PUT-HERE-THE-ENCRYPTION-KEY-YOU-GENERATED
# ===== Queues (optional) - if using queues with Redis =====
# QUEUE_BULL_REDIS_HOST=127.0.0.1
# QUEUE_BULL_REDIS_PORT=6379
Step 18 - Apply restrictive permissions:
sudo chmod 600 /home/n8n/.n8n/.env
Step 19 - Create the service file to run n8n with systemd.
This ensures that n8n is started automatically with the server and is monitored.
sudo nano /etc/systemd/system/n8n.service
Step 20 - Copy the content below to the file you just created.
[Unit]
Description=n8n Automation (Workflow) Service
After=network-online.target postgresql.service
Wants=network-online.target
[Service]
# Dedicated user
User=n8n
Group=n8n
EnvironmentFile=/home/n8n/.n8n/.env
WorkingDirectory=/home/n8n
# App startup
ExecStart=/usr/local/bin/n8n start
Restart=always
RestartSec=5
# Limits and robustness
LimitNOFILE=65535
# Logs to journal (journalctl)
StandardOutput=journal
StandardError=journal
# Hardening (adjust if you need access outside home)
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=read-only
ReadWritePaths=/home/n8n /tmp /var/tmp
# If n8n needs to bind ports <1024, remove the line below
CapabilityBoundingSet=
AmbientCapabilities=
# Longer timeout for initial migrations
TimeoutStartSec=120
[Install]
WantedBy=multi-user.target
Step 21 - Reload systemd, enable the n8n service at startup and start it immediately.
sudo systemctl daemon-reload
sudo systemctl enable n8n
sudo systemctl start n8n
Step 22 - Check if the service is running correctly.
systemctl status n8n
journalctl -u n8n -f
Troubleshooting
If you see a migration/permission error in Postgres, run a manual test:
sudo -u n8n env $(cat /home/n8n/.n8n/.env | xargs) n8n start
This way you can see errors with the same variables as the service.
Did I help you?
Buy me a beer! 🍺😁
PIX QrCode
