Docker-compose with network_mode: "service:[service name]"

I struggle to figure out how to use traefik when I make use of the command.
network_mode: "service:[service name]"

For example I am unable to access heimdall.my.domain.

My use case:
The network stack of a vpn container should be used by other containers to reach the internet.

I verified the following:

  • The openvpn-client container can reach both networks proxy and internal.
  • Traefik is working without network_mode: "service:[service name]"

docker-compose.yml

version: "3.7"

services:
  openvpn-client:
    container_name: openvpn-client
    image: dperson/openvpn-client
    restart: always
    networks:
      - internal
      - proxy
    dns:
      - 1.1.1.1
      - 1.0.0.1
    volumes:
      - /opt/docker/openvpn-client:/vpn
    environment: 
      - TZ=Europe/Berlin
      - ROUTE=10.255.86.0/24
      - ROUTE=10.0.86.0/24
      - ROUTE=172.21.0.0/16
    cap_add:
      - net_admin
    devices:
      - /dev/net/tun:/dev/net/tun

  traefik:
    container_name: traefik
    image: traefik
    restart: always
    networks:
      - proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /opt/docker/traefik/traefik.toml:/traefik.toml
      - /opt/docker/traefik/acme.json:/acme.json
      - /opt/docker/traefik/dynamic.toml:/dynamic.toml
    labels:
      - traefik.enable=true
      - traefik.http.routers.api.rule=Host(`traefik.my.domain`)
      - traefik.http.middlewares.add-dashboard.addprefix.prefix=/dashboard/
      - traefik.http.routers.api.tls.domains[0].main=my.domain
      - traefik.http.routers.api.tls.domains[0].sans=*.my.domain
      - traefik.http.services.api.loadbalancer.server.port=8080
      - traefik.http.services.api.loadbalancer.server.scheme=http
      - traefik.http.routers.https-redirect.entrypoints=web
      - traefik.http.routers.https-redirect.rule=HostRegexp(`{any:.*}`)
      - traefik.http.routers.https-redirect.middlewares=https-redirect
      - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https

  heimdall:
    container_name: heimdall
    image: linuxserver/heimdall
    restart: always
    networks_mode: "service:openvpn-client"
    volumes:
      - /opt/docker/heimdall:/config
    environment:
      - PGID=1100
      - PUID=1100
      - TZ=Europe/Berlin
    labels:
      - traefik.enable=true
      - traefik.http.routers.heimdall.entrypoints=web,web-secure
      - traefik.http.routers.heimdall.rule=Host(`heimdall.my.domain`)
      - traefik.http.routers.heimdall.tls.domains[0].main=my.domain
      - traefik.http.routers.heimdall.tls.domains[0].sans=*.my.domain
      - traefik.http.services.heimdall.loadbalancer.server.port=443
      - traefik.http.services.heimdall.loadbalancer.server.scheme=https

networks:
  proxy:
    external: true
  internal:
    external: false

traefik.toml

################################################################
#
# Configuration sample for Traefik v2.
#
################################################################

################################################################
# Global configuration
################################################################

[global]
  checkNewVersion = true
  sendAnonymousUsage = false

[serversTransport]
  insecureSkipVerify = true
  maxIdleConnsPerHost = 0

################################################################
# Entrypoints configuration
################################################################

[entryPoints]
  [entryPoints.web]
    address = ":80"
  [entryPoints.web-secure]
    address = ":443"

################################################################
# Traefik logs configuration
################################################################

[log]
  level = "ERROR"

################################################################
# Access logs configuration
################################################################

[accessLog]
  filePath = "/var/log/access.log"

################################################################
# API and dashboard configuration
################################################################

[api]
  dashboard = true
  insecure = true

################################################################
# Docker configuration backend
################################################################

[providers.docker]
  endpoint = "unix:///var/run/docker.sock"
  exposedByDefault = false
  network = "proxy"
  watch = true

[certificatesResolvers]
  [certificatesResolvers.default]
    [certificatesResolvers.default.acme]
      email = "my@email"
      storage = "acme.json"
      [certificatesResolvers.default.acme.dnsChallenge]
        provider = "cloudflare"
        delayBeforeCheck = "0s"
        resolvers = ["1.1.1.1:53", "8.8.8.8:53"]

Bump. Anyone knows what I have to do?

Hello @anatom,

to be honst, I never faced that network mode :slight_smile: My guess though is, that by using that mode your heimdall service will only be accessible from the open-vpn service(as you said), as they are on the same network. Traefik is only attached to the proxy network, so it can't reach heimdall.

Does it work when you attach heimdall to the proxy network as well?

@SantoDE You are right heimdall is only accessible through the vpn container, but with this network mode it isn't possible to attach another network.

Moving the labels from heimdall to openvpn-client does work however. At first I thought it doesn't because it takes a while until the node shows up in traefik.

version: "3.7"

services:
  openvpn-client:
    container_name: openvpn-client
    image: dperson/openvpn-client
    restart: always
    networks:
      - internal
      - proxy
    dns:
      - 1.1.1.1
      - 1.0.0.1
    volumes:
      - /opt/docker/openvpn-client:/vpn
    environment: 
      - TZ=Europe/Berlin
      - ROUTE=10.255.86.0/24
      - ROUTE=10.0.86.0/24
      - ROUTE=172.21.0.0/16
    cap_add:
      - net_admin
    devices:
      - /dev/net/tun:/dev/net/tun
    labels:
      - traefik.enable=true
      - traefik.http.routers.heimdall.entrypoints=web,web-secure
      - traefik.http.routers.heimdall.rule=Host(`heimdall.my.domain`)
      - traefik.http.routers.heimdall.tls.domains[0].main=my.domain
      - traefik.http.routers.heimdall.tls.domains[0].sans=*.my.domain
      - traefik.http.services.heimdall.loadbalancer.server.port=443
      - traefik.http.services.heimdall.loadbalancer.server.scheme=https

  traefik:
    container_name: traefik
    image: traefik
    restart: always
    networks:
      - proxy
    ports:
      - 80:80
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /opt/docker/traefik/traefik.toml:/traefik.toml
      - /opt/docker/traefik/acme.json:/acme.json
      - /opt/docker/traefik/dynamic.toml:/dynamic.toml
    labels:
      - traefik.enable=true
      - traefik.http.routers.api.rule=Host(`traefik.my.domain`)
      - traefik.http.middlewares.add-dashboard.addprefix.prefix=/dashboard/
      - traefik.http.routers.api.tls.domains[0].main=my.domain
      - traefik.http.routers.api.tls.domains[0].sans=*.my.domain
      - traefik.http.services.api.loadbalancer.server.port=8080
      - traefik.http.services.api.loadbalancer.server.scheme=http
      - traefik.http.routers.https-redirect.entrypoints=web
      - traefik.http.routers.https-redirect.rule=HostRegexp(`{any:.*}`)
      - traefik.http.routers.https-redirect.middlewares=https-redirect
      - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https

  heimdall:
    container_name: heimdall
    image: linuxserver/heimdall
    restart: always
    networks_mode: "service:openvpn-client"
    volumes:
      - /opt/docker/heimdall:/config
    environment:
      - PGID=1100
      - PUID=1100
      - TZ=Europe/Berlin

Thank you, @anatom! That did the trick.