Windows下使用docker-compose启动容器无法访问暴露端口求助
嘿,我一眼就看出问题所在了——Angular的实时开发服务器默认只监听容器内部的localhost(也就是127.0.0.1),而不是容器的所有网络接口(0.0.0.0)。虽然Docker已经帮你做了4200端口的映射,但服务只绑定了容器自己的回环地址,主机根本没法通过映射的端口连接到它。
怎么修复?
这里有两种简单的方法,选你觉得方便的就行:
方法1:修改启动命令,强制监听所有接口
你可以直接在Dockerfile里调整npm start的参数,让Angular服务监听0.0.0.0:
把Dockerfile里的CMD ["npm", "start"]替换成:
CMD ["npm", "start", "--", "--host", "0.0.0.0"]
或者,你也可以修改项目根目录的package.json,把scripts里的start脚本改成:
"start": "ng serve --host 0.0.0.0"
这样原来的Dockerfile就不用动了,npm start会自动用新的参数启动服务。
方法2:通过Docker Compose添加环境变量
如果你不想改代码或Dockerfile,也可以在docker-compose.yaml里加个环境变量,让Angular CLI自动监听0.0.0.0:
version: '3' services: angular: build: . container_name: angular-docker volumes: - ./src:/usr/src/app/src ports: - "4200:4200" environment: - HOST=0.0.0.0
验证修复结果
修改完之后,记得重新构建并启动容器:
docker-compose down docker-compose up --build
等你看到日志里出现这样的内容:
angular-docker | ** Angular Live Development Server is listening on 0.0.0.0: 4200, open your browser on http://localhost:4200/ **
这时候再用主机的Chrome访问http://localhost:4200,应该就能正常加载你的Angular应用了。
为什么容器内curl能访问?
顺便解释一下:容器里的localhost就是容器自己的回环地址,服务确实在这个地址上运行,所以你进入容器后用curl localhost:4200能拿到响应;但主机的localhost和容器的localhost是完全独立的网络空间,只有当服务监听容器的0.0.0.0(所有接口)时,Docker的端口映射才能把主机的请求转发到容器里的服务上。
内容的提问来源于stack exchange,提问作者Nima

