Running n8n in a Proxmox LXC Container

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 or host 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 running psql via sudo 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.