为何Docker容器用-p 8080:8080端口映射无效,--net=host却正常?
相关文件与操作
Dockerfile
FROM ubuntu:20.04 # 环境配置 RUN apt-get update && apt-get install -y unzip xz-utils git openssh-client curl python3 && apt-get upgrade -y && rm -rf /var/cache/apt # 安装Flutter RUN git clone https://github.com/flutter/flutter.git /usr/local/flutter ENV PATH="/usr/local/flutter/bin:/usr/local/flutter/bin/cache/dart-sdk/bin:${PATH}" RUN flutter channel master RUN flutter upgrade RUN flutter config --enable-web RUN flutter doctor -v # 复制文件并获取依赖 COPY . /usr/local/bin/app WORKDIR /usr/local/bin/app RUN flutter pub get RUN flutter build web # 声明暴露端口并启动服务 EXPOSE 8080 RUN chmod +x /usr/local/bin/app/server/server.sh ENTRYPOINT [ "/usr/local/bin/app/server/server.sh" ]
入口文件server.sh
#!/bin/bash cd build/web/ python3 -m http.server 8080
操作步骤
- 构建镜像:
docker build --network=host --tag image1 . - 三种运行方式:
docker run -d -p 8080:8080 image1:无报错但无法访问docker run -d image1:无报错但无法访问docker run -d --net=host image1:可正常访问
问题原因分析
核心问题出在http.server的绑定逻辑上:
- Python的
http.server默认仅监听容器内部的回环地址127.0.0.1,这个地址的服务只能被容器自身的进程访问。当使用-p 8080:8080做端口映射时,Docker会将主机8080端口的请求转发到容器的8080端口,但容器内的服务只监听127.0.0.1,外部请求无法到达服务进程,因此无法访问。 - 当使用
--net=host网络模式时,容器直接共享主机的网络命名空间,服务启动后绑定的是主机的127.0.0.1:8080,此时主机访问127.0.0.1:8080就能直接连接到服务,所以可以正常访问。
解决方法
修改server.sh中的启动命令,指定服务绑定到容器的所有网络接口(0.0.0.0):
#!/bin/bash cd build/web/ python3 -m http.server 8080 --bind 0.0.0.0
修改后重新构建镜像,再用docker run -d -p 8080:8080 image1启动,即可正常通过主机的8080端口访问服务。
内容的提问来源于stack exchange,提问作者Aseem
相关产品推荐
相关产品推荐

