docker环境中redis连接三种场景配置指南,物理机、wsl、docker

本指南详细说明如何将docker项目原本redis服务连接到 三种不同位置的 Redis 服务,并屏蔽项目自带的 Redis 容器。

所有操作前请备份 docker-compose.yml.env 文件。


场景一:连接到 Ubuntu 物理机上的 Redis

适用情况:Redis 直接安装在宿主机(独立的 Ubuntu 物理机或虚拟机)上,Docker 运行在该宿主机上。

1. 检查宿主机 Redis 配置

确保宿主机 Redis 允许 Docker 容器访问(默认只监听 127.0.0.1):

bash 复制代码
# 查看监听地址
sudo netstat -tlnp | grep 6379

如果只显示 127.0.0.1:6379,请修改 /etc/redis/redis.conf

conf 复制代码
bind 0.0.0.0          # 允许所有连接
# 或 bind 127.0.0.1 172.17.0.1   # 仅允许 Docker 网桥

重启 Redis:

bash 复制代码
sudo systemctl restart redis-server

2. 修改 docker-compose.yml

2.1 删除内部 Redis 服务

找到文件中的 redis: 块(约第 158 行),删除或注释。

2.2 删除 app 服务中的 Redis 依赖

app 服务的 depends_on: 中删除 redis: 条目。

2.3 修改 app 的环境变量
yaml 复制代码
app:
  environment:
    # 将 REDIS_ADDR 改为宿主机 IP(Docker 网桥网关)
    - REDIS_ADDR=172.17.0.1:6379
    # 如果宿主机 Redis 有密码,确保 .env 中 REDIS_PASSWORD 正确
    - REDIS_PASSWORD=${REDIS_PASSWORD}
    - REDIS_DB=0

说明172.17.0.1 是 Docker 默认网桥的网关地址,始终指向宿主机。也可以使用宿主机的物理 IP(如 192.168.1.100),但可能因 DHCP 变化而不稳定。

2.4 确保 .env 中的密码匹配
bash 复制代码
REDIS_PASSWORD=your_redis_password

3. 重新部署

bash 复制代码
docker compose down
docker compose up -d

4. 验证

bash 复制代码
# 进入 app 容器测试(容器内可能没有 nc/redis-cli,可用 Python)
docker exec WeKnora-app python3 -c "import socket; s=socket.socket(); s.connect(('172.17.0.1',6379)); print('OK')"

场景二:连接到 WSL 环境中的 Redis 服务

适用情况:Docker 运行在 WSL2 的 Linux 发行版中,Redis 安装在同一个 WSL 实例内(作为宿主机)。

说明:在 WSL 环境中,Docker 容器与 WSL 宿主机共享内核,但网络栈是隔离的。容器访问 WSL 宿主机的服务需要使用 WSL 实例的 IP 或 Docker 网关 IP。

1. 检查 WSL 中 Redis 的监听配置

WSL 中的 Redis 默认只监听 127.0.0.1,需要修改为监听 0.0.0.0 或至少 Docker 网桥 IP:

bash 复制代码
sudo vi /etc/redis/redis.conf

修改:

conf 复制代码
bind 0.0.0.0

重启 Redis:

bash 复制代码
sudo systemctl restart redis-server

2. 修改 docker-compose.yml

2.1 删除内部 Redis 服务及依赖(同场景一)
2.2 修改 app 环境变量

WSL 中有两种可靠的地址:

地址 说明
172.17.0.1 Docker 网桥网关,始终可达
host.docker.internal 需要 extra_hosts 支持(你的配置已添加)

推荐使用 172.17.0.1

yaml 复制代码
app:
  environment:
    - REDIS_ADDR=172.17.0.1:6379
    - REDIS_PASSWORD=${REDIS_PASSWORD}
    - REDIS_DB=0

如果希望使用 host.docker.internal(你的 extra_hosts 已配置),也可:

yaml 复制代码
- REDIS_ADDR=host.docker.internal:6379

3. 重新部署并验证

bash 复制代码
docker compose down
docker compose up -d

# 测试连通性
docker exec WeKnora-app sh -c "echo 'PING' | timeout 2 nc 172.17.0.1 6379"

场景三:连接到指定 Docker 容器中的 Redis 服务

适用情况 :已有一个独立的 Redis 容器(如 xiaozhi-esp32-server-redis),希望 WeKnora 共用。

1. 确认外部 Redis 容器信息

bash 复制代码
docker ps | grep redis

记下容器名(例如 xiaozhi-esp32-server-redis)及其密码(通过查看启动命令或进入容器获取)。

