Short Note: docker-compose and Tailscale connectivity issues

Search for a command to run...

No comments yet. Be the first to comment.
I have been playing around with the https://ergaster.org/posts/2025/07/28-direnv-bitwarden-integration/. It is a necessary read before you read this note since it explains the problem in quite nice details and builds the proposed solution step by ste...
The time has come: my homelab, for which I have been writing how-tos and occasional status updates on this blog had / has been serving me very well, but k8s ecosystem has reached maturity levels and broad acceptance and my Nomad cluster raises more q...

I figured that over night one of my PCs is spending time on “something”. System logs don’t show anything, app logs neither. So, I spent like 30min and made this tiny script which might be useful for you as well. I connect to my host using SSH, and I ...
I figured out after full day of work a very peculiar behavior in Spring Boot and wanted to write this one down since it was a pretty annoying one. Let’s say you are: using Spring Boot and need to make HTTP client connections (using RestTemplate or R...
In case you use some tools (like goreleaser) that depend on running in the case of tagged commits only, but you wish at the same time not to bother with manually tagging your commits but just to push to master… I found a nice & easy way to auto-tag c...
TL;DR
The article discusses connectivity issues between Docker Compose and services exposed via Tailscale after the OS package updates. After troubleshooting, the issue was identified as Docker Compose not running container in bridged mode. The solution involved modifying the docker-compose.yml file and using the docker compose command.
I had a very old Caddy service setup using docker-compose that was "just working" for years, and after the weekly GH Actions Ansible-driven update of all apps (including docker / docker-compose / tailscale) I've noticed all sorts of alerts popping up since Caddy couldn't access services exposed via Tailscale on other nodes.
Apparently couple of things changed:
Tailscale was updated
Docker was updated
Docker Compose was updated
Now, the first reaction was to restart docker on all nodes, but that helped fix other services (probably some kind of breaking change), but no amount of restarting didn't help to recover the Caddy.
It was a very simple docker compose setup, just this:
version: '3'
services:
caddy:
image: milanaleksic/caddy-cloudflare:2.7.6
ports:
- 80:80
- 443:443
volumes:
- ./data/caddy-config:/config
- ./data/caddy-data:/data
- ./config:/etc/caddy
And Caddy was reporting bunch of (for each attempt to access URLs which were proxied into somewhere internally within the Tailscale network):
... dial tcp 100.85.131.92:22487: i/o timeout ...
What made this issue extremely interesting is that I had to try various things until I have figured out what is going on:
From this node a normal curl 100.85.131.92:22487 just worked.
When I start a simple docker container it also just worked.
Even when I manually start the docker image from above: milanaleksic/caddy-cloudflare:2.7.6 also curl just worked!
I thought I was going crazy but then I had to get the big guns and run diff analysis of the outputs of docker inspect container1 and docker inspect container2 commands (where the 2 containers were the one that I started manually vs the one compose started). And the problem exposed it self: the docker-compose didn't run network in bridged mode. That was the difference between manually started container and the one started by docker-compose.
What I ended up doing was changing the docker-compose.yml to:
- version: '3'
-
services:
caddy:
image: milanaleksic/caddy-cloudflare:2.7.6
+ networks:
+ - caddy
ports:
- 80:80
- 443:443
volumes:
- ./data/caddy-config:/config
- ./data/caddy-data:/data
- ./config:/etc/caddy
+
+ networks:
+ caddy:
+ driver: bridge
To make this new docker-compose.yml file work I had to actually stop using docker-compose to run it since it was deprecated for a while now and just ran the docker compose command (the former was still written in Python, and the feature was migrated into Go CLI docker command).
đź’Ł, it just works now!