Detect case when port forwarding is used together with uid/gid mapping on Podman 3.4.x and issue warning
Describe the bug
I'm using podman-compose to deploy a simple app, but after the uid/gid mapping is set, the port forwarding is not working.
To Reproduce
The Dockerfile
FROM alpine:3.20
ARG NEW_UID=2000
ARG NEW_GID=2000
RUN set -eufxo pipefail && \
apk add --no-cache curl darkhttpd iproute2-ss && \
addgroup -g $NEW_GID nonroot && \
adduser -D -s /bin/sh -u $NEW_UID -G nonroot nonroot
USER nonroot
WORKDIR /home/nonroot
docker-compose.yaml
version: '3.7'
services:
app:
image: local/podman-compose-uid-gid-maps-port-fwd-not-working
build:
context: .
restart: "unless-stopped"
user: "2000:2000"
x-podman:
uidmaps:
- "0:1:2000"
- "2000:0:1"
- "2001:2001:63536"
gidmaps:
- "0:1:2000"
- "2000:0:1"
- "2001:2001:63536"
ports:
- 127.0.0.1:30020:8080/tcp
#command: sleep infinity
command: darkhttpd /etc --no-listing
networks:
net:
driver: bridge
ipam:
driver: default
Run
$ podman image rm local/podman-compose-uid-gid-maps-port-fwd-not-working || true
Error: local/podman-compose-uid-gid-maps-port-fwd-not-working: image not known
$ podman-compose version
podman-compose version: 1.0.7
['podman', '--version', '']
using podman version: 3.4.4
podman-compose version 1.0.7
podman --version
podman version 3.4.4
exit code: 0
$ podman-compose up
podman-compose version: 1.0.7
['podman', '--version', '']
using podman version: 3.4.4
** excluding: set()
['podman', 'inspect', '-t', 'image', '-f', '{{.Id}}', 'local/podman-compose-uid-gid-maps-port-fwd-not-working']
Error: error inspecting object: local/podman-compose-uid-gid-maps-port-fwd-not-working: image not known
podman build -f ./Dockerfile -t local/podman-compose-uid-gid-maps-port-fwd-not-working .
STEP 1/6: FROM alpine:3.20
STEP 2/6: ARG NEW_UID=2000
--> Using cache e03b56a5afc3faf786d227ba9baf869f66093c71da6a3abeb98068f7ddede06d
--> e03b56a5afc
STEP 3/6: ARG NEW_GID=2000
--> Using cache 7b12ebd82edc93140a88d04ec770c3c4f84ddad7070cd062f590edc11ceb23d8
--> 7b12ebd82ed
STEP 4/6: RUN set -eufxo pipefail && apk add --no-cache curl darkhttpd iproute2-ss && addgroup -g $NEW_GID nonroot && adduser -D -s /bin/sh -u $NEW_UID -G nonroot nonroot
+ apk add --no-cache curl darkhttpd iproute2-ss
fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/community/x86_64/APKINDEX.tar.gz
(1/14) Installing ca-certificates (20240226-r0)
(2/14) Installing brotli-libs (1.1.0-r2)
(3/14) Installing c-ares (1.28.1-r0)
(4/14) Installing libunistring (1.2-r0)
(5/14) Installing libidn2 (2.3.7-r0)
(6/14) Installing nghttp2-libs (1.62.1-r0)
(7/14) Installing libpsl (0.21.5-r1)
(8/14) Installing zstd-libs (1.5.6-r0)
(9/14) Installing libcurl (8.8.0-r0)
(10/14) Installing curl (8.8.0-r0)
(11/14) Installing darkhttpd (1.16-r0)
Executing darkhttpd-1.16-r0.pre-install
(12/14) Installing libcap2 (2.70-r0)
(13/14) Installing libmnl (1.0.5-r2)
(14/14) Installing iproute2-ss (6.9.0-r0)
Executing busybox-1.36.1-r29.trigger
Executing ca-certificates-20240226-r0.trigger
OK: 13 MiB in 28 packages
+ addgroup -g 2000 nonroot
+ adduser -D -s /bin/sh -u 2000 -G nonroot nonroot
--> f63d4c78b90
STEP 5/6: USER nonroot
--> bf49beaf33f
STEP 6/6: WORKDIR /home/nonroot
COMMIT local/podman-compose-uid-gid-maps-port-fwd-not-working
--> c9798460761
Successfully tagged localhost/local/podman-compose-uid-gid-maps-port-fwd-not-working:latest
c979846076162ecde05a2d2754239366165a61ab26896c89fb5a857d8e664dbd
exit code: 0
['podman', 'ps', '--filter', 'label=io.podman.compose.project=podman-compose-uid-gid-maps-port-fwd-not-working', '-a', '--format', '{{ index .Labels "io.podman.compose.config-hash"}}']
podman pod create --name=pod_podman-compose-uid-gid-maps-port-fwd-not-working --infra=false --share=
2b58a56e13dab971372d1dce70922429981fd290485005cb37d32eb2225aca0c
exit code: 0
['podman', 'network', 'exists', 'podman-compose-uid-gid-maps-port-fwd-not-working_net']
podman create --name=podman-compose-uid-gid-maps-port-fwd-not-working_app_1 --pod=pod_podman-compose-uid-gid-maps-port-fwd-not-working --label io.podman.compose.config-hash=a4c59dd80db8e11022c65068660294de4ee02f7625030caa95f198af53bd56b9 --label io.podman.compose.project=podman-compose-uid-gid-maps-port-fwd-not-working --label io.podman.compose.version=1.0.7 --label PODMAN_SYSTEMD_UNIT=podman-compose@podman-compose-uid-gid-maps-port-fwd-not-working.service --label com.docker.compose.project=podman-compose-uid-gid-maps-port-fwd-not-working --label com.docker.compose.project.working_dir=/tmp/podman-compose-uid-gid-maps-port-fwd-not-working --label com.docker.compose.project.config_files=docker-compose.yaml --label com.docker.compose.container-number=1 --label com.docker.compose.service=app --net podman-compose-uid-gid-maps-port-fwd-not-working_net --network-alias app -p 127.0.0.1:30020:8080/tcp -u 2000:2000 --restart unless-stopped --uidmap 0:1:2000 --uidmap 2000:0:1 --uidmap 2001:2001:63536 --gidmap 0:1:2000 --gidmap 2000:0:1 --gidmap 2001:2001:63536 local/podman-compose-uid-gid-maps-port-fwd-not-working darkhttpd /etc --no-listing
4409502a0777254f7ee35233d75844643f18810d0f1ae3c39a646de9d0bf7f6d
exit code: 0
podman start -a podman-compose-uid-gid-maps-port-fwd-not-working_app_1
[app] | darkhttpd/1.16, copyright (c) 2003-2024 Emil Mikulic.
Expected behavior
The port forwarding 127.0.0.1:30020:8080/tcp should be working.
Actual behavior
The port forwarding 127.0.0.1:30020:8080/tcp is not working.
# On host machine
# Exit code: 1
$ sudo netstat -tulpn | grep containers
# On host machine
# Exit code: 1
$ sudo netstat -tulpn | grep 30020
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6cb5d796b042 localhost/local/podman-compose-uid-gid-maps-port-fwd-not-working:latest darkhttpd /etc --... 3 minutes ago Up 3 minutes ago 127.0.0.1:30020->8080/tcp podman-compose-uid-gid-maps-port-fwd-not-working_app_1
$ docker exec -it podman-compose-uid-gid-maps-port-fwd-not-working_app_1 sh
~ $ ss -tlpn
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 0.0.0.0:8080 0.0.0.0:* users:(("darkhttpd",pid=1,fd=3))
~ $ curl -v localhost:8080/alpine-release
* Host localhost:8080 was resolved.
* IPv6: ::1
* IPv4: 127.0.0.1
* Trying [::1]:8080...
* connect to ::1 port 8080 from ::1 port 42796 failed: Connection refused
* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080
> GET /alpine-release HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/8.8.0
> Accept: */*
>
* Request completely sent off
< HTTP/1.1 200 OK
< Date: Wed, 03 Jul 2024 09:09:13 GMT
< Server: darkhttpd/1.16
< Accept-Ranges: bytes
< Keep-Alive: timeout=30
< Content-Length: 7
< Content-Type: application/octet-stream
< Last-Modified: Tue, 18 Jun 2024 14:15:41 GMT
<
3.20.1
* Connection #0 to host localhost left intact
# On host machine
$ curl -vL localhost:30020
* Trying 127.0.0.1:30020...
* connect to 127.0.0.1 port 30020 failed: Connection refused
* Trying ::1:30020...
* connect to ::1 port 30020 failed: Connection refused
* Failed to connect to localhost port 30020 after 0 ms: Connection refused
* Closing connection 0
curl: (7) Failed to connect to localhost port 30020 after 0 ms: Connection refused
Environment:
I do NOT have any SELinux or AppArmor settings.
$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.4 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
$ podman version
Version: 3.4.4
API Version: 3.4.4
Go Version: go1.18.1
Built: Thu Jan 1 08:00:00 1970
OS/Arch: linux/amd64
$ podman info
host:
arch: amd64
buildahVersion: 1.23.1
cgroupControllers: []
cgroupManager: cgroupfs
cgroupVersion: v1
conmon:
package: 'conmon: /usr/bin/conmon'
path: /usr/bin/conmon
version: 'conmon version 2.0.25, commit: unknown'
cpus: 12
distribution:
codename: jammy
distribution: ubuntu
version: "22.04"
eventLogger: journald
hostname: DESKTOP-BNE42DB
idMappings:
gidmap:
- container_id: 0
host_id: 1000
size: 1
- container_id: 1
host_id: 100000
size: 65536
uidmap:
- container_id: 0
host_id: 1000
size: 1
- container_id: 1
host_id: 100000
size: 65536
kernel: 5.15.133.1-microsoft-standard-WSL2
linkmode: dynamic
logDriver: journald
memFree: 1260052480
memTotal: 8159125504
ociRuntime:
name: crun
package: 'crun: /usr/bin/crun'
path: /usr/bin/crun
version: |-
crun version 0.17
commit: 0e9229ae34caaebcb86f1fde18de3acaf18c6d9a
spec: 1.0.0
+SYSTEMD +SELINUX +APPARMOR +CAP +SECCOMP +EBPF +YAJL
os: linux
remoteSocket:
exists: true
path: /run/user/1000/podman/podman.sock
security:
apparmorEnabled: false
capabilities: CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_FOWNER,CAP_FSETID,CAP_KILL,CAP_NET_BIND_SERVICE,CAP_SETFCAP,CAP_SETGID,CAP_SETPCAP,CAP_SETUID,CAP_SYS_CHROOT
rootless: true
seccompEnabled: true
seccompProfilePath: /usr/share/containers/seccomp.json
selinuxEnabled: false
serviceIsRemote: false
slirp4netns:
executable: /usr/bin/slirp4netns
package: 'slirp4netns: /usr/bin/slirp4netns'
version: |-
slirp4netns version 1.0.1
commit: 6a7b16babc95b6a3056b33fb45b74a6f62262dd4
libslirp: 4.6.1
swapFree: 2147483648
swapTotal: 2147483648
uptime: 56h 2m 5.65s (Approximately 2.33 days)
plugins:
log:
- k8s-file
- none
- journald
network:
- bridge
- macvlan
volume:
- local
registries: {}
store:
configFile: /home/lei/.config/containers/storage.conf
containerStore:
number: 1
paused: 0
running: 1
stopped: 0
graphDriverName: overlay
graphOptions: {}
graphRoot: /home/lei/.local/share/containers/storage
graphStatus:
Backing Filesystem: extfs
Native Overlay Diff: "true"
Supports d_type: "true"
Using metacopy: "false"
imageStore:
number: 206
runRoot: /run/user/1000/containers
volumePath: /home/lei/.local/share/containers/storage/volumes
version:
APIVersion: 3.4.4
Built: 0
BuiltTime: Thu Jan 1 08:00:00 1970
GitCommit: ""
GoVersion: go1.18.1
OsArch: linux/amd64
Version: 3.4.4
If I do the following changes to the docker-compose.yaml, the port forwarding will work:
--- a/podman-compose-uid-gid-maps-port-fwd-not-working/docker-compose.yaml
+++ b/podman-compose-uid-gid-maps-port-fwd-not-working/docker-compose.yaml
@@ -7,15 +7,6 @@ services:
context: .
restart: "unless-stopped"
user: "2000:2000"
- x-podman:
- uidmaps:
- - "0:1:2000"
- - "2000:0:1"
- - "2001:2001:63536"
- gidmaps:
- - "0:1:2000"
- - "2000:0:1"
- - "2001:2001:63536"
ports:
- 127.0.0.1:30020:8080/tcp
#command: sleep infinity
$ podman-compose up
podman-compose version: 1.0.7
['podman', '--version', '']
using podman version: 3.4.4
** excluding: set()
['podman', 'inspect', '-t', 'image', '-f', '{{.Id}}', 'local/podman-compose-uid-gid-maps-port-fwd-not-working']
['podman', 'ps', '--filter', 'label=io.podman.compose.project=podman-compose-uid-gid-maps-port-fwd-not-working', '-a', '--format', '{{ index .Labels "io.podman.compose.config-hash"}}']
podman pod create --name=pod_podman-compose-uid-gid-maps-port-fwd-not-working --infra=false --share=
b919e9cfe8d4c992b532ad48014468cbf961d684821b6d4a53c78338876073a6
exit code: 0
['podman', 'network', 'exists', 'podman-compose-uid-gid-maps-port-fwd-not-working_net']
podman create --name=podman-compose-uid-gid-maps-port-fwd-not-working_app_1 --pod=pod_podman-compose-uid-gid-maps-port-fwd-not-working --label io.podman.compose.config-hash=cb2cd1f4df19fc6ac17dd57e2fc757831b79e6100e25159fa949d04b23bf0f51 --label io.podman.compose.project=podman-compose-uid-gid-maps-port-fwd-not-working --label io.podman.compose.version=1.0.7 --label PODMAN_SYSTEMD_UNIT=podman-compose@podman-compose-uid-gid-maps-port-fwd-not-working.service --label com.docker.compose.project=podman-compose-uid-gid-maps-port-fwd-not-working --label com.docker.compose.project.working_dir=/tmp/podman-compose-uid-gid-maps-port-fwd-not-working --label com.docker.compose.project.config_files=docker-compose.yaml --label com.docker.compose.container-number=1 --label com.docker.compose.service=app --net podman-compose-uid-gid-maps-port-fwd-not-working_net --network-alias app -p 127.0.0.1:30020:8080/tcp -u 2000:2000 --restart unless-stopped local/podman-compose-uid-gid-maps-port-fwd-not-working darkhttpd /etc --no-listing
7645da5d504e94d166e1debdf3c986adc85f966d3f5351c9a8bc13ea3e2ba89f
exit code: 0
podman start -a podman-compose-uid-gid-maps-port-fwd-not-working_app_1
[app] | darkhttpd/1.16, copyright (c) 2003-2024 Emil Mikulic.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7645da5d504e localhost/local/podman-compose-uid-gid-maps-port-fwd-not-working:latest darkhttpd /etc --... 3 minutes ago Up 3 minutes ago 127.0.0.1:30020->8080/tcp podman-compose-uid-gid-maps-port-fwd-not-working_app_1
$ sudo netstat -tulpn | grep containers
tcp 0 0 127.0.0.1:30020 0.0.0.0:* LISTEN 653780/containers-r
$ curl -vL localhost:30020/alpine-release
* Trying 127.0.0.1:30020...
* Connected to localhost (127.0.0.1) port 30020 (#0)
> GET /alpine-release HTTP/1.1
> Host: localhost:30020
> User-Agent: curl/7.81.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Wed, 03 Jul 2024 09:22:30 GMT
< Server: darkhttpd/1.16
< Accept-Ranges: bytes
< Keep-Alive: timeout=30
< Content-Length: 7
< Content-Type: application/octet-stream
< Last-Modified: Tue, 18 Jun 2024 14:15:41 GMT
<
3.20.1
* Connection #0 to host localhost left intact
There might be an issue with how Podman 3.4.x handles port forwarding in conjunction with UID/GID mappings.
Closed, see: https://github.com/containers/podman/issues/23171
I think podman-compose should detect this scenario and issue a warning. It's easy enough to do so and will save users' time.