Is there a way to assign a static IP address to a container attached to a system bridge interface?

Since docker doesn’t really support nftables, I have to change the current configuration of my containers and set the network manually. Most of the work is already done, but I can’t really figure out how to force containers to use static IP addresses.

What I’ve done so far is the following:

I created a bridge interface manually using /etc/network/interfaces file:

auto br-docker
iface br-docker inet static
	bridge_bridgeprio 20
	address 172.20.0.1
	netmask 255.255.255.0
	bridge_ports none
	bridge_waitport 0

The bridge works fine:

# brctl show
bridge name     bridge id               STP enabled     interfaces
br-docker               0014.000000000000       no

# ip addr show dev br-docker
54: br-docker: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 172.20.0.1/24 brd 172.20.0.255 scope global br-docker
       valid_lft forever preferred_lft forever
    inet6 fe80::9c0a:30ff:febd:6979/64 scope link
       valid_lft forever preferred_lft forever

Then I added the following options to the /etc/docker/daemon.json file:

{
	"ipv6": false,
	"iptables": false,
	"ip-forward": false,
	"ip-masq": false,
	"bridge": "br-docker",
}

And in the docker-compose.yml file, I added the following lines to each container block (only this was working well):

 network_mode:
   bridge

I know that I have to set the netfiler rules manually, but for now just leave this aside.

When I issue docker-compose up, I can see that everything was set up correctly so far:

# brctl show
bridge name     bridge id               STP enabled     interfaces
br-docker               0014.1eb34868da58       no     veth8b7e600
                                                                               vethadc8e76
                                                                               vethccd04cb

So all the containers are attached to the system bridge I created earlier. But when I restart the containers, I get different IPs:

$ docker network inspect bridge | grep IPv4
                "IPv4Address": "172.20.0.4/24",
                "IPv4Address": "172.20.0.3/24",
                "IPv4Address": "172.20.0.2/24",

So basically the IPs are assigned randomly, and I have no idea how to fix that, so each container had its own IP that wouldn’t change. Is there a way to do that?

It looks like the following:

 network_mode:
   bridge

breaks some things.

I had to use

 networks:
   default:
     ipv4_address: 172.20.1.2
...
networks:
  default:
    ipam:
      config:
        - subnet: 172.20.1.0/24

instead. But this creates another bridge interface and attaches containers’ interfaces to it:

# brctl show
bridge name     bridge id               STP enabled     interfaces
br-204898c19ab4         8000.0242aa162f2f       no              veth9ecb17c
                                                        vethd979ed1
                                                        vethfd5f0db
br-docker               0014.000000000000       no

So how to combine them info one?

I realise it’s a year since you last posted, but I’ve run into the same need and problem as you and not found a solution yet. Did you ever find a stable fix?

I’ve been trying to figure out a fix for this for a while now and haven’t been able to do it either.

Hello,

You can advice the Docker Intern DHCP to give only 1 IP address to the client. maybe this can help you.