skip to Main Content

Consider a part of some base docker-compose.yml file:

services:
  foo:
    image: bar
    network_mode: host
.
.
.

Then, consider a docker-compose.prod.yml file which would override the base file’s network mode and also set ports:

services:
  foo:
    ports:
      - 'xxxx:yyyy'
    network_mode: ?

I am looking for a value of ? such that the network_mode is considered unset. In other words, setting it to none or bridge doesn’t seem to work, so I want it to just disappear, or use a value with such an effect (I don’t think there is a default).

An alternative solution to this problem is to define three docker-compose files: docker-compose.yml, docker-compose.prod.yml, and docker-compose.dev.yml (or something equivalent, doesn’t matter). It works fine (see below), but I would rather have 2 files only, and override the dev file with the prod file, rather than the other way around (it feels more natural this way).

A working version using three files:

docker-compose.yml

services:
  foo:
    image: bar
.
.
.

docker-compose.dev.yml

services:
  foo:
    network_mode: host

docker-compose.prod.yml

services:
  foo:
    ports:
      - 'xxxx:yyyy'

Notes:

  • All files are using docker-compose version 3.
  • The specific setup which doesn’t work with bridge network mode in my case is a collection of three services – one for running web stuff (exposed to public), one for celery workers (internal), and one for Redis (internal). Using bridge in web and/or celery results in being unable to connect to the Redis service.

2

Answers


  1. I don’t know how to remove a option from former docker-compose.yaml, but the bridge really works, you may want to have a double confirm.

    If we have a look for docker default network, you could see bridge really there, if we do not set --net, default docker will use bridge:

    $ docker network ls
    NETWORK ID          NAME                     DRIVER              SCOPE
    32a9a31082ae        bridge                   bridge              local
    dcb12f4cc711        host                     host                local
    16c73acab8c9        none                     null                local
    

    I give a small example to prove it:

    docker-compose.yaml:

    version: "3"
    
    services:
      web:
        image: python:3.7
        network_mode: host
        command: python -m http.server 9000
    

    docker-compose.prod.yaml:

    version: "3"
    
    services:
      web:
        ports:
        - 10000:9000
        network_mode: bridge
    
    • docker-compose up

      With this command, we will in fact just use docker-compose.yaml, at that time, if we open browser we can see could successfully visit e.g.: http://$ip:9000, this is because the network is host.

    • docker-compose -f docker-compose.yaml -f docker-compose.prod.yaml up

      With this command, we will use 2 compose files, the latter one will override the duplicate option in the former one.

      If you open browser, you will find you can’t visit http://$ip/9000 now, you could just visit http://$ip/10000. This can prove that host loss effect, and the bridge override host successfully.

      (NOTE: you will have to assure docker-compose.prod.yaml after docker-compose.yaml, the sequence order is important.)

    UPDATE 20211017 based on your new comments:

    If you want to addtional visit other container in your compose, you will have to define network_mode in that target service to use the same network of source service with network_mode: service:web, see network mode:

    docker-compose.yaml:

    version: "3"
    
    services:
      web:
        image: python:3.7-alpine3.13
        command: python -m http.server 9000
        network_mode: host
    
      db:
        image: python:3.7-alpine3.13
        command: python -m http.server 8000
        network_mode: service:web
    

    docker-compose.yaml:

    version: "3"
    
    services:
      web:
        ports:
        - 10000:9000
        network_mode: bridge
    

    Then, after up, you could use something like next to directly visit the service in db:

    docker-compose exec web wget http://localhost:8000 -O -
    

    NOTE:

    • with network_mode: bridge in web, the web container nolonger use the default network which compose set up for you. As a result, you won’t benifit from the auto dns setup by compose, which means in web you won’t be able to access db container using the service name db.
    • to conquer this issue, you now could let db container use the network of web explicitly with network_mode: service:web. This means the 2 containers now share the same network namespace, then you no need to visit db with service name, but to use localhost. In web, you now could access db‘s 8000 port just with http://localhost:8000.
    Login or Signup to reply.
  2. TL;DR

    docker-compose.prod.yml

    services:
        foo:
            network_mode: unset    # Can be any string other than 'host'.
            networks: [ default ]
            
            ports: [ 80:80 ]
    

    Docker Compose Default Network

    This is the default behavior: if there’s no networks: and no network_mode: defined for the service then it’s attached to the default network.

    Unfortunately an empty string is ignored by the YAML parser, so we can’t override network_mode: back to '', what we can do is set networks: [ default ], but that won’t work with network_mode: host so what can we set network_mode: to?

    network_mode: is equivalent to Docker --network, if we set it to a network name networks: will override it, so we can use any value other than host which apparently triggers some special behavior. It’s probably a good idea to set it to something that will fail without networks: and avoid default, bridge or none.

    To restore the default behavior we need to add default to networks: and set network_mode: to something other than host.


    Note that network_mode: default is equivalent to --network default or --network bridge which uses the default Docker network: bridge, and not the default project-wide Compose network: projectName_default.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search