140 lines
4.8 KiB
Markdown
140 lines
4.8 KiB
Markdown
---
|
||
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.
|