[BUG] mac_address is not assigned with external networks
Description
I'm checking the assignment of mac addresses in external networks on docker-compose version 2.22.0. I'm testing on the following docker-compose file
version: '3.7'
services:
busybox:
image: busybox:latest
mac_address: "ce:9f:32:e5:92:f4"
command: sleep 600
networks:
- test
networks:
test:
external: true
name: "test"
After up container, i check mac address into container and got different address
% docker-compose version
Docker Compose version v2.22.0
% docker exec $(docker ps -aq --filter "name=busybox") ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
23: eth0@if24: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:13:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0
valid_lft forever preferred_lft forever
If run container it on a docker-compose 2.18.1, then the address is correct
% docker-compose version
Docker Compose version v2.18.1
% docker exec $(docker ps -aq --filter "name=busybox") ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
25: eth0@if26: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether ce:9f:32:e5:92:f4 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0
valid_lft forever preferred_lft forever
Steps To Reproduce
- Create docker-compose.yml file
version: '3.7'
services:
busybox:
image: busybox:latest
mac_address: "ce:9f:32:e5:92:f4"
command: sleep 600
networks:
- test
networks:
test:
external: true
name: "test"
- Create network
docker network create test
- Run docker-compose up on version v2.22.0
docker-compose up -d
- check mac address into container
docker exec $(docker ps -aq --filter "name=busybox") ip a
- mac address will be ce:9f:32:e5:92:f4
Compose Version
% docker compose version
Docker Compose version v2.22.0
% docker-compose version
Docker Compose version v2.22.0
### Docker Environment
```Text
% docker info
Client:
Context: default
Debug Mode: false
Plugins:
compose: Docker Compose (Docker Inc., v2.22.0)
Server:
Containers: 2
Running: 0
Paused: 0
Stopped: 2
Images: 634
Server Version: 20.10.21
Storage Driver: overlay2
Backing Filesystem: xfs
Supports d_type: true
Native Overlay Diff: false
userxattr: false
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 2
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
Default Runtime: runc
Init Binary: docker-init
containerd version: a05d175400b1145e5e6a735a6710579d181e7fb0.m
runc version:
init version: de40ad0
Security Options:
seccomp
Profile: default
cgroupns
Kernel Version: 6.0.12-arch1-1
Operating System: Arch Linux
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 31GiB
Name: mad-arch
ID: Q3FJ:BR5P:FNEQ:ARCZ:DFIB:C4GS:RTQC:J4IO:G7TR:I67L:LFFU:VWEA
Docker Root Dir: /home/lib/docker
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: true
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
### Anything else?
_No response_
I wonder this is a duplicate for https://github.com/docker/compose/issues/10796
can you please attach docker inspect network test output so I can check if this specific network has settings which might explain this issue ?
% docker inspect test
[
{
"Name": "test",
"Id": "9061d0c818abb467e9021e6b8fcba1fb6a1f7504f58fda25982b7dfc598d6a18",
"Created": "2023-09-25T14:22:22.798163165+03:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
probably fixed by https://github.com/moby/moby/pull/46406, can you try reproducing running latest moby codebase (can use docker in docker for this purpose) ?
I understood correctly that I need to try running Docker with the latest version?
% docker run --privileged -d -v "$(pwd)/test-mac-address":/app docker:latest
Unable to find image 'docker:latest' locally
latest: Pulling from library/docker
Digest: sha256:264858d91f4d9f588c6039d165d4274dc61f5604a5a65c5910aea870496f27d3
Status: Downloaded newer image for docker:latest
2a50c53c6af34f9d29b48fb4ef4741d9fbeb61d6114b51632e9cb7a7404c55a9
% docker exec -it 2a50c53c6af34f9d29b48fb4ef4741d9fbeb61d6114b51632e9cb7a7404c55a9 sh
Check versions
/app # docker version
Client:
Version: 24.0.6
API version: 1.43
Go version: go1.20.7
Git commit: ed223bc
Built: Mon Sep 4 12:30:51 2023
OS/Arch: linux/amd64
Context: default
Server: Docker Engine - Community
Engine:
Version: 24.0.6
API version: 1.43 (minimum version 1.12)
Go version: go1.20.7
Git commit: 1a79695
Built: Mon Sep 4 12:32:17 2023
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.7.3
GitCommit: 7880925980b188f4c97b462f709d0db8e8962aff
runc:
Version: 1.1.9
GitCommit: v1.1.9-0-gccaecfc
docker-init:
Version: 0.19.0
GitCommit: de40ad0
/app # docker compose version
Docker Compose version v2.22.0
Create network
/app # docker network create test
f0558965afb272f515618fdd83361bdd29f539efc4f6d90d2a933bc60601ff53
/app # docker inspect test
[
{
"Name": "test",
"Id": "f0558965afb272f515618fdd83361bdd29f539efc4f6d90d2a933bc60601ff53",
"Created": "2023-09-28T11:16:08.392158767Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"07cc2c2677e0424adbd453abb54f4e6f2a8ff1568d2db2453600aa24aca7fbb7": {
"Name": "app-busybox-1",
"EndpointID": "70ef529161de5334d65d527f981d11fb4be011a68a85ccd682e98818a53db8f1",
"MacAddress": "02:42:ac:13:00:02",
"IPv4Address": "172.19.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
Run container
# docker compose up -d
[+] Building 0.0s (0/0) docker:default
[+] Running 1/1
✔ Container app-busybox-1 Started
/app # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
07cc2c2677e0 busybox:latest "sleep 600" 20 seconds ago Up 18 seconds app-busybox-1
/app # docker exec app-busybox-1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
4: eth0@if5: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue
link/ether 02:42:ac:13:00:02 brd ff:ff:ff:ff:ff:ff
inet 172.19.0.2/16 brd 172.19.255.255 scope global eth0
valid_lft forever preferred_lft forever
Mac addresses are different
fix is not yet available in a released version, you have to run moby from sources (https://github.com/moby/moby, use make run)
This issue has brought my house to its knees everything in my setup depends on static MACs :(
git clone https://github.com/moby/moby.git
cd moby
make run
make: *** [Makefile:194: build] Error 125
Needed docker-buildx however it didn't seem to build docker-compose and failed to install itself as it couldn't find the directory in it's build folder but seem to only compile dockerd and docker-proxy.
Not sure if the separate docker-compose branch has the fix but it didn't seem to help after compiling it and running it.
Edit: worked after replacing dockerd with the moby compiled one. (dockerd has docker compose built into it)
git clone https://github.com/moby/moby.git
cd moby
docker buildx bake
whereis dockerd
dockerd: /usr/bin/dockerd /usr/share/man/man8/dockerd.8.gz
/usr/bin/dockerd --version
Docker version 25.0.2, build fce6e0ca9b
sudo systemctl stop docker
sudo cp bundles/binary/dockerd /usr/bin/
sudo systemctl start docker
/usr/bin/dockerd --version
Docker version dev, build HEAD
Moby since v25 no longer seems to work with this! They seem to have changed mac_address to be under the network service.
https://docs.docker.com/compose/compose-file/05-services/#mac_address-1
mac_address
Available with Docker Compose version 2.24.0 and later.
mac_address sets a MAC address for the service container.
Note Container runtimes might reject this value (ie. Docker Engine >= v25.0). In that case, you should use networks.mac_address instead.
docker version
Client:
Version: 25.0.2
API version: 1.44
Go version: go1.21.6
Git commit: 29cf629222
Built: Thu Feb 1 10:50:44 2024
OS/Arch: linux/amd64
Context: default
Server:
Engine:
Version: dev
API version: 1.45 (minimum version 1.24)
Go version: go1.21.7
Git commit: HEAD
Built: Wed Feb 28 00:02:42 2024
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.7.13
GitCommit: 7c3aca7a610df76212171d200ca3811ff6096eb8.m
runc:
Version: 1.1.12
GitCommit:
docker-init:
Version: 0.19.0
GitCommit: de40ad0
# Portainer Container for Docker
version: '3.9'
services:
portainer:
container_name: portainer
hostname: portainer
#image: portainer/portainer-ce:latest
image: portainerci/portainer:2.20
restart: 'no'
labels:
- "com.centurylinklabs.watchtower.enable=true"
#restart: unless-stopped
security_opt:
- no-new-privileges:true
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /var/lib/libvirt/images/sas/docker-storage/portainer/portainer-data:/data
ports:
- "8000:8000"
- "9443:9443"
mac_address: de:ad:be:ef:00:01 # Ignores that you set it. Gives you random MAC address. Doesn't complain.
networks:
- dhcp
networks:
dhcp:
name: dbrv100
external: true
#mac_address: de:ad:be:ef:00:01 #ERROR: networks.dhcp Additional property mac_address is not allowed
since v25 you can declare mac_address per network config (https://github.com/compose-spec/compose-spec/blob/master/05-services.md#mac_address).
Do you see my example above it does not work when you add external: true
Someone should put an example here https://github.com/compose-spec/compose-spec/blob/master/05-services.md#mac_address of how to layer in YAML the mac_address.
I tested this which works, the MAC address gets applied:
version: '3.8'
services:
nginx:
image: nginx:latest
networks:
default:
mac_address: de:ad:be:ef:99:01
Soon as you add external: true like this it fails shown above and below:
version: '3.8'
services:
nginx:
image: nginx:latest
networks:
- dhcp
networks:
dhcp:
name: dbrv100
external: true
mac_address: de:ad:be:ef:00:01
ERROR: networks.dhcp Additional property mac_address is not allowed
@NonaSuomy mac_address attribute applies to service's networks (which define how a service connects to a network), not the top-level element
(which is used to define a network, with multiple connected services)
How do I apply a mac address to this external network container?
Can you show me how to correct this yaml for the container to get a static mac address and be on the external network? I don't get what I should do to make it work properly?
version: '3.8'
services:
nginx:
image: nginx:latest
networks:
- dhcp
networks:
dhcp:
name: dbrv100
external: true
mac_address: de:ad:be:ef:00:01
Maybe like this I guess?
version: '3.8'
services:
nginx:
image: nginx:latest
networks:
dhcp:
mac_address: de:ad:be:ef:00:01
networks:
dhcp:
name: dbrv100
external: true
Looks like it is working now yay!
"Networks": {
"dbrv100": {
"IPAMConfig": {},
"Links": null,
"Aliases": [
"mactest-nginx-1",
"nginx",
"############"
],
"MacAddress": "de:ad:be:ef:00:01",
"NetworkID": "0b...",
"EndpointID": "75...",
"Gateway": "10.0.42.1",
"IPAddress": "10.0.42.121",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"DriverOpts": null,
"DNSNames": [
"mactest-nginx-1",
"nginx",
"############"
]
}
}