Docker swarm / service do not bind on ipv4 only on ipv6!

What do you mean by “is not reachable”?

What’s the error? From which program? From the Internet, from outside Proxmox, from a VM inside Proxmox, from inside a Docker container? How do you expose ports to the outside of the VMs or outside your Proxmox host?

I have also this problem, any update about this issue ? :wink:

How do you know that it’s only IP6 and not IP4?

We might have the same issue: Swarm manager address not bound to IPv4 but only IPv6 · Issue #46851 · moby/moby · GitHub

Note: we discussed this topic before, we found that netstat not necessarily always shows the used IPv4 ports when using IPv6 ports at the same time, but they are still open.

I had no time to actually search further for this problem …

But note that not only

netstat -tupe

command do not give ipv4 connection but the command

lsof -i -n

give the same result, no listening on ipv4 !

So i think the problem is somewhere with docker swarm / or os / or virtualization layer

1 Like

Try this change in the following code: ports


version: "3"
services:
  portainer:
    image: portainer/portainer-ce:latest
    container_name : portainer-ce
    ports:
    - target: 9443
        published: 9443
        protocol: tcp
        mode: host
    volumes:
        - ./persist/data:/data
        - /var/run/docker.sock:/var/run/docker.sock
    restart: unless-stopped

=> For me it worked.

1 Like

I confirm, I was having the same issue with only ipv6 binding when using docker swarm and the using:

    - target: 9443
        published: 9443
        protocol: tcp
        mode: host

for all 3 ports.

btw I started off with docker installed on unpriviledged LX container on proxmox on arm:

this was the script:
bash -c “$(wget -qLO - https://github.com/asylumexp/Proxmox/raw/main/ct/docker.sh)”

anyway I suspect this will also fix the issue everyone else has been having on this post.

Deploying it in mode host is kinda pointless though if you want to be able to reach it from any host (unless you specify deplyo: mode: global, which runs the container on all nodes and has a limited usecase.

still need to figure out how to to fix the tcp (v4) binding issue in deploy: mode: replicated and with target:port mode ingress.

I can’t understand why people solely concentrate on the output of netstat, Instead of actually testing the connection.

For illustration purposes, I filter the netstat output to a global service in host mode on port 80+443 (Traefik) and a replicated service in ingress mode on port 9000 (Portainer):

$ sudo netstat -tulpn | grep -E ':80 |:443 |:9000 '
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      576900/docker-proxy
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      576877/docker-proxy
tcp6       0      0 :::9000                 :::*                    LISTEN      1537/dockerd
tcp6       0      0 :::80                   :::*                    LISTEN      576907/docker-proxy
tcp6       0      0 :::443                  :::*                    LISTEN      576885/docker-proxy

Even though, the ipv4 listener is not shown separately, It still exists and can be used for connection:

curl -iv --silent --output /dev/null http://192.168.200.20:9000
*   Trying 192.168.200.20:9000...
* TCP_NODELAY set
* Connected to 192.168.200.20 (192.168.200.20) port 9000 (#0)
> GET / HTTP/1.1
> Host: 192.168.200.20:9000
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Cache-Control: max-age=31536000
< Content-Length: 19177
< Content-Type: text/html; charset=utf-8
< Last-Modified: Sun, 21 Apr 2024 21:29:03 GMT
< Vary: Accept-Encoding
< X-Content-Type-Options: nosniff
< X-Xss-Protection: 1; mode=block
< Date: Sat, 22 Jun 2024 15:22:55 GMT
<
{ [512 bytes data]
* Connection #0 to host 192.168.200.20 left intact

By the logic applied in this topic this should be impossible, as netstat didn’t show a listener for ipv4. Still the output of the curl command proves that it works.

Note: I use --silent --output /dev/null to shorten the output

1 Like

For those who care to understand why ipv4 connections are working on a tcp6 listener: here is a short and beautiful StackExchange answer: https://unix.stackexchange.com/a/237747.