Menu
User

DropVPS Team

Writer: Cooper Reagan

How to install n8n on Ubuntu 25.10

How to install n8n on Ubuntu 25.10

Publication Date

10/11/2025

Category

Articles

Reading Time

5 Min

Table of Contents

n8n is a powerful open-source automation platform. Ubuntu 25.10 runs it reliably with Docker, PostgreSQL for persistence, and HTTPS via a reverse proxy. The steps below set up a production-ready instance with a custom domain, automatic SSL certificates, and auto-start on boot. Terminal access and a pointed DNS record are assumed.

Update Ubuntu 25.10

Apply the latest security patches and confirm the release version.

sudo apt update && sudo apt -y upgrade
. /etc/os-release && echo "$PRETTY_NAME"
Ubuntu 25.10 (Kinetic Kudu)

Set DNS and hostname

Point your domain’s A/AAAA record to the server IP, then set a matching hostname.

# Replace with your domain
export N8N_DOMAIN="n8n.example.com"

# Local hostname (optional but recommended)
sudo hostnamectl set-hostname "$N8N_DOMAIN"

# Check DNS from the server (should resolve to your public IP)
dig +short A "$N8N_DOMAIN"
dig +short AAAA "$N8N_DOMAIN"

Install Docker and Compose

Install Docker Engine and the Compose plugin from Docker’s official repository.

sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo $VERSION_CODENAME) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# Optional: run docker without sudo
sudo usermod -aG docker $USER
newgrp docker

docker --version
docker compose version

Create directories and secrets

Prepare persistent volumes and strong secrets for n8n and PostgreSQL.

sudo mkdir -p /opt/n8n/{data,postgres,caddy}
sudo chown -R $USER:$USER /opt/n8n
cd /opt/n8n

# Generate strong secrets
openssl rand -base64 48 | tr -d '\n' ; echo
openssl rand -base64 36 | tr -d '\n' ; echo

Create an .env file with production variables.

cat > /opt/n8n/.env <<'ENV'
# Domain and contact
N8N_HOST=n8n.example.com
N8N_PROTOCOL=https
N8N_PORT=5678
WEBHOOK_URL=https://n8n.example.com/

# Security and behavior
NODE_ENV=production
GENERIC_TIMEZONE=UTC
N8N_SECURE_COOKIE=true
N8N_DIAGNOSTICS_ENABLED=false
N8N_ENCRYPTION_KEY=REPLACE_WITH_32_64_CHAR_SECRET
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=REPLACE_WITH_STRONG_PASSWORD

# Database (PostgreSQL)
DB_TYPE=postgresdb
POSTGRES_USER=n8n
POSTGRES_PASSWORD=REPLACE_WITH_STRONG_DB_PASSWORD
POSTGRES_DB=n8n
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=${POSTGRES_DB}
DB_POSTGRESDB_USER=${POSTGRES_USER}
DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
ENV

Create docker-compose.yml

Define containers for PostgreSQL, n8n, and Caddy (automatic HTTPS).

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

services:
  postgres:
    image: postgres:16
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    volumes:
      - ./postgres:/var/lib/postgresql/data
    networks: [n8n]
    restart: unless-stopped

  n8n:
    image: n8nio/n8n:latest
    depends_on: [postgres]
    environment:
      - DB_TYPE=${DB_TYPE}
      - DB_POSTGRESDB_HOST=${DB_POSTGRESDB_HOST}
      - DB_POSTGRESDB_PORT=${DB_POSTGRESDB_PORT}
      - DB_POSTGRESDB_DATABASE=${DB_POSTGRESDB_DATABASE}
      - DB_POSTGRESDB_USER=${DB_POSTGRESDB_USER}
      - DB_POSTGRESDB_PASSWORD=${DB_POSTGRESDB_PASSWORD}
      - N8N_HOST=${N8N_HOST}
      - N8N_PROTOCOL=${N8N_PROTOCOL}
      - N8N_PORT=${N8N_PORT}
      - WEBHOOK_URL=${WEBHOOK_URL}
      - NODE_ENV=${NODE_ENV}
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE}
      - N8N_SECURE_COOKIE=${N8N_SECURE_COOKIE}
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY}
      - N8N_DIAGNOSTICS_ENABLED=${N8N_DIAGNOSTICS_ENABLED}
      - N8N_BASIC_AUTH_ACTIVE=${N8N_BASIC_AUTH_ACTIVE}
      - N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
      - N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
    volumes:
      - ./data:/home/node/.n8n
    networks: [n8n]
    restart: unless-stopped

  caddy:
    image: caddy:2-alpine
    depends_on: [n8n]
    ports:
      - "80:80"
      - "443:443"
    environment:
      - ACME_AGREE=true
      - [email protected]
    volumes:
      - ./caddy/Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config
    networks: [n8n]
    restart: unless-stopped

networks:
  n8n:
    driver: bridge

volumes:
  caddy_data:
  caddy_config:
YML

Create Caddyfile for HTTPS

Tell Caddy to request a certificate and proxy traffic to n8n.

mkdir -p /opt/n8n/caddy
cat > /opt/n8n/caddy/Caddyfile <<CF
{
  email [email protected]
}

n8n.example.com {
  encode zstd gzip
  tls {
    protocols tls1.2 tls1.3
  }
  reverse_proxy n8n:5678
}
CF

Launch containers

Pull the images, start the stack, and watch logs for healthy status.

cd /opt/n8n
docker compose pull
docker compose up -d
docker compose ps
docker compose logs -f --tail=100 n8n
✔ n8n  Started
Editor is now accessible via:
https://n8n.example.com/

Allow firewall ports

Open HTTP/HTTPS while keeping SSH access.

sudo ufw allow OpenSSH
sudo ufw allow 80,443/tcp
sudo ufw --force enable
sudo ufw status

Enable auto-start with systemd

Create a unit so the stack starts on boot and can be managed like a service.

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

[Service]
Type=oneshot
WorkingDirectory=/opt/n8n
RemainAfterExit=true
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-stack
systemctl status n8n-stack --no-pager

Update and backup

Upgrade n8n safely and back up the database regularly.

# Update images and restart
cd /opt/n8n
docker compose pull
docker compose up -d
docker image prune -f
# Backup Postgres (creates SQL dump with date stamp)
set -a; . /opt/n8n/.env; set +a
docker compose exec -T postgres pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > "/opt/n8n/postgres/backup-$(date +%F).sql"

Optional: Native Node.js install

For lab use without Docker, install Node.js LTS and run n8n locally (SQLite, no reverse proxy).

sudo apt update
sudo apt install -y curl
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt install -y nodejs build-essential
sudo npm i -g n8n

# Run n8n on port 5678
export N8N_ENCRYPTION_KEY="$(openssl rand -base64 48)"
export N8N_BASIC_AUTH_ACTIVE=true
export N8N_BASIC_AUTH_USER=admin
export N8N_BASIC_AUTH_PASSWORD='REPLACE_ME'
n8n start

Installation complete. n8n now runs securely on Ubuntu 25.10 with Docker, PostgreSQL, and automatic HTTPS. For more study and guidance, and to buy servers with support, you can use dropvps.

Linux VPS
U
Loading...

Related Posts