Docker容器访问本地端口报400无效主机名及端口映射失败排查
环境配置
docker-compose.yaml
version: '3.8' services: sequence-counts-loading: build: ./ volumes: - ./:/app
Dockerfile
FROM python:3.11.2-bullseye WORKDIR /app COPY requirements.txt /app RUN pip3 install -r requirements.txt COPY . /app # 防止容器停止 ENTRYPOINT ["tail", "-f", "/dev/null"]
问题现象
- 执行
docker-compose up --build启动容器后,通过VS Code Dev Containers扩展连接到容器,执行curl host.docker.internal可正常获取IIS响应。 - 但执行
curl http://host.docker.internal:6666/ajax.ashx?cmd=lib.mapping时,返回400错误:
return (<HTML><HEAD><TITLE>Bad Request</TITLE> <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD> <BODY><h2>Bad Request - Invalid Hostname</h2> <hr><p>HTTP Error 400. The request hostname is invalid.</p> </BODY></HTML> )
- 本地浏览器访问
http://localhost:6666/ajax.ashx?cmd=lib.mapping可正常返回JSON。
尝试过的操作
在docker-compose.yaml中添加端口映射:
ports: - '6666:6666'
启动容器时出现错误:
ERROR: for sequence-counts-loading Cannot start service sequence-counts-loading: Ports are not available: exposing port TCP 0.0.0.0:6666 -> 0.0.0.0:0: listen tcp 0.0.0.0:6666: bind: An attempt was made to access a socket in a way forbidden by its access permissions.
ERROR: Encountered errors while bringing up the project.
更新:使用Windows 11系统及Norton防火墙,已创建流量规则允许应用所在端口范围并重启电脑,问题未解决。该问题可通过ubuntu镜像复现:执行docker run --rm -it ubuntu /bin/bash后安装curl,再执行curl host.docker.internal:6666/ajax.ashx?cmd=lib.mapping仍报错。
原因分析
- 主机名绑定限制:本地6666端口的应用(推测为IIS托管的ASP.NET应用)启用了主机名访问限制,仅允许
localhost请求,拒绝host.docker.internal作为主机名的访问,因此返回400错误。 - 端口映射失败:本地6666端口已被应用占用,Docker无法重复绑定;此外Norton防火墙规则可能未正确生效,或Windows系统的端口权限/预留机制导致绑定失败。
解决方法
方法1:修改本地应用的主机名绑定(针对IIS)
- 打开IIS管理器,找到对应站点,右键选择「编辑绑定」
- 添加新绑定:类型选HTTP,端口填6666,主机名留空(允许所有主机名访问),或直接添加
host.docker.internal作为合法主机名 - 保存后重启站点,再在容器内尝试访问
方法2:使用本地IP替代host.docker.internal
- 在Windows命令行执行
ipconfig,获取本地局域网IP(如192.168.x.x) - 在容器内执行
curl http://192.168.x.x:6666/ajax.ashx?cmd=lib.mapping,绕过主机名限制
方法3:调整Docker端口映射(解决绑定失败)
若无需将容器端口暴露到主机,无需添加6666端口映射(容器访问主机用host.docker.internal无需端口映射)。若确实需要映射,更换未被占用的端口:
ports: - '6667:6666'
(注:此方法仅解决端口绑定失败问题,不直接解决容器访问主机的400错误)
方法4:排查防火墙与系统端口权限
- 确认Norton防火墙的入站/出站规则是否包含Docker进程(
docker.exe、dockerd.exe)及6666端口的流量权限 - 临时关闭防火墙(执行
netsh advfirewall set allprofiles state off)测试是否能正常访问,排查防火墙干扰 - 检查Windows端口预留:执行
netsh int ipv4 show excludedportrange protocol=tcp,若6666在预留范围内,重启winnat服务:
net stop winnat net start winnat
内容的提问来源于stack exchange,提问作者Nikita Vlasenko

