Cannot access host magic DNS from container with docker-compose

Tailscale version: 1.36.2
Your operating system & version: Fedora 37

Hi!

I’m trying to set up caddy as a reverse proxy to tailscale services using magic dns. This works with the network: host option but for some reason does not work using standard bridge networks.

What confuses me is

$ docker run --rm -it alpine ping fedora
PING fedora (100.XX.XX.XX): 56 data bytes

seems to work fine, but when I run the following docker-compose.yml:

---
version: "3.4"
  
networks:
  default:
    name: server-compose-network
    attachable: true

services:
  alpine:
    container_name: alpine
    tty: true
    image: alpine
    restart: always
    privileged: true

I get the following error:

$ docker-compose --verbose exec alpine ping fedora
ping: bad address 'fedora'

However, pinging with the tailscale IP address works:

$ docker-compose --verbose exec alpine ping 100.XXX.XXX.XX
64 bytes from 100.XXX.XXX.XX: seq=0 ttl=63 time=66.605 ms

Is there some difference in the networking configuration of docker-compose that I need to be aware of to access my host dns?

The issue appears to be /etc/resolv.conf is different between the two servers:

docker-compose (does not work)

/ # cat /etc/resolv.conf
search tailxxxe.ts.net xxxx.xxxx.com.beta.tailscale.net
nameserver 127.0.0.11
options edns0 trust-ad ndots:0

docker run (works)

/ # cat /etc/resolv.conf
nameserver 205.185.112.68
nameserver 205.185.112.69
nameserver 100.100.100.100
search tailxxxe.ts.net xxxx.xxxx.com.beta.tailscale.net

Furthermore, if I create a network:

$ docker network create proxy
$ docker run --rm --network=proxy -it alpine sh
/ # ping fedora
ping: bad address 'fedora'

Hi @luciman432,

While I can appreciate being directed to the upstream manual, this was the first thing I read and I would not be posting on the tailscale forums had that sufficiently resolved my issue. The debugging steps where I identified that the issue was the unique treatment of the bridge network vs. a user created network was inspired by that page.

I also additionally did extensive google keyword searches for permutations of “tailscale”, “magic dns”, “docker bridge network”, etc. along with searching the github issue tracker.

That being said, if you read the docker networking page and there is an obvious solution that I missed, please let me know by sharing the solution here. Thanks!

Hey @mjlbach,

I have made caddy+tailscale docker image that you can look into as a reference on how to set this up.

Full docs are here: GitHub - hollie/tailscale-caddy-proxy: Tailscale and Caddy proxy to expose docker containers over Tailscale with HTTPS access

Maybe this can help you as a reference to get things started. You then don’t have to couple the docker instances to the tailscale instance of the host computer.

Hope this helps,
Lieven.

Hi @Lieven,

Thanks so much! I actually did stumble onto your repo while trying to get this working,

I think the main difference with what I want to accomplish here is I do not want to run tailscale in a container, but just share my host tailscale with the container (for reference, this is because my host itself is deployed via coreos ignition, so I’m containerizing as little as possible).

Let me know if I’m misreading what you’re suggesting though!

Hey @mjlbach,

You are correct: I launch a separate Tailscale instance per service I want to expose. This way I let every service present itself as a different Tailscale ‘host’ to the other participants of the Tailscale network.

The advantage is that this way I can run multiple services/Tailscale hosts on a single server, and I can access the services straight via their hostname.

I’m afraid I cannot help you with further pointers to accomplish the same with a single shared Tailscale client running on the host OS :frowning:

Best regards,
Lieven

Hi @mjlbach,

I had a similar issue with DNS resolution in docker containers. It seems docker always uses upstream DNS server addresses inside containers. As they know nothing about Magic DNS, you have the issue.

Try the following:

  1. In /etc/systemd/resolved.conf.d create file tailscale.conf
[Resolve]
# Use IP address of your docker0 interface here. 172.17.0.1 in my case
DNSStubListenerExtra=172.17.0.1
  1. Use DNS server 172.17.0.1 for the docker container (docker-compose should have the option)