Skip to main content

Deploy Odoo ERP

Deploy a production-ready Odoo ERP instance on Octos Cloud. Odoo is a suite of open-source business apps that cover all your company needs: CRM, eCommerce, accounting, inventory, point of sale, project management, etc.

Architecture

User → DNS (odoo.yourdomain.com)
→ Octos Cloud Public IP
→ Nginx / Traefik
→ Odoo App Container
→ PostgreSQL Database

Step 1: Provision infrastructure

  1. Navigate to Create Instance in your project
  2. Select Ubuntu 22.04 LTS
  3. Choose a plan: gp.large (4 vCPU, 8 GB RAM, 160 GB NVMe) is recommended for production Odoo.
  4. Create a Virtual Network, Subnet, and Virtual Router.
  5. Attach a Floating IP to your Instance.
  6. Configure your Security Group to allow SSH.
  7. Deploy

Step 2: Install Docker and Docker Compose

SSH into your Instance and install Docker:

curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER

Step 3: Create Odoo configuration

Create a directory for your Odoo deployment:

mkdir -p /opt/odoo && cd /opt/odoo

Create a docker-compose.yml file:

version: '3.8'

services:
# PostgreSQL Database for Odoo
db:
image: postgres:16
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- db-data:/var/lib/postgresql/data
networks:
- odoo-internal
deploy:
replicas: 1
placement:
constraints:
- node.role == worker
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
resources:
limits:
cpus: '1'
memory: 1G
reservations:
cpus: '0.25'
memory: 256M

# Odoo Application
web:
image: odoo:18
depends_on:
- db
environment:
HOST: db
USER: ${POSTGRES_USER}
PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- web-data:/var/lib/odoo
- addons:/mnt/extra-addons
networks:
- odoo-internal
- traefik-public
deploy:
replicas: 1
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
labels:
- "traefik.enable=true"
- "traefik.http.routers.${STACK_NAME}-web.rule=Host(`${APP_DOMAIN}`)"
- "traefik.http.routers.${STACK_NAME}-web.entrypoints=websecure"
- "traefik.http.routers.${STACK_NAME}-web.tls.certresolver=letsencrypt"
- "traefik.http.services.${STACK_NAME}-web.loadbalancer.server.port=8069"
- "traefik.docker.network=traefik-public"

networks:
odoo-internal:
driver: overlay
name: ${STACK_NAME}-internal
attachable: false
traefik-public:
external: true

volumes:
db-data:
name: ${STACK_NAME}-db-data
web-data:
name: ${STACK_NAME}-web-data

Best Practices

  1. Database Isolation: PostgreSQL is only accessible on the odoo-internal overlay network. Traefik cannot access the database directly, reducing the attack surface.
  2. Parameterized Deployments: By using environment variables (${STACK_NAME}, ${APP_DOMAIN}, etc.), you can deploy multiple instances of Odoo (e.g., prod and staging) without network or volume collisions.
  3. Resource Controls: Odoo and PostgreSQL are given clear CPU and memory reservations and limits. This ensures predictable performance and prevents a runaway process from crashing the entire host.

Step 4: Start Odoo

Run the following command to start Odoo in the background:

docker compose up -d

Your Odoo instance is now running. You can access it via your configured domain.

Step 5: Configure Reverse Proxy & SSL

To use Odoo in production, set up a reverse proxy like Nginx or Traefik and configure an SSL certificate using Let's Encrypt. Point your domain (e.g., odoo.<yourdomain>.com) to the Instance's Floating IP address.

Production checklist

  • Security group restricts SSH to known IPs
  • Database is not exposed to the public internet
  • SSL certificate installed and auto-renewing
  • Automated snapshots configured for the Instance
  • Strong master password set in Odoo configuration

Next steps