2. 将外部 Redis 容器加入 WeKnora 的项目网络

WeKnora 项目使用自定义网络 WeKnora-network(实际名称可能带项目前缀)。先查看实际网络名:

bash 复制代码
docker network ls | grep WeKnora
# 假设输出:weknora-main_WeKnora-network

连接外部容器到该网络:

bash 复制代码
docker network connect weknora-main_WeKnora-network xiaozhi-esp32-server-redis

3. 修改 docker-compose.yml

3.1 删除内部 Redis 服务及依赖(同前)
3.2 修改 app 环境变量
yaml 复制代码
app:
  environment:
    - REDIS_ADDR=xiaozhi-esp32-server-redis:6379   # 使用容器名
    - REDIS_PASSWORD=${REDIS_PASSWORD}             # 必须与外部 Redis 密码一致
    - REDIS_DB=0
3.3 如果外部 Redis 有密码,更新 .env
bash 复制代码
REDIS_PASSWORD=external_redis_password

4. 重新部署并验证

bash 复制代码
docker compose down
docker compose up -d

# 验证 DNS 解析和连接
docker exec WeKnora-app ping -c 1 xiaozhi-esp32-server-redis
docker exec WeKnora-app python3 -c "import socket; s=socket.socket(); s.connect(('xiaozhi-esp32-server-redis',6379)); print('OK')"

通用注意事项

  1. 删除内部 Redis 后docker-compose.ymlredis: 整个块必须删除或注释,否则 Compose 仍会创建容器。

  2. 依赖关系 :务必删除 app 服务的 depends_on 中的 redis: 条目,否则启动时会等待不存在的服务。

  3. 密码一致性 :外部 Redis 如有密码,.env 中的 REDIS_PASSWORD 必须完全一致(包括大小写、特殊字符)。无密码则留空:REDIS_PASSWORD=

  4. 数据库编号 :通过 REDIS_DB 选择数据库,默认为 0。如果外部 Redis 的 DB0 已被其他应用占用,可改为 1,但需确保 WeKnora 支持。

  5. Langfuse 等可选服务 :如果启用了 --profile langfuse--profile fulllangfuse-workerlangfuse-web 也依赖 Redis,它们通过 REDIS_CONNECTION_STRING 连接,需要同步修改。如果未启用,可忽略。

  6. 网络稳定性

    • 场景一、二中,宿主机 IP(172.17.0.1)在 Docker 重启后可能改变(极少见),建议使用 host.docker.internal(需 extra_hosts 支持,你的配置已提供)。
    • 场景三中,容器名解析依赖 Docker 内置 DNS,只要容器在同一网络即可。
  7. 安全建议

    • 避免将 Redis 暴露到公网。
    • 生产环境务必设置强密码,并考虑使用 Docker 网络隔离。

附录:快速比对表

场景 REDIS_ADDR 需要额外操作 验证命令
物理机 Redis 172.17.0.1:6379宿主机IP 修改 Redis 监听 0.0.0.0 docker exec WeKnora-app python3 -c "import socket; socket.create_connection(('172.17.0.1',6379),2)"
WSL 中 Redis 172.17.0.1:6379host.docker.internal:6379 修改 Redis 监听 0.0.0.0 同上
外部 Redis 容器 <容器名>:6379 将容器加入 WeKnora-network `docker exec WeKnora-app sh -c "echo PING
相关推荐
程序员老赵11 小时前
10 分钟部署 OpenCode:Docker 一键安装,浏览器打开就能用 AI 写代码(附完整命令与排错)
docker·容器·ai编程
WangMingHua11115 小时前
LM Studio Docker 部署——本地大模型一键启动
docker
曲幽2 天前
别再用网页翻译看源码了!你的私人翻译神器LibreTranslate,部署避坑指南来了
python·docker·web·pot·translate·libretranslate·arogstranslate
武子康4 天前
调查研究-183 Apple container:Mac 上用轻量 VM 跑 Linux 容器,Swift 会改写本地容器体验吗?
docker·容器·apple
用户3169353811835 天前
Java连接Redis
redis
小小工匠7 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
Alsn867 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
2601_961875247 天前
决战申论100题2026|最新|范文
linux·容器·centos·debian·ssh·fabric·vagrant
java_cj7 天前
深入kube-apiserver认证机制:从Bearer Token到mTLS的完整认证链解析
linux·运维·服务器·云原生·容器·kubernetes
程序员老赵7 天前
服务器没有桌面?Docker 跑个 Chrome,浏览器就能远程用
docker·容器·devops