I've done something similar but I'm not sure how helpful my example would be because I use wireguard instead of tailscale and traefik instead of caddy.
The principle is the same though, iirc I have my traefik container set to network_mode: "service:wireguard" so that the traefik container uses the wireguard container's network stack. That way the traefik container also sees the wireguard interface and can receive traffic going to the wireguard IP. Then at the other end of the wireguard tunnel I can use haproxy to pass traffic to the wireguard IP through the tunnel and it automatically hits traefik.