204

I'm trying to provide static IP address to containers. I understand that I have to create a custom network. I create it and the bridge interface is up on the host machine (Ubuntu 16.x). The containers get IP from this subnet but not the static I provided.

Here is my docker-compose.yml:

version: '2'

services:
  mysql:
    container_name: mysql
    image: mysql:latest
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=root
    ports:
     - "3306:3306"
    networks:
     - vpcbr

  apigw-tomcat:
    container_name: apigw-tomcat
    build: tomcat/.
    ports:
     - "8080:8080"
     - "8009:8009"
    networks:
     - vpcbr
    depends_on:
     - mysql

networks:
  vpcbr:
    driver: bridge
    ipam:
     config:
       - subnet: 10.5.0.0/16
         gateway: 10.5.0.1
         aux_addresses:
          mysql: 10.5.0.5
          apigw-tomcat: 10.5.0.6

The containers get 10.5.0.2 and 10.5.0.3, instead of 5 and 6.

2
  • aux-address is used to manually inform the ipam-driver about IP addresses already in use in the network Commented Feb 21, 2020 at 16:42
  • How can i scale up either of these containers using 'docker compose up -d --scale container-name=3' when i have allocated a static ip to the service? Commented Apr 3, 2020 at 12:30

6 Answers 6

237

Note that I don't recommend a fixed IP for containers in Docker unless you're doing something that allows routing from outside to the inside of your container network (e.g. macvlan). DNS is already there for service discovery inside of the container network and supports container scaling. And outside the container network, you should use exposed ports on the host. With that disclaimer, here's the compose file you want:

version: '2'

services:
  mysql:
    container_name: mysql
    image: mysql:latest
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=root
    ports:
     - "3306:3306"
    networks:
      vpcbr:
        ipv4_address: 10.5.0.5

  apigw-tomcat:
    container_name: apigw-tomcat
    build: tomcat/.
    ports:
     - "8080:8080"
     - "8009:8009"
    networks:
      vpcbr:
        ipv4_address: 10.5.0.6
    depends_on:
     - mysql

networks:
  vpcbr:
    driver: bridge
    ipam:
     config:
       - subnet: 10.5.0.0/16
         gateway: 10.5.0.1
Sign up to request clarification or add additional context in comments.

15 Comments

How can you do it in version 3?
@Atr_Max At the moment, you cannot: "Note: Additional IPAM configurations, such as gateway, are only honored for version 2 at the moment." docs.docker.com/compose/compose-file/#ipam
@BMitch why do you recommend against static IPs? Is it a good idea for security for Redis, as assumed here? github.com/laradock/laradock/issues/986#issuecomment-404596974 Thanks so much.
@Ryan Static IP's won't improve security, you still need to open the same connections, and your containers will still run inside of a namespaced network where you only expose what you need. Static IP's will decrease flexibility, including the ability to do a rolling update of your application, not work in swarm mode, and make the container's configuration harder to copy between environments or similar containers. For the linked issue, you just need to listen on 0.0.0.0 inside the container.
@alvery I have the same issue, you need to use --force-recreate option because docker-compose doesn't apply config on already created network ( maybe a bug )
|
42

I was facing some difficulties with an environment variable that is with custom name (not with container name /port convention for KAPACITOR_BASE_URL and KAPACITOR_ALERTS_ENDPOINT). If we give service name in this case it wouldn't resolve the ip as

KAPACITOR_BASE_URL:  http://kapacitor:9092

In above http://[**kapacitor**]:9092 would not resolve to http://172.20.0.2:9092

I resolved the static IPs issues using subnetting configurations.

version: "3.3"

networks:
  frontend:
    ipam:
      config:
        - subnet: 172.20.0.0/24
