🚀 Complete Setup Guide: n8n + Odoo + PostgreSQL with SSL

📋 System Information

Item Value
Cloud Provider AWS Lightsail
Operating System Amazon Linux 2
Public IP Address 47.130.204.245
Domain phytolink-venture.com (Namecheap)
n8n URL https://n8n.phytolink-venture.com
Odoo URL https://odoo.phytolink-venture.com
Email liewxen@gmail.com

🔑 Access Credentials

Service Username Password Notes
n8n admin admin123 Basic Auth login
PostgreSQL (superuser) postgres your_strong_password_here Database admin
PostgreSQL (odoo user) odoo odoo_password123 Odoo database user
Odoo (first setup) Set during setup Set during setup Create during initial access
⚠️ Security Warning: Change all default passwords before using in production! The passwords shown here are examples used during setup.

📑 Table of Contents

1Install Docker

First, install Docker on your Amazon Linux 2 instance:

# Update system packages
sudo yum update -y

# Install Docker
sudo yum install docker -y

# Start Docker service
sudo systemctl start docker
sudo systemctl enable docker

# Add user to docker group (no sudo needed)
sudo usermod -a -G docker $USER
newgrp docker

# Verify installation
docker --version

2Install Docker Compose

# Download Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# Make it executable
sudo chmod +x /usr/local/bin/docker-compose

# Verify installation
docker-compose --version

3Create Project Structure

# Create main directory
mkdir ~/n8n-odoo-setup
cd ~/n8n-odoo-setup

# Create nginx directories
mkdir -p nginx/conf.d
mkdir -p nginx/ssl

4Configure Docker Compose

Create the main docker-compose.yml file:

nano ~/n8n-odoo-setup/docker-compose.yml

Paste this configuration:

services:
  postgres:
    image: postgres:latest
    container_name: postgres
    restart: unless-stopped
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres_password123
      POSTGRES_DB: postgres
    volumes:
      - postgres_data:/var/lib/postgresql
    ports:
      - "5432:5432"
    networks:
      - app-network
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  n8n:
    image: n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=postgres
      - DB_POSTGRESDB_PASSWORD=postgres_password123
      - N8N_BASIC_AUTH_ACTIVE=true
      - N8N_BASIC_AUTH_USER=admin
      - N8N_BASIC_AUTH_PASSWORD=admin123
      - WEBHOOK_URL=https://n8n.phytolink-venture.com/
      - N8N_HOST=n8n.phytolink-venture.com
      - N8N_PROTOCOL=https
    volumes:
      - n8n_data:/home/node/.n8n
    networks:
      - app-network
    depends_on:
      postgres:
        condition: service_healthy

  odoo:
    image: odoo:latest
    container_name: odoo
    restart: unless-stopped
    environment:
      - HOST=postgres
      - USER=odoo
      - PASSWORD=odoo_password123
      - DB_PORT=5432
    volumes:
      - odoo_data:/var/lib/odoo
      - odoo_addons:/mnt/extra-addons
    networks:
      - app-network
    depends_on:
      postgres:
        condition: service_healthy

  nginx:
    image: nginx:alpine
    container_name: nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/conf.d:/etc/nginx/conf.d
      - ./nginx/ssl:/etc/nginx/ssl
      - certbot_www:/var/www/certbot
      - certbot_conf:/etc/letsencrypt
    networks:
      - app-network
    depends_on:
      - n8n
      - odoo

  certbot:
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot_www:/var/www/certbot
      - certbot_conf:/etc/letsencrypt
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

volumes:
  postgres_data:
  n8n_data:
  odoo_data:
  odoo_addons:
  certbot_www:
  certbot_conf:

networks:
  app-network:
    driver: bridge

Save the file: Ctrl+X, then Y, then Enter

5Initialize Databases

Start PostgreSQL and create the required database and user (Odoo will create its own database via the web UI):

# Start PostgreSQL first
docker-compose up -d postgres

# Wait for PostgreSQL to be ready (10 seconds)
sleep 10

# Create n8n database
docker exec -it postgres psql -U postgres -c "CREATE DATABASE n8n;"

