How to combine host network with the default network in docker-compose

Viewed 9911

I'm building the docker-compose service that includes two containers. One of those containers (node) is designed to support an auto-discovery mechanism and needs to be a part of the host LAN (as I need multicast UDP packages to be handled by the LAN router, not the built-in docker router).

While the "network_mode: host" in docker-compose.yml perfectly does the trick, I need this service to be also available to a second container (qtcore) by its hostname via the default docker-compose network (like that: http://node:37326). And that doesn't seem to be possible with the network_mode set to "host".

My docker-compose.yml currently looks like this:

version: '3.7'
services:
    qtcore:
        image: yansidorovtesseris/qtcore
        build: .
        container_name: qtcore
        depends_on:
            - node
        env_file: defaults.env
        ports:
            - "8000:8000"

    node:
        image: yansidorovtesseris/komodo
        container_name: node
        env_file: node.env
        ports:
            - "37326:37326"
            - "1900:1900"
        network_mode: host
        volumes:
            - $HOME/node_state:/komodo/.komodo/$AC_NAME

I've tried to use the sample from the docker-compose docs (https://docs.docker.com/compose/compose-file/#host-or-none) to connect the host network as an external network. With the thought to add both host and default networks to a service.

version: '3.7'
services:
    node:
        ...
        networks:
            hostnet: {}
        ...
networks:
    hostnet:
        external: true
        name: host

But all I get when I try to run the docker-compose is the following error: ERROR: for node network-scoped alias is supported only for containers in user defined networks

2 Answers

Alright, it seems to me that it's impossible to configure service to use both "host" and "bridge" options simultaneously. Would be glad if someone points out the opposite, though.
I've come up with a simple workaround to allow services to operate as a one docker-compose unit in a host LAN and yet use the "extra_hosts" (suggested by hNczy) for the hostname lookup.
It isn't ideal and might not fit for every scenario, but it does the trick for me.
Basically, two services are both using the "network_mode: host" right now, and the "extra_hosts" of a "qtcore" service is supplied with the "node" name bound to 127.0.0.1.

version: '3.7'
services:
    qtcore:
        image: yansidorovtesseris/qtcore
        build: .
        container_name: qtcore
        depends_on:
            - node
        env_file: defaults.env
        network_mode: host
        extra_hosts:
            - "node:127.0.0.1"
        ports:
            - "8000:8000"

    node:
        image: yansidorovtesseris/komodo
        container_name: node
        env_file: node.env
        ports:
            - "37326:37326"
            - "1900:1900"
        network_mode: host
        volumes:
            - $HOME/node_state:/komodo/.komodo/$AC_NAME

See https://docs.docker.com/network/host/, it says where you declare network mode = host then port mappings are ignored.

Solution: Use host.docker.internal:portNumber to use/connect to host ports from a container which is in bridged network mode/dafault mode.

version: '3.7'
services:
  qtcore:
    image: yansidorovtesseris/qtcore
    build: .
    container_name: qtcore
    env_file: defaults.env
    ports:
      - '8000:8000'
  node:
    image: yansidorovtesseris/komodo
    container_name: node
    env_file: node.env
    network_mode: host
    volumes:
      - '$HOME/node_state:/komodo/.komodo/$AC_NAME'

Now when in host mode komodo can use any ports which it is designed to work. Now in qtcore whenever you want to connect to host port use host.docker.internal. ex: host.docker.internal:37326 OR host.docker.internal:1900 , whatever port komodo is using. Never used komodo so can't write exact port.

Related