You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

M1芯片MacOS下Docker Compose host网络模式失效问题咨询

问题与解决方法

环境信息

  • Docker Compose版本:v2.23.3
  • Docker(podman)版本:
    Client:       Podman Engine
    Version:      4.9.3
    API Version:  4.9.3
    Go Version:   go1.21.7
    Git Commit:   8d2b55ddde1bc81f43d018dfc1ac027c06b26a7f
    Built:        Tue Feb 13 14:55:17 2024
    OS/Arch:      darwin/arm64
    
    Server:       Podman Engine
    Version:      4.9.0
    API Version:  4.9.0
    Go Version:   go1.21.6
    Built:        Wed Jan 24 05:07:09 2024
    OS/Arch:      linux/arm64
    
  • 操作系统:MacOS 14.3.1 (23D60)
  • 芯片:M1

场景与配置

有一个名为app的服务,预期监听1997端口接收主机消息。文件夹结构:

tree .
.
├── Dockerfile
├── app
│   ├── app.py
│   ├── received.txt
│   └── send.py
└── docker-compose.yaml

各文件内容

Dockerfile

FROM python:3.9-slim

# Set the working directory in the container
WORKDIR /app

# Command to run the application
CMD sh -c 'pwd && ls && exec python app.py'

app.py

import socket

def write_to_file(message):
    with open("/app/received.txt", "a") as f:  # Use mode 'a' to append to the file
        f.write(message + "\n")  # Write the message followed by a newline

def start_server(host='0.0.0.0', port=1997):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((host, port))
        s.listen()
        print(f"Listening on {host}:{port}")
        while True:
            conn, addr = s.accept()
            with conn:
                print(f"Connected by {addr}")
                while True:
                    data = conn.recv(1024)
                    if not data:
                        break
                    message = data.decode('utf-8')
                    write_to_file(message)
                    if message.strip().lower() == "bye":
                        print("Received 'bye', shutting down the server.")
                        return  # Exit the function and terminate the server

if __name__ == "__main__":
    start_server()

send.py

import socket
import sys

def send_message(host, port, message):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((host, port))
        s.sendall(message.encode('utf-8'))
        # If you want to wait for a response, uncomment the next line
        # data = s.recv(1024)
    print(f"Message sent: {message}")

if __name__ == "__main__":
    if len(sys.argv) > 1:
        message = ' '.join(sys.argv[1:])  # Join all arguments into a single message, separated by spaces
        send_message('localhost', 1997, message)
    else:
        print("Usage: python send_message.py <message>")

初始docker-compose.yaml

version: '3.8'
services:
  app:
    build:
      context: .
      network: host
    volumes:
      - ./app:/app

问题现象

启动服务后,本地执行python3 ./app/send.py hello hello gello触发连接拒绝错误:

python3 ./app/send.py hello hello gello
Traceback (most recent call last):
  File "/~~~/draft/./app/send.py", line 15, in <module>
    send_message('localhost', 1997, message)
  File "/~~~/draft/./app/send.py", line 6, in send_message
    s.connect((host, port))
ConnectionRefusedError: [Errno 61] Connection refused

但在容器内部执行相同命令可正常工作:

docker exec -it draft-app-1  python /app/send.py jillo 
Message sent: jillo

改用network_mode: "host"配置后,问题依旧存在。

解决方法

M1 Mac上的Podman基于虚拟机运行,network_mode: host仅作用于虚拟机内部,无法直接让Mac主机访问容器端口。提供两种解决方案:

方案1:使用端口映射(推荐)

修改docker-compose.yaml,添加端口映射规则,将容器1997端口映射到主机同端口:

version: '3.8'
services:
  app:
    build: .
    ports:
      - "1997:1997"
    volumes:
      - ./app:/app

修改后重启服务,本地执行send.py即可正常连接。

方案2:连接Podman虚拟机IP

若必须使用host网络,先获取Podman虚拟机的IP地址:

podman machine inspect --format '{{.IPAddress}}'

将send.py中的localhost替换为该IP,或执行命令时指定对应主机地址即可。


内容的提问来源于stack exchange,提问作者IsaIkari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 14:24:49