Express无法绑定全接口及Docker容器外部访问问题求助
问题:无法从容器外部访问Express应用
最小示例代码说明
包含以下文件,可复现问题:
index.js
const express = require('express') const app = express() app.get('/', (req, res) => res.json({hello: "world"})) app.listen({port: 12345, host: '0.0.0.0'}, () => console.log('ready'))
注:也曾尝试app.listen(12345)和app.listen(12345, '0.0.0.0'),效果一致。
Dockerfile
FROM node WORKDIR /project ADD package.json yarn.lock /project/ RUN yarn EXPOSE 12345 ADD index.js /project/ ENTRYPOINT [ "node", "index.js" ]
package.json
{ "name": "test-express", "version": "1.0.0", "description": "what's the deal", "main": "index.js", "license": "MIT", "dependencies": { "express": "^4.18.2" } }
复现步骤
- 本地直接运行
node index.js后,执行curl localhost:12345/,可正常收到响应。 - 构建并进入容器内部访问:
可正常收到响应。docker build -t test-express . container_id="$(docker run -d test-express)" docker exec $container_id curl localhost:12345/ - 尝试通过容器IP访问:
请求无限挂起。ip_addr=$(docker inspect $container_id --format "{{ .NetworkSettings.Networks.bridge.IPAddress }}") curl $ip_addr:12345
解决方案
问题出在Docker容器端口未做映射。EXPOSE指令仅用于声明容器使用的端口,不会自动将端口暴露给主机。要让外部访问容器内的服务,运行容器时必须用-p参数完成主机与容器的端口映射:
docker run -d -p 12345:12345 test-express
其中第一个12345是主机对外提供服务的端口,第二个是容器内应用监听的端口,两者可设置为不同值(例如-p 8080:12345,即可通过主机8080端口访问容器内的12345端口)。
完成映射后,直接执行curl localhost:12345即可访问容器内的Express应用。
内容的提问来源于stack exchange,提问作者D. Scott Boggs
相关产品推荐
相关产品推荐

