[rootless] Compose ignoring cap add NET_ADMIN while docker run works

Hi, I am running rootless docker on Arch 6.4.2-arch1-1.

Docker version 24.0.4, build 3713ee1
Docker Compose version v2.19.1

I have a compose file with

cap_add:
      - NET_ADMIN

and is using Alpine, the Dockerfile is as follow:

FROM alpine:latest

RUN apk update && apk upgrade && apk add curl iptables
RUN ipables -L

Throws the error:

iptables v1.8.9 (legacy): can't initialize iptables table filter’: Permission denied (you must be root)`

I tried to print the capabilities and this is the result:

0.690 Current: cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys_chro
ot,cap_mknod,cap_audit_write,cap_setfcap=ep
0.691 Bounding set =cap_chown,cap_dac_override,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_net_bind_service,cap_net_raw,cap_sys
_chroot,cap_mknod,cap_audit_write,cap_setfcap

0.691 Current IAB: !cap_dac_read_search,!cap_linux_immutable,!cap_net_broadcast,!cap_net_admin,!cap_ipc_lock,!cap_ipc_owner,!cap_sys_module,!cap_sys_raw
io,!cap_sys_ptrace,!cap_sys_pacct,!cap_sys_admin,!cap_sys_boot,!cap_sys_nice,!cap_sys_resource,!cap_sys_time,!cap_sys_tty_config,!cap_lease,!cap_audit_c
ontrol,!cap_mac_override,!cap_mac_admin,!cap_syslog,!cap_wake_alarm,!cap_block_suspend,!cap_audit_read,!cap_perfmon,!cap_bpf,!cap_checkpoint_restore

indicating the lack of NET_ADMIN

if I redo the same but with “docker run” as in:

docker run --rm --cap-add NET_ADMIN -it alpine sh
works without problem (the NET_ADMIN is inserted correctly)

apk add -U iptables && iptables -L
fetch https://dl-cdn.alpinelinux.org/alpine/v3.18/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.18/community/x86_64/APKINDEX.tar.gz
(1/3) Installing libmnl (1.0.5-r1)
(2/3) Installing libnftnl (1.2.5-r1)
(3/3) Installing iptables (1.8.9-r2)
Executing busybox-1.36.1-r0.trigger
OK: 10 MiB in 21 packages
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Any help? Seems like the compose works differently and ignores the CAP_ADD ?

Thanks in advance

Rootless docker is rootless for a reason. Your user will not have permision to manage networks so your Docker will not have the permission either. NET_ADMIN should not changed that (but I can be wrong). Are you sure you used the same rootless Docker when you ran the docker run command and didn’t change the docker context to the rootful Docker?

docker context ls

Yes I am sure, I am running rootless docker on the machine.
The output from the command you mentioned proves the same.

I am still not understanding why the docker run (with the cap add flag) works while the same with docker-compose doesnt.

Just to be clear: you are referring to a problem during image build using docker compose, right?

At least that’s what would make sense, since docker build doesn’t have an argument to set capabilities during build. The compose specification doesn’t specify any configuration element underneath the service build element. The cap_add definition in a service configuration is not used for builds.

Though, if it’s just about running containers, docker run --cap-add and cap_add in a compose file service configuration should have the same result.

1 Like

I don’t know why I didn’t take it into account that you wrote about docker build and docker run. I guess I focused on the permissions and how a non-root user could have netadmin permission without testing it on my machine. Now I think it is what @meyay suggested.