Self-Host n8n on Oracle Cloud Free Tier

The following commands are used in the YouTube tutorial (https://www.youtube.com/watch?v=GQbEj455Cqk). You can copy and paste them in your terminal.

# SSH into your instance
chmod 400 /path/to/your/my_oracle_key.key # Set correct permissions for private key
ssh -i /path/to/your/my_oracle_key.key ubuntu@<your_instance_public_ip>

# Update and upgrade System Packages
sudo apt update -y
sudo apt upgrade -y

# Install Nginx
sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx

# Check status
systemctl status nginx

# Reset iptables policies
sudo iptables -P INPUT ACCEPT
sudo iptables -P OUTPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -F
sudo apt install iptables-persistent -y
sudo netfilter-persistent save

# Configure Ubuntu firewall (UFW)
sudo ufw allow 22/tcp # Allow SSH
sudo ufw allow 80/tcp # Allow HTTP
sudo ufw allow 443/tcp # Allow HTTPS
sudo ufw enable
sudo ufw status verbose # Verify rules are active

# Install Docker and Docker Compose plugin
sudo apt install ca-certificates curl gnupg lsb-release -y
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
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update -y
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
sudo systemctl start docker
sudo systemctl enable docker

# Add user (ubuntu) to the docker group
sudo usermod -aG docker ubuntu
newgrp docker # Apply group changes immediately for current session

# Create Nginx web root and test page
sudo mkdir -p /var/www/html
echo "Hello from Nginx! Testing HTTP Connectivity." | sudo tee /var/www/html/index.html
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html

# Create a new Nginx configuration file
sudo nano /etc/nginx/conf.d/n8n.conf

# Paste the following content in the file, save and exit
server {
    listen 443;
    listen [::]:443;
    server_name n8n.yourdomain.com; # Your free domain

    location /.well-known/acme-challenge/ {
        root /var/www/html; # Used by Certbot for verification
        allow all;
    }

    location / {
        root /var/www/html; # Temporarily serve static HTML
        index index.html index.htm;
        try_files $uri $uri/ =404;
    }
}

# Test Nginx configuration and reload
sudo nginx -t
sudo systemctl reload nginx

# Install Certbot and Nginx plugin
sudo apt install certbot python3-certbot-nginx -y

# Run Certbot
sudo certbot --nginx -d n8n.yourdomain.com # Your free domain

# Test Certbot automatic renewal
sudo certbot renew --dry-run

# Create a directory for n8n
mkdir ~/n8n
cd ~/n8n

# Generate a unique N8N_ENCRYPTION_KEY, and copy the generated key for later use
head /dev/urandom | tr -dc A-Za-z0-9_ | head -c 32 ; echo ''

# Create docker-compose.yml
nano docker-compose.yml

# Paste the following content in the file, save and exit
services:
  postgres:
    image: postgres:15
    restart: always
    environment:
      POSTGRES_DB: n8n
      POSTGRES_USER: n8nuser
      POSTGRES_PASSWORD: your_strong_database_password # CHANGE THIS!
    volumes:
      - ./pg_data:/var/lib/postgresql/data
    networks:
      - n8n_backend
    healthcheck: # Ensures n8n waits for DB to be ready
      test: ['CMD-SHELL', 'pg_isready -U n8nuser -d n8n']
      interval: 5s
      timeout: 5s
      retries: 5

  n8n:
    image: n8nio/n8n
    restart: always
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: 5432
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8nuser
      DB_POSTGRESDB_PASSWORD: your_strong_database_password # MUST MATCH ABOVE!
      N8N_HOST: n8n.yourdomain.com # CHANGE THIS to your free domain
      WEBHOOK_URL: https://n8n.yourdomain.com/ # CHANGE THIS to your free domain
      N8N_PROTOCOL: https
      GENERIC_TIMEZONE: America/Toronto # Adjust to your timezone
      N8N_ENCRYPTION_KEY: your_generated_32_char_key # PASTE THE GENERATED KEY HERE
    ports:
      - '127.0.0.1:5678:5678' # Only expose to localhost for Nginx proxy
    volumes:
      - ./n8n_data:/home/node/.n8n
    networks:
      - n8n_backend
    depends_on:
      postgres:
        condition: service_healthy # Wait for DB to be healthy

networks:
  n8n_backend:
    driver: bridge

# Set permissions for n8n data volume
mkdir n8n_data && sudo chown -R 1000:1000 n8n_data

# Start n8n and the Database
docker compose up -d

# Verify both n8n and postgres Docker containers (showing Up status)
docker ps

# Edit the Nginx configuration file again
sudo nano /etc/nginx/conf.d/n8n.conf

# In the file, replace the location block with the following content, save and exit
    location / {
        proxy_pass http://localhost:5678; # n8n Docker container is accessible on localhost:5678
        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_buffering off; # Important for long-running workflows
    }

# Test Nginx configuration and reload
sudo nginx -t
sudo systemctl reload nginx

# Open your browser and enter the URL https://n8n.yourdomain.com (replace with your free domain). You should now see the n8n setup webpage. Enjoy building n8n automation workflows!

Reference: reference

Leave a Reply

Your email address will not be published. Required fields are marked *