Why Docker Swarm for Odoo?
Docker Swarm provides container orchestration without the complexity of Kubernetes. If you need multi-node deployment, rolling updates, and automatic service recovery but find Kubernetes overkill, Docker Swarm is the middle ground. It uses the same Docker CLI you already know, requires no additional tooling, and can be set up in minutes.
For Odoo deployments with 2-5 servers, Docker Swarm delivers high availability and load balancing with dramatically less operational overhead than Kubernetes.
Architecture
Manager Node 1 (leader)
├── Traefik (reverse proxy + SSL)
├── Odoo replica 1
└── PostgreSQL (primary)
Worker Node 2
├── Odoo replica 2
└── PostgreSQL (replica, optional)
Worker Node 3
└── Odoo replica 3Prerequisites
- 2-5 servers (Ubuntu 24.04 recommended)
- Docker installed on all nodes
- Ports 2377, 7946, 4789 open between nodes
- Domain name pointing to manager node IP
Step 1: Initialize the Swarm
# On manager node
docker swarm init --advertise-addr YOUR_MANAGER_IP
# This outputs a join token. Run it on worker nodes:
docker swarm join --token SWMTKN-xxx YOUR_MANAGER_IP:2377
# Verify nodes
docker node lsStep 2: Create Overlay Network
docker network create --driver overlay --attachable odoo-networkStep 3: Create Docker Compose for Swarm
# docker-compose.yml
version: '3.8'
services:
postgresql:
image: postgres:16
environment:
POSTGRES_USER: odoo
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
POSTGRES_DB: odoo
volumes:
- pg_data:/var/lib/postgresql/data
networks:
- odoo-network
secrets:
- db_password
deploy:
replicas: 1
placement:
constraints:
- node.role == manager
resources:
limits:
memory: 4G
cpus: '2'
odoo:
image: odoo:19
environment:
HOST: postgresql
PORT: 5432
USER: odoo
PASSWORD_FILE: /run/secrets/db_password
volumes:
- odoo_data:/var/lib/odoo
- odoo_addons:/mnt/extra-addons
networks:
- odoo-network
secrets:
- db_password
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 30s
order: start-first
restart_policy:
condition: on-failure
delay: 10s
resources:
limits:
memory: 4G
cpus: '2'
labels:
- "traefik.enable=true"
- "traefik.http.routers.odoo.rule=Host(`erp.yourdomain.com`)"
- "traefik.http.routers.odoo.tls.certresolver=le"
- "traefik.http.services.odoo.loadbalancer.server.port=8069"
- "traefik.http.services.odoo.loadbalancer.sticky.cookie=true"
traefik:
image: traefik:v3.0
command:
- --providers.docker.swarmMode=true
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- [email protected]
- --certificatesresolvers.le.acme.storage=/letsencrypt/acme.json
- --certificatesresolvers.le.acme.httpchallenge.entrypoint=web
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- letsencrypt:/letsencrypt
networks:
- odoo-network
deploy:
placement:
constraints:
- node.role == manager
volumes:
pg_data:
odoo_data:
odoo_addons:
letsencrypt:
networks:
odoo-network:
external: true
secrets:
db_password:
external: trueStep 4: Deploy the Stack
# Create secrets
echo "secure_password" | docker secret create db_password -
# Deploy
docker stack deploy -c docker-compose.yml odoo
# Check services
docker service ls
docker service ps odoo_odooStep 5: Rolling Updates
Update Odoo with zero downtime:
# Build and push your custom Odoo image
docker build -t your-registry/odoo:19-custom-v2 .
docker push your-registry/odoo:19-custom-v2
# Update the service
docker service update --image your-registry/odoo:19-custom-v2 odoo_odoo
# The update_config ensures:
# - 1 container at a time (parallelism: 1)
# - 30s delay between updates
# - New container starts before old one stops (start-first)Shared Storage
Odoo's filestore must be shared across all replicas. Options:
| Solution | Complexity | Performance | Cost |
|---|---|---|---|
| NFS share | Low | Good | Free (self-managed) |
| GlusterFS | Medium | Very good | Free |
| AWS EFS | Low | Good | $0.30/GB/mo |
| MinIO (S3-compatible) | Medium | Excellent | Free |
Monitoring
Add monitoring to your Swarm stack:
# Add to docker-compose.yml
portainer:
image: portainer/portainer-ce
ports:
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer_data:/data
deploy:
placement:
constraints:
- node.role == managerDocker Swarm vs Kubernetes for Odoo
| Feature | Docker Swarm | Kubernetes |
|---|---|---|
| Setup complexity | Minutes | Hours to days |
| Learning curve | Low (Docker CLI) | High (new concepts) |
| Scaling | Manual or basic | HPA, VPA, custom metrics |
| Rolling updates | Built-in | Built-in, more options |
| Service discovery | Built-in DNS | CoreDNS, services |
| Ecosystem | Smaller | Vast (Helm, operators) |
| Best for | 2-10 nodes | 10+ nodes, complex apps |
DeployMonkey + Docker Swarm
DeployMonkey uses Docker for container orchestration. If you need multi-node Odoo deployments without Kubernetes complexity, Docker Swarm provides the right balance of simplicity and reliability.