Docker部署React/Node.js应用至Digital Ocean遇无法访问问题
问题诊断与修复方案
看起来你的部署流程大部分是对的——容器构建、服务启动、MongoDB连接都正常,但访问失败的核心问题出在端口映射不匹配,另外还有几个需要检查的点,我一步步给你拆解:
1. 端口映射与服务监听端口不匹配
你运行容器时用了-p 80:3000,意思是把Droplet的80端口转发到容器的3000端口,但你的server.js里,服务实际监听的是5000端口(const port = process.env.PORT || 5000;)。这就相当于你把快递寄到了3000号门,但服务其实在5000号门办公,自然收不到请求。
两种修复方式:
- 方式一:修改端口映射,把Droplet的80端口映射到容器的5000端口:
docker run -p 80:5000 -e NODE_ENV="production" -e MONGO_URI="URI" -e SECRET_OR_KEY="KEY" myImage - 方式二:通过环境变量指定服务监听3000端口,保持映射一致:
docker run -p 80:3000 -e PORT=3000 -e NODE_ENV="production" -e MONGO_URI="URI" -e SECRET_OR_KEY="KEY" myImage
2. 检查DigitalOcean Droplet的防火墙规则
即使容器端口映射正确,如果Droplet的防火墙没有开放80端口,外部浏览器还是无法访问。
怎么检查:
- 登录DigitalOcean控制面板,找到你的Docker Droplet
- 切换到「Firewalls」标签页
- 确认存在一条入站规则:端口
80,来源0.0.0.0/0(允许所有外部IP访问) - 如果没有这条规则,点击「Edit」添加即可
3. Dockerfile的优化建议(非当前问题,但能避免后续坑)
你的Dockerfile里在构建时克隆代码,这不是最佳实践——应该把本地项目文件通过COPY指令复制到容器,而不是依赖外部Git仓库。另外,EXPOSE的端口要和服务实际监听的端口一致,这样更清晰:
FROM node:11.10.0 WORKDIR /usr/src/project # 先复制package.json,利用Docker缓存加速构建 COPY package*.json ./ RUN npm install # 复制客户端代码并构建 COPY client/ ./client/ WORKDIR /usr/src/project/client RUN npm install && npm run build # 回到根目录,复制剩余服务端代码 WORKDIR /usr/src/project COPY . . # 暴露服务实际监听的端口 EXPOSE 5000 ENTRYPOINT ["npm", "run", "server"]
4. 验证容器内服务的监听状态
如果前面的步骤都做了还是不行,可以登录Droplet,检查容器内的服务是否真的在监听端口:
# 先获取运行中的容器ID docker ps # 进入容器(替换成你的容器ID) docker exec -it <your-container-id> bash # 安装netstat(如果容器内没有的话) apt update && apt install net-tools # 检查端口监听 netstat -tulpn
你应该能看到node进程在监听5000(或你指定的PORT)端口,如果没有,那可能是服务启动有隐藏问题,再仔细看容器日志确认。
按照这些步骤排查,应该就能解决访问失败的问题了!
内容的提问来源于stack exchange,提问作者mordecai
相关产品推荐
相关产品推荐

