Published on : 2026-08-31 15:11
       
       I have five computers in my living room. At some point, it seemed 
       like a good idea to make them work together. So, naturally, I 
       installed Docker and used it's swarm feature. My little cluster 
       currently looks like this:
       
           Tiny       : Swarm leader
           Lenovo 1   : worker
           Lenovo 2   : worker
           Lenovo 3   : worker
           NAS        : worker + NAS (backups)
       
 (IMG)  Tiny, the 3 Lenovos and the router
 (IMG)  The NAS with it's guardian
       
       Tiny is an Ace Magician mini PC with a Celeron N5095 and 8 GB of 
       RAM. The three Lenovo M53s are even more impressive with Pentiums 
       J2900, 8 GB of RAM and 500 GB HDDs. And then there's the NAS, a 
       Lenovo P510 with a Xeon and 16 GB of RAM.
       
       In other words, this isn't exactly a cloud provider.
       
       Creating the Swarm
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       Swarm Init
       ‾‾‾‾‾‾‾‾‾‾
       I started on Tiny:
       
           docker swarm init --advertise-addr <TINY-IP>
       
       Swarm Join
       ‾‾‾‾‾‾‾‾‾‾
       Docker then gave me a docker swarm join command:
       
           docker swarm join --token SWMTKN-1-... <TINY-IP>:2377
       
       I ran that on the other four machines and checked everything from
        Tiny:
       
           docker node ls
       
       Five machines appeared: 1 leader and 4 workers. It worked. 
       Already more distributed computing than most living rooms 
       probably need.
       
           HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE
           lenovo1    Down      Active                          29.7.2
           lenovo2    Down      Active                          29.7.2
           lenovo3    Down      Active                          29.7.2
           nas        Down      Active                          29.7.2
           tiny       Ready     Active         Leader           29.7.2
       
       Running a service
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       One of the things I wanted to run across the cluster is my HTTPS 
       service.
       
       Normally I'd create it with a rather long command:
       
           docker service create \
             --with-registry-auth \
             --name httpsSavaRocks \
             --replicas 5 \
             --publish published=8082,target=8082 \
             --restart-condition any \
             --replicas-max-per-node 1 \
             --mount type=bind,source=/etc/hostname,
               destination=/etc/hostname \
             savarocks/https:latest
       
       The interesting bit is:
       
           --replicas 5
           --replicas-max-per-node 1
       
       I have five nodes, so Swarm puts a replica on each node. 
       5 old computers pretending to be proper infrastructure.
       
       Updating the service
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       Let's say I've updated the docker image for the service https. 
       I can pull the new image and update all 5 replicas with:
       
           docker service update --force --image savarocks/https:latest\
           httpsSavaRocks
       
       These commands are long so using aliases is the better approach:
       
 (DIR)  Using aliases for complex and daily terminal commands
       
       Put it in a file
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       Of course, nobody wants to keep that command in their shell 
       history forever or use aliases. Using compose files is another 
       great way to manage your swarm services:
       
           services:
             httpsSavaRocks:
               image: savarocks/https:latest
               ports:
                 - target: 8082
                   published: 8082
                   protocol: tcp
                   mode: ingress
               volumes:
                 - type: bind
                   source: /etc/hostname
                   target: /etc/hostname
               deploy:
                 replicas: 5
                 restart_policy:
                   condition: any
                 placement:
                   max_replicas_per_node: 1
       
       Then you can run an easier to remember command like:
       
           docker stack deploy \
             --with-registry-auth \ 
             -c httpsSavaRocks.yml \
             httpsSavaRocks
       
       And that's it.
       
       Why the hostname mount?
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       The slightly strange /etc/hostname mount is intentional. 
       The HTTPS service can see the hostname of the machine running 
       the container. So when something breaks, I can find out whether 
       it happened on Tiny, one of the Lenovos, or the NAS. Because 
       "something broke" is not nearly as useful as "something broke 
       on Lenovo 2", especially when Lenovo 2 is one of three identical 
       little boxes sitting next to each other.
       
       Is Swarm necessary?
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       Probably not. I could run everything with regular Docker. But 
       that's not really the point. I already have five machines. 
       Docker Swarm lets me treat them as a small cluster without 
       turning my homelab into a full-time Kubernetes administration 
       course.
       
       And I like keeping things simple.
       
       A Compose file or command says: "replicas: 5" and the swarm 
       replies with OK. And then five containers appear.
       
       Five computers in the living room
       ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
       There is something funny about running a Docker Swarm on 5 
       machines that were mostly acquired because they were cheap, 
       small, old, or all three.
       
       But that's what I like about homelabs. You don't need a rack 
       full of servers. You can take a few old computers, give them 
       names, connect them together and convince yourself you're 
       running a tiny privately owned cloud. And technically... you are.
       
       Just don't ask me about the electricity bill.
       
 (DIR)  Back to my phlog