docker / for-win

Bug reports for Docker Desktop for Windows
https://www.docker.com/products/docker#/windows
1.86k stars 291 forks source link

Can someone help me figure this out? #13246

Closed YouveGotMeowxy closed 1 year ago

YouveGotMeowxy commented 1 year ago

Actual behavior

I run my containers in Swarm. Even though I have specified ports to open on the host, they don't get bound in the contaier when I run the usual docker stack deploy command.:

image

This obviously means I can't connect to any containers anymore.

The odd thing is, there's only a single container/stack that does bind the port, and that's my Portainer stack. And looking at it's Compose there's nothing different or unusual about it. And even stranger, That stack has 2 containers defined, both of which expose ports to the host, and only 1 of them (Portainer Agent) results in the port exposed to the host while the other does not.

Portainer Compose ``` services: agent: image: 'portainer/agent:latest' environment: AGENT_CLUSTER_ADDR: 'tasks.agent' volumes: - '/:/host:ro' - '/var/run/docker.sock:/var/run/docker.sock:ro' ports: - target: 9001 published: 9001 protocol: 'tcp' mode: 'host' deploy: mode: 'global' restart_policy: condition: 'any' labels: com.centurylinklabs.watchtower.enable: 'false' networks: - 'portainer' portainer: image: 'portainer/portainer-ee:latest' environment: TZ: 'America/Chicago' volumes: - '/opt/docker/configs/portainer/data:/data:rw' - '/mnt/e/Docker/Logs/portainer:/data/log:rw' ports: - '9013:9443' depends_on: - 'agent' command: -H tcp://tasks.agent:9001 --tlsskipverify deploy: mode: 'replicated' replicas: 1 placement: constraints: [node.role == manager] restart_policy: condition: 'any' networks: - 'portainer' - 'security' ```

Expected behavior

They get bound.

Information

Output of & "C:\Program Files\Docker\Docker\resources\com.docker.diagnose.exe" check

Click ``` [2023-02-16T18:24:21.746146900Z][com.docker.diagnose.exe][I] set path configuration to OnHost Starting diagnostics [PASS] DD0027: is there available disk space on the host? [PASS] DD0028: is there available VM disk space? [PASS] DD0002: does the bootloader have virtualization enabled? [SKIP] DD0018: does the host support virtualization? [PASS] DD0001: is the application running? [PASS] DD0022: is the Virtual Machine Platform Windows Feature enabled? [PASS] DD0021: is the WSL 2 Windows Feature enabled? [PASS] DD0024: is WSL installed? [PASS] DD0025: are WSL distros installed? [PASS] DD0026: is the WSL LxssManager service running? [PASS] DD0029: is the WSL 2 Linux filesystem corrupt? [PASS] DD0035: is the VM time synchronized? [PASS] DD0017: can a VM be started? [PASS] DD0016: is the LinuxKit VM running? [PASS] DD0011: are the LinuxKit services running? [PASS] DD0004: is the Docker engine running? [PASS] DD0015: are the binary symlinks installed? [PASS] DD0031: does the Docker API work? [PASS] DD0013: is the $PATH ok? [PASS] DD0003: is the Docker CLI working? [PASS] DD0005: is the user in the docker-users group? [PASS] DD0038: is the connection to Docker working? [PASS] DD0014: are the backend processes running? [PASS] DD0007: is the backend responding? [PASS] DD0008: is the native API responding? [PASS] DD0009: is the vpnkit API responding? [PASS] DD0010: is the Docker API proxy responding? [PASS] DD0006: is the Docker Desktop Service responding? [SKIP] DD0030: is the image access management authorized? [PASS] DD0033: does the host have Internet access? [PASS] DD0002: does the bootloader have virtualization enabled? [PASS] DD0018: does the host support virtualization? [PASS] DD0001: is the application running? [PASS] DD0022: is the Virtual Machine Platform Windows Feature enabled? [PASS] DD0021: is the WSL 2 Windows Feature enabled? [PASS] DD0024: is WSL installed? [PASS] DD0025: are WSL distros installed? [PASS] DD0026: is the WSL LxssManager service running? [PASS] DD0029: is the WSL 2 Linux filesystem corrupt? [PASS] DD0035: is the VM time synchronized? [PASS] DD0017: can a VM be started? [PASS] DD0016: is the LinuxKit VM running? [PASS] DD0011: are the LinuxKit services running? [PASS] DD0004: is the Docker engine running? [PASS] DD0015: are the binary symlinks installed? [PASS] DD0031: does the Docker API work? [PASS] DD0032: do Docker networks overlap with host IPs? No fatal errors detected. ```
YouveGotMeowxy commented 1 year ago

Well, after further investigation, it seems to appear that docker compose only accepts (or at least acknowledge) this format for setting ports:

- target: 9001
  published: 9001
  protocol: 'tcp'
  mode: 'host'

and not this format:

- "443:443"

It shows the ports in DD as bound using the first format now, and viewing listening connections on my machine show those ports listening, however, I still can't connect. Always getting something like: ERR_CONNECTION_CLOSED or empty response.

