Menu
Buy VPS
Payments
Tools
User

DropVPS Team

Writer: Cooper Reagan

How to install n8n on RHEL 9

How to install n8n on RHEL 9

Publication Date

Category

Articles

Reading Time

5 Min

Table of Contents

Deploying n8n on RHEL 9 is straightforward and reliable with Docker and PostgreSQL. The setup below focuses on persistence, SELinux compatibility, and production readiness. Expect a clean directory layout, secure configuration, and service management with systemd. You’ll go from a fresh RHEL 9 box to a working n8n web UI with HTTPS support.

Prepare RHEL 9 and firewall

Update the OS, set the timezone, and open required ports. This ensures a secure baseline and network reachability for the n8n UI and optional HTTPS.

sudo dnf -y update
sudo timedatectl set-timezone UTC
sudo firewall-cmd --add-port=5678/tcp --permanent
sudo firewall-cmd --add-service=http --permanent
sudo firewall-cmd --add-service=https --permanent
sudo firewall-cmd --reload

Install Docker Engine

RHEL 9 ships with Podman, but Docker Engine with the Compose plugin offers a simple path for n8n. Enable the Docker repository, install, and activate the service.

sudo dnf -y install dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
sudo dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
sudo usermod -aG docker $USER
newgrp docker

Create n8n project directories

Set up a workspace with persistent volumes. Use UID/GID 1000 to match the n8n container’s user. SELinux relabeling will be applied later via Compose.

mkdir -p ~/n8n/data/n8n ~/n8n/data/postgres
sudo chown -R 1000:1000 ~/n8n/data/n8n
cd ~/n8n

Configure environment variables

Create an .env file to hold database credentials, host URLs, and security keys. The encryption key secures credentials stored by n8n.

openssl rand -hex 24

Copy the hex string, then create the file:

cat > .env <<'EOF'
# n8n core
GENERIC_TIMEZONE=UTC
N8N_HOST=your.domain.com
N8N_PORT=5678
N8N_PROTOCOL=https
WEBHOOK_URL=https://your.domain.com/
N8N_EDITOR_BASE_URL=https://your.domain.com/
N8N_ENCRYPTION_KEY=PASTE_HEX_KEY_HERE
N8N_SECURE_COOKIE=true

# Database (PostgreSQL)
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=db
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=n8n
DB_POSTGRESDB_PASSWORD=ChangeThisStrongPassword!
EOF

Write the Docker Compose file

Define Postgres and n8n services with persistent storage. The :Z suffix on volumes makes them SELinux-friendly on RHEL 9.

cat > docker-compose.yml <<'YML'
version: "3.8"

services:
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=${DB_POSTGRESDB_USER}
      - POSTGRES_PASSWORD=${DB_POSTGRESDB_PASSWORD}
      - POSTGRES_DB=${DB_POSTGRESDB_DATABASE}
    volumes:
      - ./data/postgres:/var/lib/postgresql/data:Z
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${DB_POSTGRESDB_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5

  n8n:
    image: n8nio/n8n:latest
    user: "1000:1000"
    env_file:
      - ./.env
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "${N8N_PORT}:5678"
    volumes:
      - ./data/n8n:/home/node/.n8n:Z
    restart: unless-stopped
YML

Launch n8n and verify

Start the stack and confirm the application is reachable. The first web visit will prompt you to create the owner account.

docker compose up -d
docker compose ps
docker compose logs -f --tail=50 n8n

Optional health check:

curl -i http://127.0.0.1:5678/healthz

Example output:

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 2

ok

Make n8n run on boot (systemd)

Create a systemd unit that encapsulates your Compose project. Replace USER with your username and adjust paths if needed.

sudo tee /etc/systemd/system/n8n.service >/dev/null <<'UNIT'
[Unit]
Description=n8n workflow automation (Docker Compose)
Requires=docker.service
After=docker.service network-online.target
Wants=network-online.target

[Service]
Type=oneshot
WorkingDirectory=/home/USER/n8n
Environment="COMPOSE_FILE=docker-compose.yml"
RemainAfterExit=yes
ExecStart=/usr/bin/docker compose up -d
ExecStop=/usr/bin/docker compose down

[Install]
WantedBy=multi-user.target
UNIT

sudo systemctl daemon-reload
sudo systemctl enable --now n8n
systemctl status n8n --no-pager

Optional: HTTPS reverse proxy with NGINX

Terminate TLS on the host with NGINX and Let’s Encrypt. This keeps n8n behind localhost while users access a secure domain.

sudo dnf -y install epel-release
sudo dnf -y install nginx certbot python3-certbot-nginx
sudo tee /etc/nginx/conf.d/n8n.conf >/dev/null <<'NGINX'
server {
  listen 80;
  server_name your.domain.com;

  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;
    client_max_body_size 50m;
    proxy_read_timeout 3600;
  }
}
NGINX
sudo systemctl enable --now nginx
sudo certbot --nginx -d your.domain.com -m [email protected] --agree-tos --redirect -n

Ensure your .env uses HTTPS and the domain for N8N_HOST, N8N_PROTOCOL, N8N_EDITOR_BASE_URL, and WEBHOOK_URL, then recreate n8n if changed.

docker compose up -d

Upgrade and backup

Pull new images and recreate containers with zero data loss. Back up both the n8n config directory and the Postgres database regularly.

cd ~/n8n
docker compose pull
docker compose up -d
docker image prune -f

Database backup (replace the container name if different):

docker ps --format '{{.Names}}'
docker exec -t n8n-db-1 pg_dump -U n8n n8n > ~/n8n/backup-$(date +%F).sql
tar -C ~/n8n -czf ~/n8n/files-$(date +%F).tar.gz data/n8n

Troubleshooting SELinux and permissions

If volumes fail due to SELinux, the :Z flag usually fixes it. For manual labeling, apply a persistent context and restore:

sudo dnf -y install policycoreutils-python-utils
sudo semanage fcontext -a -t container_file_t '~/n8n(/.*)?'
sudo restorecon -Rv ~/n8n

If n8n cannot write to its directory, ensure ownership is 1000:1000:

sudo chown -R 1000:1000 ~/n8n/data/n8n

Installation complete. You now have a production-friendly n8n on RHEL 9 with Docker, PostgreSQL, SELinux-safe volumes, and optional HTTPS. For more study, guidance, server purchases, and support, you can use dropvps. For more guides, visit dropvps.com

Linux VPS

Follow DropVPS on Google

Add DropVPS as a preferred source to see our latest VPS guides and tutorials surfaced first in Google Search and AI Overviews.

🐧Linux VPS

Need a Linux Server for This?

Run Debian, Ubuntu, or any Linux distro on DropVPS — fast NVMe SSD, full root access, and 24/7 support. Perfect for everything you just read.

  • Full Root Access
  • Debian & Ubuntu Ready
  • 99.99% Uptime
  • 24/7 Support
Get Linux VPS →

No commitment · Cancel anytime

U
Loading...

Related Posts