Compose: How to set static ip when using default network

Created on 16 Jul 2016  Â·  11Comments  Â·  Source: docker/compose

docker verion

Docker version 1.11.2, build b9f10c9

docker info

Containers: 5
 Running: 0
 Paused: 0
 Stopped: 5
Images: 12
Server Version: 1.11.2
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 52
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins: 
 Volume: local
 Network: host bridge null
Kernel Version: 4.4.0-21-generic
Operating System: Ubuntu 16.04 LTS
OSType: linux
Architecture: x86_64
CPUs: 1
Total Memory: 2.568 GiB
Name: ubuntu
ID: TH3M:2PEP:RVDP:45LA:2WVF:CFVT:NQOH:SMYN:GZG5:UNP2:LEUB:VGRB
Docker Root Dir: /var/lib/docker
Debug mode (client): false
Debug mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support

docker-compose version

docker-compose version 1.7.1, build 0a9ab35

my docker-compose.yml

version: '2'
services:
    nginx:
        image: nginx:latest
        ports:
            - "80:80"
        volumes:
            - xxx
        networks:
            default:
                ipv4_address: 192.168.0.7
networks:
    default:
        ipam:
            driver: default
            config:
                - subnet: 192.168.0.0/24
                  gateway: 192.168.0.1

I got this error when docker-compose up

ERROR: for nginx  User specified IP address is supported only when connecting to networks with user configured subnets
Traceback (most recent call last):
  File "<string>", line 3, in <module>
  File "compose/cli/main.py", line 63, in main
AttributeError: 'ProjectError' object has no attribute 'msg'
docker-compose returned -1

then I change the network "defualt“ to a custom name,it works.
I want to know if I could set static ip when using the default network,my English is not so good,thanks for any help.

Most helpful comment

This is so annoying. Thank God the problem has been solved by closing the ticket.

All 11 comments

Same question here, need to define static ip through docker-compose.yml with such configuration:

# docker network ls
NETWORK ID          NAME                DRIVER
315eba914429        bridge              bridge

# cat  docker-compose.yml
version: '2'                                                                                                                                                                                                                                                                   
services:                                                                                                                                                                                                                                                                      
  riemann:                                                                                                                                                                                                                                                                     
    build: .                                                                                                                                                                                                                                                                   
    ports:                                                                                                                                                                                                                                                                     
    - "5555:5555"                                                                                                                                                                                                                                                              
    - "5555:5555/udp"                                                                                                                                                                                                                                                          
    - "5556:5556"                                                                                                                                                                                                                                                              
    volumes:                                                                                                                                                                                                                                                                   
    - /etc/timezone:/etc/timezone:ro                                                                                                                                                                                                                                           
    - ./config:/etc/riemann                                                                                                                                                                                                                                                    
    networks:                                                                                                                                                                                                                                                                  
      bridge:                                                                                                                                                                                                                                                                  
        ipv4_address: 172.17.0.2                                                                                                                                                                                                                                               

networks:                                                                                                                                                                                                                                                                      
  bridge:                                                                                                                                                                                                                                                                      
    external: true

# docker-compose run --service-ports riemann 
ERROR: User specified IP address is supported on user defined networks only

So, now it's two ways:

  • define your custom network from docker-compose
  • configure static ip for container somewhere outside of compose (inside Dockerfile?)

If it'll be native compose solution, it'll be nice.

same here

I'm also experiencing this issue. Can't set static IPs with the default network.

+1 for this.

Specifically: If I use a custom network, then custom DNS entries aren't directly written to the container's /etc/resolv.conf, but are instead always used by the embedded DNS resolver. This isn't suitable for me; I want to route DNS requests over a VPN running in the container, and the embedded DNS resolver is bypassing this.

So I need to use the default bridge as a workaround. I can set a static IP with the default bridge with the normal docker cli, so it seems like I should be able to do this in compose.

I can set a static IP with the default bridge with the normal docker cli, so it seems like I should be able to do this in compose.

I do not think that is a correct assertion:

$ docker run --ip 172.17.0.124 busybox ls
docker: Error response from daemon: user specified IP address is supported on user defined networks only.
ERRO[0000] error waiting for container: context canceled

