--- name: odoo-docker-deployment description: "Production-ready Docker and docker-compose setup for Odoo with PostgreSQL, persistent volumes, environment-based configuration, and Nginx reverse proxy." risk: safe source: "self" --- # Odoo Docker Deployment ## Overview This skill provides a complete, production-ready Docker setup for Odoo, including PostgreSQL, persistent file storage, environment variable configuration, and an optional Nginx reverse proxy with SSL. It covers both development and production configurations. ## When to Use This Skill - Spinning up a local Odoo development environment with Docker. - Deploying Odoo to a VPS or cloud server (AWS, DigitalOcean, etc.). - Troubleshooting Odoo container startup failures or database connection errors. - Adding a reverse proxy with SSL to an existing Odoo Docker setup. ## How It Works 1. **Activate**: Mention `@odoo-docker-deployment` and describe your deployment scenario. 2. **Generate**: Receive a complete `docker-compose.yml` and `odoo.conf` ready to run. 3. **Debug**: Describe your container error and get a diagnosis with a fix. ## Examples ### Example 1: Production docker-compose.yml ```yaml # Note: The top-level 'version' key is deprecated in Docker Compose v2+ # and can be safely omitted. Remove it to avoid warnings. services: db: image: postgres:15 restart: always environment: POSTGRES_DB: odoo POSTGRES_USER: odoo POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} volumes: - postgres-data:/var/lib/postgresql/data networks: - odoo-net odoo: image: odoo:17.0 restart: always depends_on: db: condition: service_healthy ports: - "8069:8069" - "8072:8072" # Longpolling for live chat / bus environment: HOST: db USER: odoo PASSWORD: ${POSTGRES_PASSWORD} volumes: - odoo-web-data:/var/lib/odoo - ./addons:/mnt/extra-addons # Custom modules - ./odoo.conf:/etc/odoo/odoo.conf networks: - odoo-net volumes: postgres-data: odoo-web-data: networks: odoo-net: ``` ### Example 2: odoo.conf ```ini [options] admin_passwd = ${ODOO_MASTER_PASSWORD} ; set via env or .env file db_host = db db_port = 5432 db_user = odoo db_password = ${POSTGRES_PASSWORD} ; set via env or .env file ; addons_path inside the official Odoo Docker image (Debian-based) addons_path = /mnt/extra-addons,/usr/lib/python3/dist-packages/odoo/addons logfile = /var/log/odoo/odoo.log log_level = warn ; Worker tuning for a 4-core / 8GB server: workers = 9 ; (CPU cores × 2) + 1 max_cron_threads = 2 limit_memory_soft = 1610612736 ; 1.5 GB — soft kill threshold limit_memory_hard = 2147483648 ; 2.0 GB — hard kill threshold limit_time_cpu = 600 limit_time_real = 1200 limit_request = 8192 ``` ### Example 3: Common Commands ```bash # Start all services in background docker compose up -d # Stream Odoo logs in real time docker compose logs -f odoo # Restart Odoo only (not DB — avoids data risk) docker compose restart odoo # Stop all services docker compose down # Backup the database to a local SQL dump docker compose exec db pg_dump -U odoo odoo > backup_$(date +%Y%m%d).sql # Update a custom module without restarting the server docker compose exec odoo odoo -d odoo --update my_module --stop-after-init ``` ## Best Practices - ✅ **Do:** Store all secrets in a `.env` file and reference them with `${VAR}` — never hardcode passwords in `docker-compose.yml`. - ✅ **Do:** Use `depends_on: condition: service_healthy` with a PostgreSQL healthcheck to prevent Odoo starting before the DB is ready. - ✅ **Do:** Put Nginx in front of Odoo for SSL termination (Let's Encrypt / Certbot) — never expose Odoo directly on port 80/443. - ✅ **Do:** Set `workers = (CPU cores × 2) + 1` in `odoo.conf` — `workers = 0` uses single-threaded mode and blocks all users. - ❌ **Don't:** Expose port 5432 (PostgreSQL) to the public internet — keep it on the internal Docker network only. - ❌ **Don't:** Use the `latest` or `17` Docker image tags in production — always pin to a specific patch-level tag (e.g., `odoo:17.0`). - ❌ **Don't:** Mount `odoo.conf` and rely on it for secrets in CI/CD — use Docker secrets or environment variables instead. ## Limitations - This skill covers **self-hosted Docker deployments** — Odoo.sh (cloud-managed hosting) has a completely different deployment model. - **Horizontal scaling** (multiple Odoo containers behind a load balancer) requires shared filestore (NFS or S3-compatible storage) not covered here. - Does not include an Nginx configuration template — consult the [official Odoo Nginx docs](https://www.odoo.com/documentation/17.0/administration/install/deploy.html) for the full reverse proxy config. - The `addons_path` inside the Docker image may change with new base image versions — always verify after upgrading the Odoo image.