如何在Docker Compose中用Redis扩展ExpressJS服务器?遇连接拒绝问题
问题分析与解决方案
核心问题
你的Express应用无法被外部访问,主要有两个关键原因:
1. Express绑定地址错误
从容器日志能看到,应用运行在容器的内部IP(如http://c36ea0029a41:5000),这意味着Express只监听了容器的本地回环地址,主机和外部网络无法直接访问容器内的服务。
2. 多副本端口映射无统一入口
你配置的ports: - 5000会让Docker随机给每个容器分配不同的主机端口(从docker ps能看到是65226-65230),但你可能直接访问了localhost:5000——这个端口并没有被映射到任何容器,所以出现连接拒绝。
解决步骤
第一步:修改Express代码,监听0.0.0.0
确保你的Express应用绑定到0.0.0.0,这样容器外部才能访问:
const express = require('express'); const app = express(); // 你的业务代码... // 关键:监听0.0.0.0而不是localhost或容器IP app.listen(5000, '0.0.0.0', () => { console.log(`Running at http://0.0.0.0:5000`); });
第二步:添加Nginx反向代理实现统一入口
多副本应用需要一个统一的访问入口,用Nginx做负载均衡是标准方案:
- 创建
nginx.conf文件:
events {} http { # 定义后端服务集群,Docker会自动解析url-shortener为所有副本的IP upstream url-shortener-cluster { server url-shortener:5000; } server { listen 80; location / { proxy_pass http://url-shortener-cluster; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } }
- 修改
docker-compose.yml,添加Nginx服务并调整原有配置:
version: '3.7' services: url-shortener: build: context: . dockerfile: Dockerfile volumes: - ./src:/home/node/app/src deploy: replicas: 5 expose: - 5000 networks: - default depends_on: - "redis" command: npm start redis: image: redis:latest networks: - default volumes: - 'redis_data:/bitnami/redis/data' # 添加Nginx反向代理 nginx: image: nginx:alpine volumes: - ./nginx.conf:/etc/nginx/nginx.conf ports: - "5000:80" # 主机5000端口映射到Nginx的80端口 networks: - default depends_on: - url-shortener volumes: redis_data: driver: local networks: default: driver: bridge
验证
重新部署后,访问localhost:5000即可正常访问应用,Nginx会自动把请求转发到5个Express副本,实现负载均衡。
内容的提问来源于stack exchange,提问作者GIA
相关产品推荐
相关产品推荐

