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
- Navigate to Create Instance in your project
- Select Ubuntu 22.04 LTS
- Choose a plan:
gp.large(4 vCPU, 8 GB RAM, 160 GB NVMe) is recommended for production Odoo. - Create a Virtual Network, Subnet, and Virtual Router.
- Attach a Floating IP to your Instance.
- Configure your Security Group to allow SSH.
- 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
- Database Isolation: PostgreSQL is only accessible on the
odoo-internaloverlay network. Traefik cannot access the database directly, reducing the attack surface. - 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. - 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