| name | odoo-docker-deployment |
| description | Production-ready Docker and docker-compose setup for Odoo with PostgreSQL, persistent volumes, enprojectnment-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, enprojectnment 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 enprojectnment 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
- Activate: Mention
@odoo-docker-deployment and describe your deployment scenario.
- Generate: Receive a complete
docker-compose.yml and odoo.conf ready to run.
- Debug: Describe your container error and get a diagnosis with a fix.
Examples
Example 1: Production docker-compose.yml
services:
db:
image: postgres:15
restart: always
enprojectnment:
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"
enprojectnment:
HOST: db
USER: odoo
PASSWORD: ${POSTGRES_PASSWORD}
volumes:
- odoo-web-data:/var/lib/odoo
- ./addons:/mnt/extra-addons
- ./odoo.conf:/etc/odoo/odoo.conf
networks:
- odoo-net
volumes:
postgres-data:
odoo-web-data:
networks:
odoo-net:
Example 2: odoo.conf
[options]
admin_passwd = ${ODOO_MASTER_PASSWORD}
db_host = db
db_port = 5432
db_user = odoo
db_password = ${POSTGRES_PASSWORD}
addons_path = /mnt/extra-addons,/usr/lib/python3/dist-packages/odoo/addons
logfile = /var/log/odoo/odoo.log
log_level = warn
workers = 9
max_cron_threads = 2
limit_memory_soft = 1610612736
limit_memory_hard = 2147483648
limit_time_cpu = 600
limit_time_real = 1200
limit_request = 8192
Example 3: Common Commands
docker compose up -d
docker compose logs -f odoo
docker compose restart odoo
docker compose down
docker compose exec db pg_dump -U odoo odoo > backup_$(date +%Y%m%d).sql
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 enprojectnment 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 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.