services:
    db:
        image: postgres:9.4.4
        networks:
            frontend:
                ipv4_address: 172.20.0.5
        ports:
            - "5432:5432"
        volumes:
            - postgres_data:/var/lib/postgresql/data

    redis:
        image: redis:latest
        networks:
            frontend:
                ipv4_address: 172.20.0.6
        ports:
            - "6379"

    influxdb:
        image: influxdb:latest
        ports:
            - "8086:8086"
            - "8083:8083"
        volumes:
            - ../influxdb/influxdb.conf:/etc/influxdb/influxdb.conf
            - ../influxdb/inxdb:/var/lib/influxdb
        networks:
            frontend:
                ipv4_address: 172.20.0.4
        environment:
          INFLUXDB_HTTP_AUTH_ENABLED: "false"
          INFLUXDB_ADMIN_ENABLED: "true"
          INFLUXDB_USERNAME: "db_username"
          INFLUXDB_PASSWORD: "12345678"
          INFLUXDB_DB: db_customers

    kapacitor:
        image: kapacitor:latest
        ports: 
            - "9092:9092"
        networks:
            frontend:
                ipv4_address: 172.20.0.2
        depends_on:
            - influxdb
        volumes:
            - ../kapacitor/kapacitor.conf:/etc/kapacitor/kapacitor.conf
            - ../kapacitor/kapdb:/var/lib/kapacitor
        environment:
          KAPACITOR_INFLUXDB_0_URLS_0: http://influxdb:8086

    web:
        build: .
        environment:
          RAILS_ENV: $RAILS_ENV
        command: bundle exec rails s -b 0.0.0.0
        ports:
            - "3000:3000"
        networks:
            frontend:
                ipv4_address: 172.20.0.3
        links:
            - db
            - kapacitor
        depends_on:
            - db
        volumes:
            - .:/var/app/current
        environment:
          DATABASE_URL: postgres://postgres@db
          DATABASE_USERNAME: postgres
          DATABASE_PASSWORD: postgres
          INFLUX_URL: http://influxdb:8086
          INFLUX_USER: db_username
          INFLUX_PWD: 12345678
          KAPACITOR_BASE_URL:  http://172.20.0.2:9092
          KAPACITOR_ALERTS_ENDPOINT: http://172.20.0.3:3000

volumes:
  postgres_data:

Comments

25

If you are never seeing the static IP address set, perhaps it could be because you are using "docker compose up". Try using "docker-compose up".

When I use "docker-compose up" (with the hyphen) I now see the static IPs assigned.

networks:
  hfnet:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 192.168.55.0/24
          gateway: 192.168.55.1

services:
  web:
    image: 'mycompany/webserver:latest'
    hostname: www
    domainname: mycompany.com
    stdin_open: true # docker run -i
    tty: true        # docker run -t
    networks:
      hfnet:
        ipv4_address: 192.168.55.10
    ports:
      - '80:80'
      - '443:443'
    volumes:
      - '../honeyfund:/var/www/html'

I wasted a lot of time to figure that one out. :(

4 Comments

This answer just solved an issue I was dealing with for over a week! 🙏🏽
This works for me. I think you have a typo in your yaml. Shouldn't it be mynet instead of hfnet?
@JackLeEmmerdeur this is a random string. You can call it whatever you want. This is then used in the name of the network
@BonisTech My comment was valid before larsks corrected the answer. Take a look at their edit from Aug 3.
3

I realized, that the more convenient and meaningful way is to give the container a container-name. You can use the name in the same docker network as source. This helped me because the docker-containers had changing IPs and by this I can communicate with another container with a static name that I can use in config-files.

Comments

0

If you want to configure a default network in docker compose do it like that:

networks:
  default: # here we set the network name
    driver: bridge
    ipam:
      driver: default
      config:
      - subnet:  10.103.0.1/16

Comments

0

I achieve it by using ipvlan docker network.

  1. Create a docker ipvlan network, in this sample with the name lan and with the same configuration of the host physical connection eth0 nic, and is importan to set this two options:

    ipvlan_mode=l2
    parent=eth0
    

    FYI: https://docs.docker.com/engine/network/drivers/ipvlan/

  2. Then in my case via docker composer set the container to the created network and the ip you want to set.

...
    networks:
      lan:
        ipv4_address: 192.168.1.7

networks:
  lan:
    external: true
  1. Start the container and called by the IP 192.168.1.7, then enjoy it!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.