Docker Swarm Cluster for Odoo: Create and Join Nodes

Set up a Docker Swarm cluster for Odoo: open the right ports, join managers and workers, then drain, promote, demote and remove nodes safely.

Updated . 7 min read

A Docker Swarm cluster for Odoo lets you run many Odoo instances across several servers and manage them from one place. Odoo containers can move to another host when one fails, and you can patch a server without logging in to each instance. This guide covers setting up that cluster from start to finish: planning managers and workers, opening the right ports, creating the swarm, joining nodes with tokens, and handling routine node work (drain, promote, demote, remove) without losing quorum.

If you have not decided between Compose and Swarm yet, read Odoo Docker Compose vs Swarm first. For the full production picture, see the pillar guide Odoo on Docker Swarm.

Plan the cluster before you add a node

A swarm has two node roles. Managers store the cluster state and schedule work. Workers run containers. For Odoo hosting, a common layout is:

  • 3 managers: small servers (2 vCPU, 4 GB RAM is plenty) set to drain so they run no Odoo containers. Three managers can lose one and keep working.
  • Workers for Odoo: size them by how many Odoo workers you plan to run. Odoo's own sizing rule is about (CPUs × 2) + 1 HTTP workers per server, with one worker serving roughly 6 concurrent users. Budget RAM for each worker too. Odoo also recommends budgeting RAM for each worker, with heavy requests using far more than light ones.
  • A PostgreSQL node: a worker with fast local disk, labeled so the database service always lands there. See Odoo server placement in Swarm for labels and constraints.

Use an odd number of managers. Four managers tolerate one failure, the same as three, so the fourth adds risk without adding safety. Install the same Docker Engine version on every node, and keep clocks in sync with NTP: nodes authenticate with TLS certificates, and certificate checks fail when clocks drift.

Open the swarm ports

Nodes must reach each other on a private network. Open these ports between swarm hosts only, never to the internet:

PortProtocolUsed for
2377TCPCluster management traffic to managers
7946TCP and UDPNode discovery for overlay networks
4789UDPOverlay network (VXLAN) data traffic
IP protocol 50 (ESP)-Only if you create encrypted overlay networks

VXLAN on port 4789 has no authentication, so a host that can reach that port can inject traffic into your overlay networks. Keep it on the private network. Your public firewall should only allow 80 and 443 to the nodes that run your reverse proxy.

Create the swarm on the first manager

On the first manager, initialize the swarm and advertise its private address:

docker swarm init --advertise-addr <MANAGER1_PRIVATE_IP>

--advertise-addr is the address other nodes use to reach this manager. Set it explicitly on any server with more than one network interface, or Docker may pick the public one. If you want overlay data traffic on a separate interface from management traffic, add --data-path-addr <IP_OR_INTERFACE>.

The command prints a ready-made docker swarm join line for workers. You can print it again at any time.

Get the join tokens

Every swarm has two join tokens: one that makes a new node a worker and one that makes it a manager. Treat both like passwords. The manager token is the more sensitive one, because a manager controls the whole cluster.

docker swarm join-token worker
docker swarm join-token manager

# print only the token, for scripts
docker swarm join-token -q worker

Join workers and managers

On each Odoo worker, run the join command with the worker token:

docker swarm join --token <WORKER_TOKEN> <MANAGER1_PRIVATE_IP>:2377

On the second and third managers, use the manager token. Add --availability drain so they never receive Odoo containers:

docker swarm join --token <MANAGER_TOKEN> \
  --advertise-addr <THIS_NODE_PRIVATE_IP> \
  --availability drain \
  <MANAGER1_PRIVATE_IP>:2377

Back on any manager, check the result:

docker node ls

You should see three nodes with a MANAGER STATUS of Leader or Reachable, and your workers with an empty manager status. Every node should be Ready. Managers you joined with drain show Drain under AVAILABILITY. If you created the first manager before deciding to drain it, run docker node update --availability drain <NODE> on it now.

Label nodes for Odoo workloads

Labels let your Odoo stacks pick the right hosts. Add them from a manager:

docker node update --label-add pool=odoo worker-1
docker node update --label-add pool=odoo worker-2
docker node update --label-add db=true db-1

Drain a node for maintenance

A node's availability is one of three states:

  • active: the scheduler can place new tasks here.
  • pause: running tasks stay, but no new tasks are placed here.
  • drain: running tasks are stopped and rescheduled on other nodes, and no new tasks are placed here.

Before you patch the kernel or resize a worker, drain it:

docker node update --availability drain worker-2
docker node ps worker-2

Wait until docker node ps shows no running tasks, do the maintenance, then bring the node back:

docker node update --availability active worker-2

Two Odoo-specific warnings. First, an Odoo service with one replica is restarted on another node when you drain, so its users see a short interruption while the new container loads the registry. Do it outside business hours. Second, the new node must reach the same filestore. With a local volume, the rescheduled Odoo container starts with an empty /var/lib/odoo and attachments appear missing. Use shared storage as described in Odoo filestore on NFS, or pin each instance to its node with a constraint.

Bringing a node back to active does not move existing tasks back onto it. Swarm does not rebalance on its own. To spread a service again, force a rolling restart with docker service update --force <SERVICE>.

Promote and demote managers

To replace a failing manager or grow from one manager to three, promote a worker:

docker node promote worker-3

To take a manager out of the control plane, demote it:

docker node demote manager-3
Quorum warning: managers need a majority to make any change. With 3 managers, demoting one leaves 2, and losing one more stops all scheduling. Running Odoo containers keep serving users, but you cannot deploy, scale or reschedule anything. Promote the replacement first, then demote the old manager. Never demote or remove managers in bulk.
ManagersMajority neededFailures tolerated
110
321
532
743

Remove a node cleanly

To retire a worker, drain it, then make it leave from the node itself:

# on the worker
docker swarm leave

The node then shows as Down in docker node ls. Remove it from the list on a manager:

docker node rm worker-2

If a server died and will never come back, docker node rm refuses while Swarm still thinks the node is up. Use docker node rm --force worker-2.

For a manager, demote it before removing it. A manager can only leave with docker swarm leave --force, and doing that without demoting first breaks your quorum math. If you ever lose quorum completely, the only recovery is docker swarm init --force-new-cluster on a surviving manager. Back up /var/lib/docker/swarm on a manager regularly so you have the Raft data if that day comes.

Rotate join tokens

If a token leaks or someone with access leaves your team, rotate it. Nodes already in the swarm are not affected.

docker swarm join-token --rotate worker
docker swarm join-token --rotate manager

Do not store tokens in Git or in plain-text provisioning scripts. Have your automation fetch them from a manager at join time with docker swarm join-token -q.

Next steps

With nodes joined and labeled, deploy Odoo and PostgreSQL as a stack with docker stack deploy, then put a reverse proxy in front of it.

Running a swarm means you own manager quorum, certificate expiry, storage and upgrades. If you would rather run Odoo than run the cluster, Easy Instance hosts Odoo 17 to 20 on managed infrastructure for $30 per Odoo worker per month (pricing). You can try it with a 10-day free trial, no credit card needed.

Rather not run the server yourself?

Get managed Odoo hosting with backups, SSL, monitoring and updates handled for you. Free for 10 days.