Closing as this is not something that can be fixed at the Compose level, but feel free to take this discussion over to the moby/moby repo.

This is so annoying. Thank God the problem has been solved by closing the ticket.

To anyone who might be having this problem:

docker-compose will create a network named after your project name (usually your folder, unless you specified COMPOSE_PROJECT_NAME) suffixed with _default. So if the project name is foo, the default network name will be foo_default. It will always be this unless you specify otherwise.

Once this network has been created, docker-compose will never remove it. This means you need to remove it yourself using docker.

$ docker network rm foo_default

Once you've done this, docker-compose will attempt to recreate your network. If you've specified some network options in your docker-compose.yml file, it will create the network with your new options.

version: '3.4'
networks:
  default:
    ipam:
      config:
        - subnet: 10.5.0.0/16

Hope this helps.

To anyone who might be having this problem:

docker-compose will create a network named after your project name (usually your folder, unless you specified COMPOSE_PROJECT_NAME) suffixed with _default. So if the project name is foo, the default network name will be foo_default. It will always be this unless you specify otherwise.

Once this network has been created, docker-compose will never remove it. This means you need to remove it yourself using docker.

$ docker network rm foo_default

Once you've done this, docker-compose will attempt to recreate your network. If you've specified some network options in your docker-compose.yml file, it will create the network with your new options.

version: '3.4'
networks:
  default:
    ipam:
      config:
        - subnet: 10.5.0.0/16

Hope this helps.

No it doesn't.

The networking stack in Linux is using the same layers that every other networking stack uses as well. So the main idea here is to have a bridge running that contains the main Ethernet interface as one of its members as well as the virtual interfaces of the containers that are created later on that main bridge.

As it is a layer two bridge, the containers are directly exposed to the main network and can either get their IP address from a local DHCP server, as broadcasting is possible, or they just get assigned a static IP address from the address range of the local network and just use that particular address.

So far the theory.

All virtualization environments actually support this modus operandi because it's the easiest and simplest setup there is. The main host doesn't have to take care of anything and it just works.

Now docker, instead of using the same setup, has to create bridges with no real interface, add virtual interfaces of the containers to said bridges and then mess around with layer 3 routing, network filtering and NAT just to make it happen so that a container is actually able to access the outside world when it is not running with the host's IP address.

If you don‘t go with the NAT option and just use the routing approach, what you have to do when you want access from the outside to the container, you have to reconfigure your complete network environment to let each and every device in it know that the next hop to the docker subnet is on a different machine than the main router. And no, nobody really wants to rely on ICMP redirects.

Another option would be to use a very special setup called brouting. But that creates a lot of other complications that nobody really wants. For example you would have to reserve a subnet from the existing subnet to actually make the brouting happen. DHCP from the local DHCP server is not working and all kinds of broadcasting stuff can only start working with a lot of layer 3/iptables trickery. All much to complicated. Hence the layer 2 bridge approach…

So just by looking at the fact that this thing has come up here multiple times over and over again and the tickets just have been closed shows me that there are people that need a rendezvous with reality to understand that the default modus operandi in datacenters is actually the bridging approach described above.

I understand that there are use cases where a rather complicated network scenario, like the one that docker uses, is actually necessary, but looking at reality I’m quite certain that the bridging approach would be the best way to handle this. And as it seems it’s not just me.

IMHO this reminds me a lot of the way web developers rather reinvent the wheel in a complicated and messed up way than just using the existing technology to make it all happen.

Anyway, glad we talked about it.

$0.02

This is so frustrating i have multiple static ipv4 and i wish to put them to use for every specific docker image that i put online not some bootleg automated private network that docker automatically creates

Have you tried this? Had some issues with 2 others going in first on bridge.

ServerIP

Docker-Compose

version: "2.0"
services:
   conatiner:
    image: image
    container_name: container
    network_mode: bridge
    restart: always
    ports:
      - 980:80/tcp
    volumes:
      - /docker/container:/container/location
    environment:
      TZ: America/New_York
      DNS1: 172.16.0.2#53
      ServerIP: 172.17.0.2
Was this page helpful?
0 / 5 - 0 ratings