EC2部署Docker Compose容器服务无法通过浏览器访问如何解决
问题根因
- 端口映射完全不匹配:NestJS应用通过
process.env.PORT配置实际监听容器内3005端口,但docker-compose端口配置仅写了- 8080:8080,既没有把宿主机端口映射到容器的3005,容器内8080端口也无任何服务监听,外部请求根本无法到达应用。 - 工作路径配置冲突:Dockerfile设置的工作目录是
/dist,但docker-compose卷挂载的目标路径是/usr/src/app,两个路径完全不一致,容器启动后会出现找不到依赖、找不到执行代码的问题,服务大概率没有正常启动。 - 安全组规则未覆盖业务端口:你配置的全量入站规则仅开放了HTTP(80)、HTTPS(443)端口,既没有配置反向代理把80/443端口的请求转发到Node服务端口,也没有在安全组开放实际业务用的3005/8080端口,公网流量无法到达对应服务。
- 冗余配置无效:docker-compose里的
expose字段仅用于容器间内部通信标记,不会对外暴露端口,配置的expose 8080/3005对公网访问没有任何作用;Dockerfile里的EXPOSE 8080也只是镜像标记,不会完成实际端口映射。 - 之前直接执行
nest start能访问,本质是当时安全组针对你的IP开放了应用默认端口(3000/3005),和你配置的80/443全量放行规则无关。换成Docker部署后端口映射错误、安全组未开放对应端口,自然无法访问。
修复步骤
1. 修正Dockerfile配置
统一工作目录为/usr/src/app,和docker-compose配置对齐,修正后内容:
FROM node:16.3.0-alpine as builder WORKDIR /usr/src/app COPY package*.json ./ RUN npm install --force COPY . . RUN npm run build # 标记应用实际监听端口 EXPOSE 3005 CMD [ "npm", "run", "dev"]
2. 修正docker-compose.yaml配置
调整端口映射到应用实际监听的3005端口,Redis不要暴露到公网避免被入侵,删除无效冗余配置,修正后内容:
version: '3.7' networks: proxy: name: proxy services: redis: image: redis:6.2-alpine ports: - 127.0.0.1:6379:6379 # 仅绑定本地环回,不对外暴露Redis端口 command: ["redis-server", "--requirepass", "redisPass12345!"] networks: - proxy worker: container_name: worker build: context: . dockerfile: Dockerfile depends_on: - redis ports: - 3005:3005 env_file: - .env volumes: - .:/usr/src/app - /usr/src/app/node_modules command: npm run dev networks: - proxy
3. 调整EC2安全组规则
两种方案二选一:
- 临时测试方案:在入站规则新增一条配置,允许
0.0.0.0/0访问TCP 3005端口,之后直接访问http://<EC2公网IP>:3005即可 - 生产环境推荐方案:不需要开放3005端口公网访问,安装Nginx做反向代理,把80端口的请求转发到
127.0.0.1:3005,后续配置SSL证书即可走HTTPS 443端口访问,安全性更高。
4. 重启服务验证
重新构建启动容器,先检查日志确认服务正常:
sudo docker-compose up -d --build # 查看服务日志,确认NestJS启动成功、监听3005端口 sudo docker-compose logs -f worker
日志无报错后再通过对应地址访问即可。
额外排查点:如果启动后仍无法访问,检查EC2实例内部系统防火墙(firewalld/ufw)是否开放对应端口,亚马逊Linux2默认放行所有端口,自定义Ubuntu镜像需要手动确认规则。
内容的提问来源于stack exchange,提问作者BeginnerDev
相关产品推荐
相关产品推荐

