Docker 端口映射异常

Docker port mapping weirdness

我正在使用这个 docker-compose 文件:

version: "3.7"

services:
  mautrix-wsproxy:
    container_name: mautrix-wsproxy
    image: dock.mau.dev/mautrix/wsproxy
    restart: unless-stopped
    ports:
      - 29331
    environment:
      #LISTEN_ADDRESS: ":29331"
      APPSERVICE_ID: imessage
      AS_TOKEN: put your as_token here
      HS_TOKEN: put your hs_token here
      # These URLs will work as-is with docker networking
      SYNC_PROXY_URL: http://mautrix-syncproxy:29332
      SYNC_PROXY_WSPROXY_URL: http://mautrix-wsproxy:29331
      SYNC_PROXY_SHARED_SECRET: ...

  mautrix-syncproxy:
    container_name: mautrix-syncproxy
    image: dock.mau.dev/mautrix/syncproxy
    restart: unless-stopped
    environment:
      #LISTEN_ADDRESS: ":29332"
      DATABASE_URL: postgres://user:pass@host/mautrixsyncproxy
      HOMESERVER_URL: http://localhost:8008
      SHARED_SECRET: ...

但随后 docker ps 显示

... dock.mau.dev/mautrix/wsproxy ... 0.0.0.0:49156->29331/tcp, :::49156->29331/tcp

而且我必须使用外部端口 49156 连接到其内部端口 29331。

这个49156到底是从哪里来的?我如何将其映射为 29331->29331?

docker inspect 显示:

        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": ...,
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "29331/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "49156"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "49156"
                    }
                ]
            },

查看 documentation for ports in a compose file (docs.docker.com) 我们可以阅读以下内容:

Short syntax

There are three options:

...

  • Specify just the container port (an ephemeral host port is chosen for the host port).

...

这实质上意味着选择一个随机的、空闲的主机端口。

要将容器端口显式映射到已知主机端口(即使它与容器端口相同),我们使用 HOST:CONTAINER 语法(参见上面的 link):

version: "3.7"

services:
  mautrix-wsproxy:
    ...
    ports:
      - "29331:29331"
    ...

From the docs 对于 ports:

There are three options:

  • Specify both ports (HOST:CONTAINER)
  • Specify just the container port (an ephemeral host port is chosen for the host port).
  • ....

您使用的是第二个选项,只需指定要公开的容器端口。由于您没有指定将其映射到的主机端口,“选择了一个临时主机端口”。

除了提供的答案之外,如果您想要修复端口映射,您可以在使用 compose 时通过使用 publish flag or in the ports 数组提供由冒号分隔的 2 个端口来实现。左边是宿主系统上可用的映射端口,右边是容器内部的端口。

# make port 29331 inside the container available on port 8080 on the host system
docker run --publish 8080:29331 busybox

根据你的情况,回答你的问题。

How do I map it so it's 29331->29331 ?

services:
  mautrix-wsproxy:
    ports:
      - "29331:29331"
    ...