YouveGotMeowxy commented 1 year ago

Just updating my findings as I go in case it helps anyone else.

Seems like it possibly may have to do with docker swarm, since everything I run with compose cant connect, but when I do a direct:

docker run --name nginx -p 6969:80 -v /opt/docker/configs/www:/usr/share/nginx/html:ro -d nginx 

I am able to get a static text page at that port on localhost.

thaJeztah commented 1 year ago

When using swarm services, the default for services is to publish ports through the "ingress" network. Instances (containers / tasks) of the service are behind an internal loadbalancer, which means that the individual containers don't have their ports mapped.

For example;

docker service create --name foo -p 8080:80 nginx:alpine
ewv6ea7lq23rr571wdey4l95f
overall progress: 1 out of 1 tasks
1/1: running   [==================================================>]
verify: Service converged

When looking at the service (docker service ls), the mapped port is shown;

docker service ls
ID             NAME      MODE         REPLICAS   IMAGE          PORTS
ewv6ea7lq23r   foo       replicated   1/1        nginx:alpine   *:8080->80/tcp

And the port can be reached from any node in the swarm cluster (I'm using localhost here, as this is a local swarm with only one node);

curl -s localhost:8080 | grep Welcome
<title>Welcome to nginx!</title>
<h1>Welcome to nginx!</h1>

But when looking at the individual containers running on this node, no port-mapping will be shown;

docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS     NAMES
cd5c946ce2fe   nginx:alpine   "/docker-entrypoint.…"   4 minutes ago   Up 4 minutes   80/tcp    foo.1.4qki5ovbmhwlhb8r9z0l6kwan

Same when looking at the service "tasks" (which can be running on other nodes in the swarm);

docker service ps foo
ID             NAME      IMAGE          NODE             DESIRED STATE   CURRENT STATE            ERROR     PORTS
4qki5ovbmhwl   foo.1     nginx:alpine   docker-desktop   Running         Running 23 seconds ago
YouveGotMeowxy commented 1 year ago

Thank you for helping me solve this, @thaJeztah :)

There still seems to be something screwy going on though, as I haven't change any configs, but this all just started happening about 3 DD versions ago.

And also, for example on the Swag container (which is basically an Nginx container) here's my original config that previously worked great (in swarm, and also notice the ports format):

  swag:
    image: 'ghcr.io/linuxserver/swag:latest'
    env_file: 'swag.env'
    volumes:
      - '/opt/docker/configs/swag/config:/config:rw'
      - '/mnt/e/Docker/Logs/swag:/config/log:rw'
      - '/opt/docker/configs/.extras/.bashrc:/root/.bashrc:rw' # My Aliases
      - '/var/run/docker.sock:/var/run/docker.sock:ro'
    ports:
      - '443:443'
      - '80:80'
    deploy:
      mode: 'global'
      restart_policy:
        condition: 'any'
    networks:
      - 'clouds-syncs'

ports 443 and 80 showed up on the host machine, and then I could connect to any reverse proxied containers/services via those ports (via the ingress).

That stopped working.

So if I switch:

  swag:
    image: 'ghcr.io/linuxserver/swag:latest'
    env_file: 'swag.env'
    volumes:
      - '/opt/docker/configs/swag/config:/config:rw'
      - '/mnt/e/Docker/Logs/swag:/config/log:rw'
      - '/opt/docker/configs/.extras/.bashrc:/root/.bashrc:rw' # My Aliases
      - '/var/run/docker.sock:/var/run/docker.sock:ro'
    ports:
      - target: 443
        published: 443
        protocol: 'tcp'
        mode: 'host'
      - target: 80
        published: 80
        protocol: 'tcp'
        mode: 'host'
    deploy:
      mode: 'global'
      restart_policy:
        condition: 'any'
    networks:
      - 'clouds-syncs'

The only real change is the short/long syntax for ports, which essentially is identical as far as functionality, one would think?

Here's the short syntax:

image

But after that change to the long syntax the 443 and 80 ports now show up (in the DD container UI) (they didn't before with the short syntax), but doing a 'docker service ls' seems to show no ports open to the host?

image

Again, I should note, that for some reason I can no longer connect to any containers (though they're all shown as running as usual in the DD UI) that were started as a swarm service no matter which syntax I use, and whether I try to load the page directly on the localhost:port, or via reverse proxy. Very confused.

docker-robott commented 1 year ago

There hasn't been any activity on this issue for a long time. If the problem is still relevant, mark the issue as fresh with a /remove-lifecycle stale comment. If not, this issue will be closed in 30 days.

Prevent issues from auto-closing with a /lifecycle frozen comment.

/lifecycle stale

vialjoris commented 7 months ago
ports:
      - target: "30000-31000"
        host_ip: "127.0.0.1"
        published: "30000-31000"
        protocol: tcp

error while interpolating services.pureftpd.ports.[].target: failed to cast to expected type: strconv.Atoi: parsing "30000-31000": invalid syntax