# Create odoo user with password and allow database creation
docker exec -it postgres psql -U postgres -c "CREATE USER odoo WITH PASSWORD 'odoo_password123';"
docker exec -it postgres psql -U postgres -c "ALTER USER odoo CREATEDB;"
✅ Database Structure:

6Configure Initial Nginx (HTTP Only)

Create the initial nginx configuration for obtaining SSL certificates:

nano ~/n8n-odoo-setup/nginx/conf.d/default.conf

Paste this configuration:

server {
    listen 80;
    server_name n8n.phytolink-venture.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        proxy_pass http://n8n:5678;
        proxy_set_header Host $host;
    }
}

server {
    listen 80;
    server_name odoo.phytolink-venture.com;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        proxy_pass http://odoo:8069;
        proxy_set_header Host $host;
    }
}

Start All Services

cd ~/n8n-odoo-setup
docker-compose up -d
docker-compose ps

All containers should show "Up" status.

7Setup DNS Records at Namecheap

  1. Login to Namecheap
  2. Go to Domain List → Click Manage next to phytolink-venture.com
  3. Click on Advanced DNS tab
  4. Under Host Records, click Add New Record
  5. Add these two A Records:
Type Host Value TTL
A Record n8n 47.130.204.245 Automatic
A Record odoo 47.130.204.245 Automatic

Click Save All Changes and wait 5-15 minutes for DNS propagation.

Verify DNS Propagation

# From your server
nslookup n8n.phytolink-venture.com
nslookup odoo.phytolink-venture.com

# Both should return: 47.130.204.245

8Configure Lightsail Firewall

  1. Go to AWS Lightsail Console
  2. Click on your instance
  3. Go to Networking tab
  4. Scroll down to IPv4 Firewall
  5. Ensure you have these rules (click + Add rule if missing):
Application Protocol Port Purpose
SSH TCP 22 Server access
HTTP TCP 80 SSL certificate verification
HTTPS TCP 443 Secure web access
PostgreSQL (Optional) TCP 5432 Database access (if using pgAdmin)
🔒 Security Note: Only open port 5432 if you need external database access. For better security, use SSH tunneling instead of exposing PostgreSQL directly.

9Obtain SSL Certificates

Get free SSL certificates from Let's Encrypt using standalone mode:

Step 1: Stop Nginx temporarily

docker-compose stop nginx

Step 2: Get certificate for n8n

docker run --rm -it \
  -v n8n-odoo-setup_certbot_conf:/etc/letsencrypt \
  -v n8n-odoo-setup_certbot_www:/var/www/certbot \
  -p 80:80 \
  certbot/certbot certonly --standalone \
  --email liewxen@gmail.com \
  --agree-tos \
  --no-eff-email \
  -d n8n.phytolink-venture.com

Step 3: Get certificate for Odoo

docker run --rm -it \
  -v n8n-odoo-setup_certbot_conf:/etc/letsencrypt \
  -v n8n-odoo-setup_certbot_www:/var/www/certbot \
  -p 80:80 \
  certbot/certbot certonly --standalone \
  --email liewxen@gmail.com \
  --agree-tos \
  --no-eff-email \
  -d odoo.phytolink-venture.com

You should see: "Successfully received certificate" for both domains.

Step 4: Verify certificates

docker run --rm \
  -v n8n-odoo-setup_certbot_conf:/etc/letsencrypt \
  certbot/certbot certificates

10Configure SSL in Nginx

Update nginx configuration to use SSL certificates:

nano ~/n8n-odoo-setup/nginx/conf.d/default.conf

Replace entire content with this complete SSL configuration:

# n8n - HTTP to HTTPS redirect
server {
    listen 80;
    server_name n8n.phytolink-venture.com;
    
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
    
    location / {
        return 301 https://$host$request_uri;
    }
}

