Why Docker CI/CD for Odoo?
Manual Odoo deployments (SSH, git pull, restart) are error-prone and cause downtime. A Docker-based CI/CD pipeline provides: reproducible builds, automated testing, zero-downtime deployments, instant rollback, and consistent environments across dev/staging/production.
Architecture
Developer → Git Push → CI/CD Pipeline
→ Build Docker Image (Odoo + custom addons)
→ Push to Registry (Docker Hub / ECR / GHCR)
→ Deploy to Server (docker compose pull && up)
→ Health Check → Route Traffic
→ (If fail → Rollback to previous image)Custom Odoo Dockerfile
# Dockerfile
FROM odoo:19
# Copy custom addons
COPY ./custom-addons /mnt/extra-addons
# Install Python dependencies for custom modules
COPY requirements.txt /tmp/requirements.txt
RUN pip3 install --no-cache-dir -r /tmp/requirements.txt
# Copy custom odoo.conf
COPY config/odoo.conf /etc/odoo/odoo.conf
# Set permissions
RUN chown -R odoo:odoo /mnt/extra-addonsBuild and Push
# Build the image
docker build -t mycompany/odoo:19-$(git rev-parse --short HEAD) .
docker tag mycompany/odoo:19-$(git rev-parse --short HEAD) mycompany/odoo:latest
# Push to Docker Hub
docker push mycompany/odoo:19-$(git rev-parse --short HEAD)
docker push mycompany/odoo:latest
# Or push to GitHub Container Registry
docker tag mycompany/odoo:latest ghcr.io/mycompany/odoo:latest
docker push ghcr.io/mycompany/odoo:latestGitHub Actions CI/CD
# .github/workflows/deploy.yml
name: Deploy Odoo
on:
push:
branches: [main]
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: |
docker build -t ghcr.io/${{ github.repository }}/odoo:${{ github.sha }} .
docker tag ghcr.io/${{ github.repository }}/odoo:${{ github.sha }} \
ghcr.io/${{ github.repository }}/odoo:latest
- name: Push to GHCR
run: |
echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
docker push ghcr.io/${{ github.repository }}/odoo:${{ github.sha }}
docker push ghcr.io/${{ github.repository }}/odoo:latest
- name: Deploy to server
uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.SERVER_HOST }}
username: deploy
key: ${{ secrets.SSH_KEY }}
script: |
cd /opt/odoo
docker compose pull odoo
docker compose up -d odoo
sleep 10
curl -f http://localhost:8069/web/health || (docker compose rollback && exit 1)Zero-Downtime Deployment
# Strategy 1: Rolling update with health check
# docker-compose.yml:
services:
odoo:
image: ghcr.io/mycompany/odoo:latest
deploy:
update_config:
parallelism: 1
delay: 30s
order: start-first # Start new before stopping old
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8069/web/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
# Strategy 2: Blue-green with nginx
# Run two containers (blue on 8069, green on 8070)
# Switch nginx upstream after health check passes
# Rollback: switch back to previous containerRollback
# Quick rollback to previous version:
docker compose down odoo
# Set previous image tag:
# In docker-compose.yml or .env:
# ODOO_IMAGE=ghcr.io/mycompany/odoo:previous-sha
docker compose up -d odoo
# Or use specific tag:
docker compose pull odoo # pulls :latest which is previous
docker compose up -d odooModule Upgrade in Pipeline
# After deploying new image, upgrade modules:
docker compose exec odoo odoo -d production -u my_module --stop-after-init
# For automated upgrades:
# deploy.sh:
#!/bin/bash
set -e
docker compose pull odoo
docker compose stop odoo
docker compose run --rm odoo odoo -d production -u my_module --stop-after-init
docker compose up -d odoo
# Health check
sleep 15
curl -f http://localhost:8069/web/health || exit 1
echo "Deployment successful!"Private Registry Options
| Registry | Free Tier | Best For |
|---|---|---|
| GitHub Container Registry | Free (public) | GitHub repos |
| Docker Hub | 1 private repo | Simple setup |
| AWS ECR | 500MB free | AWS deployments |
| Harbor | Self-hosted (free) | Full control |
| GitLab Registry | Free with GitLab | GitLab users |
DeployMonkey
DeployMonkey provides Git-integrated deployments with Docker. Push to your repo, DeployMonkey builds, tests, and deploys automatically. Zero-downtime with automatic rollback on health check failure. No CI/CD pipeline to maintain.