Automation is becoming a central component in homelabs and enterprise environments. I have been using Node-RED for years, and after seeing a YouTube video demonstrating the integration of cloud models, I wanted to evaluate n8n as a potential alternative. n8n is an open-source workflow automation tool that can integrate APIs, databases, and third-party services without requiring extensive coding. Running n8n in a Proxmox LXC container on AlmaLinux provides a lightweight and efficient deployment option.

Self-Hosted vs. n8n Cloud
n8n is published as open source and can be run for free when self-hosted. This distinction is important:
- Self-Hosted (Free)
- Completely free to use on your own infrastructure
- Full control over data and workflows
- Runs easily on Proxmox, Docker, or any Linux system
- Perfect for homelabs, small teams, or internal automation
- n8n Cloud (Paid)
- Managed SaaS offering from the n8n team
- Subscription-based pricing model
- Includes monitoring, scaling, and managed backups
- Requires no server maintenance
- Aimed at businesses preferring a hands-off solution
The key difference:
The open-source edition is free only if you self-host. If you choose n8n Cloud, a subscription plan is mandatory. For most homelab or private users, self-hosting on Proxmox is the best option to stay cost-free.
Preparing the LXC Container
- Deploy an AlmaLinux container in Proxmox
- Assign resources depending on workload (e.g., 2 vCPU, 2–4 GB RAM)
- Update the container system packages:
sudo dnf update -y
Installing Node.js and Dependencies
n8n requires Node.js. On AlmaLinux, install via module streams:
sudo dnf module reset nodejs -y
sudo dnf module enable nodejs:20 -y
sudo dnf install -y nodejs npm
Verify installation:
node -v
npm -v
Installing n8n
Install n8n globally using npm:
sudo npm install -g n8n
Check version:
n8n --version
Configuring Systemd Service
To run n8n persistently, create a Systemd service file:
sudo dnf install nano vim-enhanced -y
sudo nano /etc/systemd/system/n8n.service
Example content:
[Unit]
Description=n8n Workflow Automation
After=network.target
[Service]
ExecStart=/usr/local/bin/n8n
Restart=always
User=root
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
Environment=N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
Environment=N8N_RUNNERS_ENABLED=true
Environment="N8N_SECURE_COOKIE=false"
WorkingDirectory=/root
[Install]
WantedBy=multi-user.target
Enable and start the service:
sudo systemctl enable n8n
sudo systemctl start n8n
Check status:
sudo systemctl status n8n
sudo ss -tulpen | grep 5678
Reverse Proxy with Nginx
It is essential to run n8n behind a reverse proxy with a valid SSL certificate.
By default, n8n enforces secure cookies for authentication, which only work properly when accessed over HTTPS. Without SSL, browsers will reject or block the session cookies, leading to unstable behavior. This is why you may encounter issues such as:
- “Your n8n server is configured to use a secure cookie, however you are either visiting this via an insecure URL.”
- “connection lost”
Using a reverse proxy with HTTPS ensures that secure cookies are accepted, protects sensitive workflow data in transit, and provides stable and reliable long-term access in production environments.
Install NGINX on AlmaLinux / RHEL-based systems:
sudo dnf install -y nginx
sudo systemctl enable --now nginx
Create a new config file, e.g. /etc/nginx/conf.d/n8n.conf
:
server {
listen 80;
server_name n8n.example.de;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name n8n.example.com;
ssl_certificate /etc/nginx/conf.d/n8n.example.com.crt;
ssl_certificate_key /etc/nginx/conf.d/n8n.example.com.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://127.0.0.1:5678/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
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_read_timeout 300s;
proxy_send_timeout 300s;
}
}
After saving, test and reload Nginx:
sudo nginx -t
sudo systemctl reload nginx
Setup

Migrate to PostgreSQL
By default, n8n uses SQLite. It’s simple and lightweight, but not ideal for production:
- Poor concurrency handling (locks during parallel executions).
- Performance drops as workflows grow.
- Backups and replication are cumbersome.
PostgreSQL is the recommended backend:
- Easier integration – fits well with monitoring, failover, and HA setups.
- Scalable – handles larger workloads without locking issues.
- Stable – proven in production environments.
- Flexible backups – with
pg_dump
or replication.