# n8n - HTTPS
server {
    listen 443 ssl http2;
    server_name n8n.phytolink-venture.com;

    ssl_certificate /etc/letsencrypt/live/n8n.phytolink-venture.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/n8n.phytolink-venture.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    client_max_body_size 50M;

    location / {
        proxy_pass http://n8n: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;
        
        # WebSocket support for n8n
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

# Odoo - HTTP to HTTPS redirect
server {
    listen 80;
    server_name odoo.phytolink-venture.com;
    
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }
    
    location / {
        return 301 https://$host$request_uri;
    }
}

# Odoo - HTTPS
server {
    listen 443 ssl http2;
    server_name odoo.phytolink-venture.com;

    ssl_certificate /etc/letsencrypt/live/odoo.phytolink-venture.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/odoo.phytolink-venture.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    client_max_body_size 50M;

    location / {
        proxy_pass http://odoo:8069;
        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_redirect off;
    }

    # Odoo longpolling for live updates
    location /longpolling {
        proxy_pass http://odoo:8072;
        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;
    }
}

Save the file: Ctrl+X, Y, Enter

Restart Nginx and verify

# Start nginx
docker-compose start nginx

# Test configuration
docker exec nginx nginx -t

# Check logs
docker logs nginx --tail 20

# Verify all containers are running
docker-compose ps

11Access Your Applications

🎉 Setup Complete! Your applications are now live:

Application URL Username Password
n8n https://n8n.phytolink-venture.com admin admin123
Odoo https://odoo.phytolink-venture.com Create during first access

First Time Odoo Setup

  1. Visit: https://odoo.phytolink-venture.com
  2. Fill in the database creation form:
    • Master Password: Create a strong master password
    • Database Name: Choose a name (e.g., "production")
    • Email: Your email address
    • Password: Your Odoo admin password
    • Phone: Optional
    • Language: Select your language
    • Country: Select your country
    • Demo Data: Uncheck (unless you want sample data)
  3. Click Create database
  4. Wait for Odoo to initialize (1-2 minutes)
  5. You'll be logged in automatically

12Install OCA Contract Addons (optional)

To add the OCA Contract addons to Odoo, clone them into the /mnt/extra-addons volume, then update the Apps list and install from Odoo.

Create the extra-addons directory

This creates the directory inside the named Docker volume that Odoo mounts at /mnt/extra-addons.

# Create directory inside the named volume (project: n8n-odoo-setup)
docker run --rm \
  -v n8n-odoo-setup_odoo_addons:/mnt/extra-addons \
  alpine sh -c "mkdir -p /mnt/extra-addons && ls -la /mnt/extra-addons"

Clone addons into the extra-addons volume

# Choose the branch matching your Odoo major version (e.g., 19.0)
BRANCH=19.0

# Clone OCA/contract into the named volume that is mounted at /mnt/extra-addons
docker run --rm \
  -v n8n-odoo-setup_odoo_addons:/mnt/extra-addons \
  alpine/git clone --depth=1 -b "$BRANCH" https://github.com/OCA/contract.git /mnt/extra-addons/oca-contract

# (Re)start Odoo to pick up new addons
docker-compose restart odoo

# Verify Odoo sees /mnt/extra-addons now
docker-compose logs --tail=200 odoo
Note: Use a branch that matches your Odoo version. For example, set BRANCH=19.0 for Odoo 19. If a matching branch is not yet available, the addons may be incompatible.

Install from the Odoo UI

  1. Open Odoo → Apps.
  2. Enable Developer Mode (Settings → Activate Developer Mode).
  3. Click Update Apps List and then Update.
  4. Search for Contract (publisher: OCA) and install desired modules (e.g., contract, product_contract).

🔧 Troubleshooting

Issue: "Site can't be reached" or ERR_QUIC_PROTOCOL_ERROR

Solution 1: Disable QUIC in Chrome

  1. Go to chrome://flags
  2. Search for "QUIC"
  3. Set to "Disabled"
  4. Restart Chrome

Solution 2: Try a different browser (Firefox, Edge, Safari)

Issue: PostgreSQL connection failed in pgAdmin

Solution: Use SSH tunnel instead of exposing port 5432

# On Windows PowerShell
ssh -i "path\to\your-key.pem" -L 5432:localhost:5432 ec2-user@47.130.204.245 -N

# Then connect pgAdmin to localhost:5432

Issue: Odoo shows "Access Denied" during database creation

# Grant CREATEDB permission
docker exec -it postgres psql -U postgres -c "ALTER USER odoo CREATEDB;"
docker-compose restart odoo

Issue: SSL certificate errors

# Verify certificates exist
docker exec nginx ls -la /etc/letsencrypt/live/n8n.phytolink-venture.com/
docker exec nginx ls -la /etc/letsencrypt/live/odoo.phytolink-venture.com/

# Check nginx config
docker exec nginx nginx -t

# Restart nginx
docker-compose restart nginx

Issue: Container keeps restarting

# Check logs for the problematic container
docker logs n8n
docker logs odoo
docker logs postgres
docker logs nginx

# Check all container status
docker-compose ps

🛠️ Maintenance Commands

View Container Status

cd ~/n8n-odoo-setup
docker-compose ps

View Logs

# All services
docker-compose logs -f

# Specific service
docker logs n8n
docker logs odoo
docker logs nginx
docker logs postgres

# Last 50 lines
docker logs nginx --tail 50

Restart Services

# Restart all services
docker-compose restart

# Restart specific service
docker-compose restart nginx
docker-compose restart n8n
docker-compose restart odoo

Stop and Start Services

# Stop all services
docker-compose down

# Start all services
docker-compose up -d

# Stop specific service
docker-compose stop odoo

# Start specific service
docker-compose start odoo

Access PostgreSQL Database

# Access PostgreSQL CLI
docker exec -it postgres psql -U postgres

# List databases
docker exec -it postgres psql -U postgres -c "\l"

# Connect to specific database
docker exec -it postgres psql -U postgres -d n8n

# Exit PostgreSQL CLI
\q

Backup Databases

# Backup n8n database
docker exec postgres pg_dump -U postgres n8n > n8n_backup.sql

# Backup odoo database
docker exec postgres pg_dump -U odoo odoo > odoo_backup.sql

# Backup all databases
docker exec postgres pg_dumpall -U postgres > all_databases_backup.sql

Restore Databases

# Restore n8n database
cat n8n_backup.sql | docker exec -i postgres psql -U postgres n8n

# Restore odoo database
cat odoo_backup.sql | docker exec -i postgres psql -U odoo odoo

Update Docker Images

# Pull latest images
docker-compose pull

# Restart with new images
docker-compose up -d

Check SSL Certificate Expiration

# View certificate details
docker exec certbot certbot certificates

# Manually renew certificates (usually automatic)
docker-compose run --rm certbot renew

View Disk Usage

# Check Docker disk usage
docker system df

# Check volume sizes
docker volume ls
docker system df -v

Clean Up Docker System

# Remove unused images, containers, networks
docker system prune

# Remove unused volumes (WARNING: This deletes data!)
docker system prune --volumes

# Remove specific volume
docker volume rm volume_name

📊 System Architecture

Internet
   │
   ├─── Port 80 (HTTP) ──→ Nginx ──→ Redirect to HTTPS
   │
   └─── Port 443 (HTTPS) ──→ Nginx (SSL Termination)
            │
            ├──→ n8n.phytolink-venture.com ──→ n8n:5678
            │
            └──→ odoo.phytolink-venture.com ──→ odoo:8069
                                                    │
                                                    └──→ PostgreSQL:5432
                                                          │
                                                          ├─ Database: n8n
                                                          └─ Database: odoo

🔐 Security Best Practices

📝 Important Files and Locations

Item Location
Project Directory /home/ec2-user/n8n-odoo-setup
Docker Compose Config ~/n8n-odoo-setup/docker-compose.yml
Nginx Config ~/n8n-odoo-setup/nginx/conf.d/default.conf
SSL Certificates Docker volume: certbot_conf
PostgreSQL Data Docker volume: postgres_data
n8n Data Docker volume: n8n_data
Odoo Data Docker volume: odoo_data

🔗 Useful Links

📞 Support and Resources

Getting Help

✨ Setup Summary

You now have a fully functional, secure infrastructure with:

Total setup time: ~30-45 minutes

Monthly cost: AWS Lightsail instance cost only (typically $5-$20/month depending on instance size)


Documentation created: October 27, 2025
Last updated: October 27, 2025
Version: 1.0

✅ Copied to clipboard!