Skip to content

Odoo Blue-Green Deployment: Zero Downtime Updates Guide (2026)

DeployMonkey Team · March 23, 2026 11 min read

What is Blue-Green Deployment?

Blue-green deployment maintains two identical production environments. One ("blue") serves live traffic while the other ("green") sits idle. When you deploy an update, you deploy to the idle environment, test it, then switch traffic. If something goes wrong, switch back instantly.

For Odoo, this eliminates the dreaded maintenance window where users see "System under maintenance" for 30-60 minutes during module upgrades. Instead, the switch happens in seconds.

Why Blue-Green for Odoo?

Odoo updates are risky. Module upgrades run database migrations, update views, and modify workflows. A failed upgrade can leave your system in an inconsistent state. Traditional deployment means:

  1. Notify users of downtime
  2. Stop Odoo
  3. Run backup (15-30 min for large DBs)
  4. Run module upgrade (-u) (5-30 min)
  5. Test (5-10 min)
  6. Start Odoo or rollback from backup (15-30 min)

Total: 30-90 minutes of downtime. With blue-green, users experience zero downtime, and rollback takes seconds instead of 30 minutes.

Architecture

                DNS / Load Balancer
                     ↓
         ┌───────────┼───────────┐
         ↓                       ↓
    Blue Environment         Green Environment
    ┌─────────────┐         ┌─────────────┐
    │ Odoo v1.0   │         │ Odoo v1.1   │
    │ nginx       │         │ nginx       │
    │ PG (copy)   │         │ PG (copy)   │
    └─────────────┘         └─────────────┘
    
    ACTIVE (serving)        IDLE (updated, tested)

Step 1: Set Up Two Environments

Create two identical server configurations. Use Docker to make this manageable:

# Blue environment (currently active)
docker compose -f docker-compose.blue.yml up -d

# Green environment (idle)
docker compose -f docker-compose.green.yml up -d
# docker-compose.blue.yml
services:
  odoo-blue:
    image: your-registry/odoo:v1.0
    ports:
      - "8069:8069"
    environment:
      HOST: pg-blue
    volumes:
      - odoo-blue-data:/var/lib/odoo
      - ./addons:/mnt/extra-addons
  
  pg-blue:
    image: postgres:16
    volumes:
      - pg-blue-data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: odoo
      POSTGRES_PASSWORD: ${DB_PASSWORD}

Step 2: Deployment Process

#!/bin/bash
# deploy.sh - Blue-green deployment script

CURRENT=$(cat /opt/deploy/active)  # "blue" or "green"
if [ "$CURRENT" = "blue" ]; then
    TARGET="green"
else
    TARGET="blue"
fi

echo "Deploying to $TARGET (current: $CURRENT)"

# 1. Copy database from active to target
echo "Copying database..."
pg_dump -h pg-$CURRENT -U odoo odoo | psql -h pg-$TARGET -U odoo odoo_staging

# 2. Update code in target
echo "Updating code..."
docker compose -f docker-compose.$TARGET.yml pull
docker compose -f docker-compose.$TARGET.yml up -d

# 3. Run module upgrade on target
echo "Running module upgrade..."
docker compose -f docker-compose.$TARGET.yml exec odoo \
  odoo -d odoo_staging -u your_modules --stop-after-init

# 4. Smoke test
echo "Running smoke tests..."
curl -f http://localhost:${TARGET_PORT}/web/health || {
    echo "SMOKE TEST FAILED. Aborting."
    exit 1
}

# 5. Switch traffic
echo "Switching traffic to $TARGET..."
sed -i "s/odoo-$CURRENT/odoo-$TARGET/g" /etc/nginx/conf.d/odoo.conf
nginx -s reload

# 6. Record active environment
echo $TARGET > /opt/deploy/active
echo "Deployment complete. $TARGET is now active."

Step 3: Database Handling

The database is the trickiest part. Options:

StrategyDowntimeData Loss RiskComplexity
Shared databaseZeroNoneLow (but migration risk)
Database copy before switchBrief (pg_dump)Transactions during copyMedium
Logical replicationZeroNoneHigh
Point-in-time clone (ZFS/LVM)SecondsNoneMedium

Recommended: Shared Database with Migration Guard

For most Odoo deployments, sharing a single database between blue and green is simplest. The key is ensuring backward compatibility:

  • New fields should have defaults so old code handles them
  • Avoid removing columns in the same release that drops the code
  • Test the migration on a database copy before switching

Step 4: Rollback

#!/bin/bash
# rollback.sh - Instant rollback

CURRENT=$(cat /opt/deploy/active)
if [ "$CURRENT" = "blue" ]; then
    ROLLBACK="green"
else
    ROLLBACK="blue"
fi

echo "Rolling back to $ROLLBACK..."
sed -i "s/odoo-$CURRENT/odoo-$ROLLBACK/g" /etc/nginx/conf.d/odoo.conf
nginx -s reload
echo $ROLLBACK > /opt/deploy/active
echo "Rollback complete. $ROLLBACK is now active."

Step 5: Automated Health Checks

#!/bin/bash
# health_check.sh - Verify deployment health

TARGET_URL="http://odoo-$TARGET:8069"

# Check HTTP response
HTTP_CODE=$(curl -s -o /dev/null -w '%{http_code}' $TARGET_URL/web/health)
if [ "$HTTP_CODE" != "200" ]; then
    echo "FAIL: HTTP health check returned $HTTP_CODE"
    exit 1
fi

# Check response time
RESP_TIME=$(curl -s -o /dev/null -w '%{time_total}' $TARGET_URL/web/login)
if (( $(echo "$RESP_TIME > 5" | bc -l) )); then
    echo "FAIL: Response time ${RESP_TIME}s exceeds 5s threshold"
    exit 1
fi

# Check database connectivity
PG_STATUS=$(docker compose exec odoo python3 -c "import psycopg2; psycopg2.connect('...')" 2>&1)
if [ $? -ne 0 ]; then
    echo "FAIL: Database connectivity check failed"
    exit 1
fi

echo "All health checks passed"

CI/CD Integration

Integrate blue-green deployment into your CI/CD pipeline:

  1. Push code to main branch
  2. CI builds new Docker image
  3. CI pushes image to registry
  4. CD triggers deployment script
  5. Script deploys to idle environment
  6. Automated tests run against new deployment
  7. If tests pass, switch traffic
  8. If tests fail, alert team, no traffic switch

DeployMonkey + Blue-Green

DeployMonkey supports blue-green deployment strategies for managed Odoo instances. Deploy updates with zero downtime and instant rollback capability through the control panel.