Important Note:
Before migrating n8n to a new database (e.g., from SQLite to PostgreSQL), always export your workflows as JSON.
- During migration, the admin user in the new system is newly created.
- Workflow ownership is tied to users, so imported workflows will not automatically be assigned to the new admin user.
- Exporting as JSON ensures you can re-import your workflows and assign them correctly.
- Remember: Credentials must be exported separately, otherwise workflows may fail after import.
Always perform the JSON export before any database migration to avoid losing workflow access.
Install PostgreSQL on AlmaLinux
# Install packages
sudo dnf install -y postgresql-server postgresql
# initialize database
sudo postgresql-setup --initdb
# enable + start service
sudo systemctl enable --now postgresql
Create database and user
sudo -u postgres psql
CREATE USER n8n WITH ENCRYPTED PASSWORD 'securepw';
CREATE DATABASE n8n OWNER n8n;
ALTER DATABASE n8n OWNER TO n8n;
\q
Configure PostgreSQL Authentication for n8n
By default, PostgreSQL on AlmaLinux uses ident authentication for local connections. n8n requires password-based authentication. To enable it, update the pg_hba.conf
file so that local connections use md5
:
Important: The n8n-specific block in
pg_hba.conf
must be placed before the default rules. PostgreSQL applies the first matching rule it finds, so if the general rules (local all all peer
orhost all all …
) appear first, your n8n user will not use password authentication and logins will fail.
sudo cp /var/lib/pgsql/data/pg_hba.conf{,.default}
vim /var/lib/pgsql/data/pg_hba.conf
[...]
# TYPE DATABASE USER ADDRESS METHOD
# n8n-specific rules
local n8n n8n md5
host n8n n8n 127.0.0.1/32 md5
host n8n n8n ::1/128 md5
# "local" is for Unix domain socket connections only
local all all peer
# IPv4 local connections:
host all all 127.0.0.1/32 ident
# IPv6 local connections:
host all all ::1/128 ident
[...]
systemctl restart postgresql
This ensures that n8n can connect to PostgreSQL reliably.
Configure n8n to use PostgreSQL
Edit systemd environment or .env
:
sudo nano /etc/systemd/system/n8n.service
Environment=DB_TYPE=postgresdb
Environment=DB_POSTGRESDB_HOST=127.0.0.1
Environment=DB_POSTGRESDB_PORT=5432
Environment=DB_POSTGRESDB_DATABASE=n8n
Environment=DB_POSTGRESDB_USER=n8n
Environment=DB_POSTGRESDB_PASSWORD=securepw
Stop the old n8n service, then restart with the new settings. On first start, n8n will create the tables in PostgreSQL.
systemctl daemon-reload
systemctl restart n8n
journalctl -u n8n -f
Set or Reset the n8n PostgreSQL Password
To ensure n8n can connect to PostgreSQL, set a password for the n8n
user:
sudo -u postgres psql -c "ALTER USER n8n WITH PASSWORD 'securepw';"
Note: You might see a warning like
could not change directory to "/root": Permission denied
This is normal when runningpsql
viasudo
from/root
and does not indicate an error. The password is still updated correctly.
After this, you can verify the password works:
psql -h 127.0.0.1 -U n8n -d n8n -W
If prompted for the password, enter the one you just set. You should get a working n8n=#
prompt.
Backup
To secure workflows and configurations:
- Backup workflow database (SQLite by default):
cp ~/.n8n/database.sqlite ~/backups/n8n_database.sqlite
- Backup configuration files:
cp -r ~/.n8n ~/backups/n8n_config
- Automate backups with cron:
0 2 * * * cp ~/.n8n/database.sqlite ~/backups/n8n_database_$(date +\%F).sqlite
- Backup the postgresql database with
pg_dump
:
pg_dump -U n8n -h 127.0.0.1 -F c n8n > ~/backups/n8n_database_$(date +%F).dump
-U n8n
→ DB user-h 127.0.0.1
→ Host-F c
→ Custom format (recommended for restore)n8n
→ Database name
- Automate with cron:
0 2 * * * pg_dump -U n8n -h 127.0.0.1 -F c n8n > ~/backups/n8n_database_$(date +%F).dump
Ensure backups are copied outside of the LXC container (e.g., Proxmox storage or NFS).
Upgrade
Keeping n8n updated ensures security and access to new features.
- Update system packages:
sudo dnf update -y
- Update Node.js if necessary:
node -v
sudo dnf module reset nodejs -y
sudo dnf module enable nodejs:20 -y
sudo dnf install -y nodejs npm
- Stop the n8n service:
sudo systemctl stop n8n
- Upgrade n8n:
sudo npm install -g n8n
- Restart the service:
sudo systemctl daemon-reload
sudo systemctl start n8n
- Verify logs:
sudo journalctl -u n8n -f
Always perform a backup before upgrading.
n8n export:workflow --all --separate --output=./backup/workflows
n8n export:credentials --all --separate --output=./backup/credentials
Security and Operational Considerations
- Nginx configured without authentication for simplicity
- TLS recommended for production (Let’s Encrypt)
- Keep AlmaLinux, Node.js, and n8n updated
- Monitor workflows via Systemd logs or alerting mechanisms
Conclusion
Running n8n in an AlmaLinux LXC container on Proxmox with an nginx reverse proxy provides a self-hosted, cost-free workflow automation environment. Logging is integrated for operational transparency, backups ensure recovery of workflows, databases, and execution history, and upgrade procedures allow maintaining security and stability. Optional AI integration enables automated content processing, making this setup ideal for small teams or home-office environments.