RousselTMLEARNING

Automation

Vagrant multi-machine: deploying a ready-to-use Docker Swarm cluster

Use a single Vagrantfile to build a three-node Docker Swarm cluster (one manager, two workers) with automated joining, then deploy and scale a service.

1. The principle #

Several machines, a single file.

Why automate joining #

Docker Swarm needs one node to initialize the cluster (docker swarm init) and the others to join it with a token. Done by hand, it is tedious and error-prone. With Vagrant, the manager writes its token into the shared /vagrant folder, which the workers read when they start.

Docker Swarm cluster with Vagrant
The synced folder serves as a channel between machines during provisioning.
Creation order: Machines are created in the order of the Vagrantfile: the manager must be declared first so that the token exists when the workers start.

2. The Vagrantfile #

A loop and two scripts.

Vagrantfile #

NODES = { "manager1" => "192.168.56.10", "worker1" => "192.168.56.11", "worker2" => "192.168.56.12" }

Vagrant.configure("2") do |config|
  config.vm.box = "bento/ubuntu-24.04"
  config.vm.provision "shell", path: "scripts/docker.sh"          # commun : installer Docker

  NODES.each do |name, ip|
    config.vm.define name do |node|
      node.vm.hostname = name
      node.vm.network "private_network", ip: ip
      node.vm.provider "virtualbox" do |vb|
        vb.memory = 1536
        vb.cpus = 2
      end
      role = name.start_with?("manager") ? "manager" : "worker"
      node.vm.provision "shell", path: "scripts/#{role}.sh", args: [ip, NODES["manager1"]]
    end
  end
end

scripts/docker.sh #

#!/usr/bin/env bash
set -euo pipefail
curl -fsSL https://get.docker.com | sh
usermod -aG docker vagrant

scripts/manager.sh and scripts/worker.sh #

# manager.sh
set -euo pipefail
docker swarm init --advertise-addr "$1"
docker swarm join-token -q worker > /vagrant/worker.token

# worker.sh
set -euo pipefail
docker swarm join --token "$(cat /vagrant/worker.token)" "$2:2377"

3. Starting and using the cluster #

Check, deploy, scale.

Commands #

vagrant up                                   # crée les trois nœuds dans l'ordre
vagrant ssh manager1 -c "docker node ls"      # trois nœuds Ready, un Leader
vagrant ssh manager1 -c "docker service create --name web --replicas 3 -p 8080:80 nginx"
vagrant ssh manager1 -c "docker service ps web"
vagrant ssh manager1 -c "docker service scale web=6"
curl http://192.168.56.11:8080               # le maillage de routage répond sur chaque nœud
vagrant destroy -f && rm -f worker.token

Pitfalls #

  • Advertise interface: without --advertise-addr, Swarm picks VirtualBox's NAT interface (10.0.2.15), identical on every machine, and joining fails.
  • Stale token: delete worker.token after a vagrant destroy.
  • Ports: 2377 (management), 7946 (communication) and 4789/udp (overlay network) must be open between the nodes.
Good practice: For a more resilient cluster, declare three managers: Swarm then tolerates the loss of one manager (Raft quorum).

Related articles

Vagrant: overview and vocabulary (box, provider, provisioner, Vagrantfile)

The essential notions for following the Vagrant course: what Vagrant is for, the lifecycle of an environment,…

Vagrant plugins: extending providers, provisioners and commands

Understand Vagrant's plugin system: what a plugin can add (provider, provisioner, command, capability), insta…

Sharing a Vagrant environment: ngrok and the vagrant-share plugin

Make an application running in a Vagrant machine accessible to a colleague or a client: port forwarding, ngro…

Keep learning

Support us

♥ SUPPORT US

Support RousselTM Learning

Courses, articles, labs and certificates stay free with no intrusive ads. A voluntary contribution, of any amount you choose, pays for hosting, lab environments and new content.

Contribute with PayPal Any amount · card or PayPal accountLearn more
QR code PayPal
Or scan this QR code with your phone

Thank you, every contribution counts!