Docker容器内Go应用无法连接Redis Stack问题求助
Redis连接被拒问题排查
你的部署环境Redis连接失败是3个配置错误共同导致的,按以下步骤修改即可恢复:
- 端口映射完全错误:Redis Stack官方镜像默认在容器内监听
6379端口提供Redis服务,8001是可视化管理界面端口,你之前把容器端口映射写为6378:6378,相当于容器内根本没有服务在6378端口运行,连接请求自然被拒绝。 - Compose配置格式错误+依赖缺失:原docker-compose.yaml缩进混乱,redis、rabbitmq服务没有被正确纳入services层级;同时你的业务服务
exam-service只配置了postgres的依赖与网络链接,没有关联redis、rabbitmq服务,容器内部DNS无法正常解析服务地址,网络也没打通。 - 配置文件格式错误:App.env中
REDIS_DB_NAME=0#Default DB没有在注释前加空格,viper读取时会把注释内容当成配置值的一部分,拿到的DB编号不是预期的0;另外容器间通信应当使用服务内部端口,而非映射到宿主机的对外端口,之前的端口配置逻辑搞反了内外端口的使用场景。
修复方案
1. 修正docker-compose.yaml
对齐缩进,修正端口映射,补全服务依赖,修正数据卷挂载路径,改后内容如下:
version: "3.3" services: postgres: container_name: student-grades image: postgres:latest environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: 38043 POSTGRES_DB: postgres ports: - "5432:5432" volumes: - pgdata:/var/lib/postgresql/data restart: unless-stopped redis: container_name: exam-db image: redis/redis-stack ports: # 右侧为容器内部固定监听端口,左侧为宿主机映射端口可自定义 - "6378:6379" - "8001:8001" volumes: - redisdata:/data restart: unless-stopped rabbitmq: image: rabbitmq:3-management container_name: RabbitMQ volumes: - rabbit-data:/var/lib/rabbitmq ports: - "5672:5672" - "15672:15672" restart: unless-stopped exam-service: container_name: exam-service image: eyadzz/dexam_exam_service ports: - "8888:8888" depends_on: - postgres - redis - rabbitmq env_file: - ./App.env volumes: redisdata: pgdata: rabbit-data:
2. 修正App.env配置
调整Redis端口为容器内部端口,修复注释格式:
# Server SERVER_PORT=:8888 # config DEVELOPMENT=true # Redis DB REDIS_DB_HOST=redis # 容器内访问Redis走内部默认端口6379,和宿主机映射的6378无关 REDIS_DB_PORT=6379 REDIS_DB_PASSWORD= # 注释前必须加空格,避免被viper识别为配置值 REDIS_DB_NAME=0 # Default DB # PG DB PG_DB_HOST=postgres PG_DB_PORT=5432 PG_DB_USER=postgres PG_DB_PASSWORD=38043 PG_DB_NAME=postgres # Rabbitmq RABBITMQ_HOST=rabbitmq RABBITMQ_PORT=5672
3. 调整Go代码的地址拼接逻辑
把端口配置改为纯数字读取,拼接时自动补冒号,避免后续配置漏写冒号引发格式错误:
func getRedisDbConnection() (*redis.Client, *rejson.Handler) { redisDb := redis.NewClient(&redis.Options{ Addr: fmt.Sprintf("%s:%d", viper.GetString("REDIS_DB_HOST"), viper.GetInt("REDIS_DB_PORT")), Password: viper.GetString("REDIS_DB_PASSWORD"), DB: viper.GetInt("REDIS_DB_NAME"), }) _, err := redisDb.Ping().Result() if err != nil { log.Println("Can't connect with Redis database", "Errors:", err) } else { log.Println("Redis Db is connected", "Errors:", err) } redisJsonDb := rejson.NewReJSONHandler() redisJsonDb.SetGoRedisClient(redisDb) return redisDb, redisJsonDb }
关键提醒:Docker Compose部署场景下,容器之间互相访问走的是容器内部网络,直接用服务名+容器内部监听端口即可;映射到宿主机的端口仅用于宿主机、外部机器访问服务,容器间通信用不上。
所有配置改完后,先执行docker compose down -v清理之前错误创建的容器、网络和存储卷,再执行docker compose up -d重新启动服务,Redis即可正常连接。
内容的提问来源于stack exchange,提问作者Eyad Youssef
相关产品推荐
相关产品推荐

