☰
Docker Desktop 安装 Redis 全指南:挂载配置、持久化与排障
2026/10/15 5:04:44 网站建设 项目流程

先说个背景:我前后用 Docker Desktop 装 Redis 装了很多次,有帮朋友远程排障的,也有自己开发环境从宿主机切到容器踩坑的。坦白讲,单说“安装”两步就完成了——拉镜像、起容器,但把它调到能长期稳定用于开发、又不污染本机环境,中间有一堆细节容易被跳过。这篇文章把我在 Docker Desktop 里安装 Redis 的完整思路、执行命令、挂载配置、数据持久化,以及那些让人半夜抓狂的报错都梳理一遍,把该解释的原理也解释到位。适合刚接触 Docker、想在 Windows 或 macOS 上跑 Redis 的开发者,也适合已经用 Docker 装过其他镜像、但对 Redis 特定坑还不熟的人。

1. 为什么在 Docker Desktop 里安装 Redis,而不是直接装本体

1.1 和宿主机直接安装 Redis 相比,差别在哪儿

很多人在本机装 Redis,绕不开这三类麻烦。

第一是版本冲突。某个项目用的是 Redis 5,另一个项目要求 Redis 7,如果你直接在宿主机装了 7,再把 5 跑起来,涉及一遍源码编译或者多实例共存,环境很容易乱。第二是清理问题。包管理器装的 Redis 还稍微好一点,如果是编译安装,散落在/usr/local下面的二进制、配置、日志文件,想彻底删干净得手工排查。第三是系统环境被“污染”。本机安装后默认开机自启、注册成服务,有时候你只是想临时用一下,它却常驻在后台。

换成 Docker Desktop 之后,本质上是在操作系统上划出一块隔离区:Redis 只活在容器里,宿主机上只有一个 Docker Desktop 守护进程在跑。想用某个版本就拉对应 tag 的镜像,想换版本就停掉旧容器、起一个新容器。所有中间产物都在容器内部,删容器就是连环境一起删,宿主机还是干净的。

这个隔离方式有个很贴切的类比:宿主机就像你的租住房,你在墙上钉个钉子(装全局依赖)容易留下痕迹、损坏墙面;而 Docker 容器就像房间里放了一个收纳箱,所有东西都装进箱子里,箱子扔掉后房间原样。

1.2 容器化 Redis 的“可复现性”优势

另一个我非常看重的点是可复现。本地开发时,你写了一个用到 Redis 的功能,代码提交给同事后,对方如果本机没装 Redis,或者装了但版本不一致,运行结果可能就对不上。而 Docker 容器把 Redis 的版本、配置文件、启动参数都固化在一个镜像描述里——拉同一个镜像、挂同一份配置,基本上能保证在不同电脑上跑出相同状态。

我之前在某个模拟项目里需要同时对比 Redis 6 和 Redis 7 的某些行为差异,宿主机方案要先改端口、再改配置、还可能两个版本互相干扰。用 Docker 就很直接:

docker run -d --name redis6-test -p 6380:6379 redis:6.2 docker run -d --name redis7-test -p 6381:6379 redis:7.2

两条命令,两个实例互不干扰。用完直接docker rm -f redis6-test redis7-test,连痕迹都不留。这种体验用久了回不去,也是我建议开发期“能用容器解决的依赖都尽量用容器”的原因。

1.3 Docker Desktop 在 Windows 和 macOS 上的底层差异

Docker Desktop 不是直接在宿主机上跑 Linux 内核,而是依赖虚拟化技术在系统里构建一个 Linux 运行环境。macOS 上它使用轻量虚拟机;Windows 上通常基于 WSL 2 后端。

这个差异对现在的操作有两个影响。一个是路径挂载:Windows 的路径是C:\Users\xxx\redis\redis.conf这种,挂载时要用反斜杠或者转义;macOS 的路径是/Users/xxx/redis/redis.conf,直接写就行。另一个是文件权限感知:Windows 下容器对挂载文件的权限处理比较宽松,macOS 下偶尔会遇到挂载文件权限被映射得比较奇怪的问题。

后文涉及具体命令时,我会把 Windows 和 macOS 的差别标出来。只要不涉及挂载路径,两者的 Docker 命令行为是一致的。

2. Docker Desktop 安装与基础环境准备

2.1 安装过程最容易忽略的几个检查项

如果你还没装 Docker Desktop,去官网下载对应系统的安装包,双击安装即可。这里提醒几个我见过很多人忽略的检查项。

安装完成的标志不是图标出现,而是命令行能正常跑通:

docker version

如果docker: command not found,先检查安装时是否勾选了“添加到 PATH”之类选项,或者重新打开终端再试。Windows 上有一个很常见的坑:Docker Desktop 安装好了,但 WSL 2 内核没更新,启动时一直提示 WSL kernel version too low。解决办法是运行一次 WSL 2 内核更新包,或者在 PowerShell 里执行wsl --update。

macOS 上则是另一个常见问题:Docker Desktop 图标点开后,左上角一直转圈。这时候多半是因为没有给 Docker Desktop 开启“文件共享”权限,或者虚拟机平台权限不足。到“系统设置 - 隐私与安全性”里把 Docker 需要的权限打开,通常就能解决。

然后验证守护进程是否正常:

docker info

能看到Server Version这类信息就说明正常。如果报Cannot connect to the Docker daemon,大概率是 Docker Desktop 没有启动,或者 Windows 上 WSL 后端崩了。重启 Docker Desktop 之后再试。

2.2 配置公共镜像加速服务,避免拉镜像卡住

安装 Redis 的第一步是拉取官方 Redis 镜像。很多人在这一步就卡住:docker pull redis半天不动,或者断断续续超时。这不是 Docker 本身的问题,而是因为默认的镜像仓库在部分网络环境下连接速度不稳定。

Docker Desktop 提供了一个设置入口可以配置 registry mirror。以我日常使用的版本为例,打开 Docker Desktop 的 Settings(设置),找到 Docker Engine 一项,这里实际上是在编辑一个 JSON 格式的守护进程配置。

在 JSON 里加入一段:

{ "registry-mirrors": [ "https://docker-mirror.example.com" ] }

注意:docker-mirror.example.com是一个示例地址,你需要把它换成你所处网络环境实际可用的公共镜像加速地址,比如你使用的云服务商提供的加速服务地址。配置完成后点击 Apply & Restart,Docker Desktop 会重启守护进程。

重启后怎么确认生效?执行:

docker info

在输出里找到Registry Mirrors这一行,如果列出了刚才填的地址,说明配置成功。这之后再拉取 Redis 镜像,速度会有非常明显的改善。

另外提一句,如果是在公司内网环境,还需要检查防火墙是否允许访问镜像仓库所在域名。有些企业网络对 443 端口有白名单限制,Docker 客户端拉镜像会直接卡在“等待响应”阶段,这时候配置镜像加速服务也可能救不了,可能需要联系网络管理员开通访问权限。

2.3 装完 Docker Desktop 后先跑一个最小验证

正式安装 Redis 之前,我建议先用一句话验证整个链路通不通。比如拉取一个最小镜像并临时运行:

docker run --rm hello-world

这个镜像不会常驻,跑完打印一段提示就退出。如果它能正常显示信息,说明 Docker 的拉取、容器创建、运行、清理四个环节都通了。此时再进入 Redis 的安装流程,排障范围会小很多。

3. 安装 Redis 容器:从拉镜像到跑起来

3.1 拉取 Redis 镜像,并理解版本标签

基础命令是:

docker pull redis:7.2

为什么不直接docker pull redis?因为不带标签默认拉取latest标签,而latest是会往前滚动的。今天你拉的是 7.x,明年它可能变成 8.x 或者某个新特性版本,配置文件行为可能发生变化,你的项目却还按旧版本逻辑在写。指定具体版本号,比如redis:7.2,能让环境稳定下来,也方便后续团队统一版本。

Redis 官方镜像对体积也做过分层优化。如果只是本地开发和跑单机功能,可以用 alpine 变体:

docker pull redis:7.2-alpine

alpine 镜像体积比标准版小不少。但它背后是一个精简 Linux 环境,里面的 shell 不是 bash,进入容器调试时会略有不同。比如docker exec -it 容器名 sh,用sh而不是bash。日常使用不受影响。我个人的习惯是:本地开发用redis:7.2,因为调试时工具更全;部署到线上的容器镜像再针对实际情况选择更适合的精简变体。

3.2 首个 Redis 容器:端口映射和后台运行

拉完镜像后,第一次启动我建议用这样一条命令:

docker run --name my-redis -p 6379:6379 -d redis:7.2

拆开看。--name my-redis给容器起一个固定名字,后面所有操作都可以通过这个名字引用,不用记一串随机的容器 ID。-p 6379:6379是把宿主机的 6379 端口映射到容器的 6379 端口。容器内 Redis 默认监听 6379,但容器有自己的网络命名空间,宿主机默认访问不到,必须做端口映射才能通过本机地址访问。-d表示后台运行,终端不会卡在日志输出上。

启动完成后验证容器状态:

docker ps

STATUS显示Up就说明正常。此时测试 Redis 是否能响应。不过一个现实问题:宿主机上不一定装了 redis-cli,所以我通常直接用容器内的客户端测试:

docker exec -it my-redis redis-cli ping

这个命令的含义是在运行中的my-redis容器内部执行redis-cli ping。如果返回PONG,说明 Redis 服务端正常。

还有一种测试方式是用一个临时容器来连接,适合那种不想记录复杂命令的情况:

docker run --rm -it --network host redis:7.2 redis-cli -h 127.0.0.1 ping

--network host让临时容器直接使用宿主机网络,所以它能访问到刚才映射在本机 6379 端口的 Redis。--rm表示这个临时容器用完后自动删除,不会残留。

3.3 设置访问密码:两种合理的传参方式

默认情况下,刚启动的 Redis 没有访问密码。在本地开发环境可能无所谓,但如果你的宿主机本身开启了端口转发,或者 Redis 监听在非 loopback 地址上,那最好加上密码。

最直接的方式是在启动命令中追加 Redis 参数。Redis 官方镜像的默认启动命令是redis-server,你可以在docker run的最后追加参数来覆盖它:

docker run --name my-redis -p 6379:6379 -d redis:7.2 redis-server --requirepass yourpassword

这里redis-server后面的--requirepass yourpassword会被传进去。验证方式:

docker exec -it my-redis redis-cli -a yourpassword ping

返回PONG就说明密码生效。不加-a直接 ping 会报NOAUTH Authentication required。

为什么不用环境变量传密码?因为官方 Redis 镜像并没有为requirepass提供专用的环境变量入口,只有通过命令行参数或配置文件两种选择。如果你觉得每次启动命令都带密码太长,可以把配置写进 redis.conf,后文会讲。

3.4 数据持久化:让 Redis 重启后不“失忆”

Redis 有一个很容易被新手忽视的特征:容器默认是可以随时被删除和重建的,但如果你不主动做数据持久化,容器删除后数据就全没了。

目录映射的意思可以这样理解:宿主机上有一个目录或数据卷,相当于移动硬盘;容器内的/data目录,相当于电脑硬盘。移动硬盘上存着数据,只要你不把移动硬盘扔掉,哪怕电脑换一台,插上去数据都还在。

启动时用-v参数完成挂载:

docker run --name my-redis \ -p 6379:6379 \ -v redis-data:/data \ -d redis:7.2

这里的redis-data是 Docker 管理的命名卷。和直接挂载宿主机路径不同,命名卷不关心你的操作系统目录结构,Docker 会自己找一个内部位置存储。

Redis 镜像默认配置了持久化策略,RDB 快照会写到容器内的/data目录。我把/data挂载成命名卷redis-data后,即使容器被删除,再用同样挂载方式起一个新容器,之前的 key 都还在。

如果想更直观地在宿主机上看到数据文件,也可以使用路径挂载:

docker run --name my-redis \ -p 6379:6379 \ -v /absolute/path/to/redis-data:/data \ -d redis:7.2

注意宿主机路径必须写绝对路径,相对路径在部分 Docker Desktop 版本上会报错。Windows 上类似:

-v C:\dev\redis\data:/data

3.5 挂载自定义 redis.conf,以及那个让人困惑的 daemonize 问题

当你不满足于默认参数,想修改maxmemory、appendonly、bind等配置时,最清晰的做法是准备一份自己的 redis.conf,挂载进容器。比如在宿主机创建/opt/redis/conf/redis.conf,然后在启动命令里挂载:

docker run --name my-redis \ -p 6379:6379 \ -v /opt/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf:ro \ -v /opt/redis/data:/data \ -d redis:7.2 \ redis-server /usr/local/etc/redis/redis.conf

这里面有几个点要特别提醒。

:ro表示只读挂载。配置信息在容器运行期间不需要改动,防止容器内部误写配置文件;如果不加,某些 Redis 版本执行CONFIG REWRITE时可能会尝试写回挂载文件,引发一些意外的文件权限问题。

redis-server /usr/local/etc/redis/redis.conf是覆盖默认启动命令,改为显式加载挂载的配置文件。这一步必须加,因为镜像默认启动命令是读镜像内部的默认配置,你即使挂载了自定义配置文件,不指定它也不会被 Redis 读取。

还有一个很隐蔽、但几乎每个用过宿主机 redis.conf 挂进 Docker 的人都踩过的坑是daemonize。

如果你的 redis.conf 是从宿主机拷贝来的,里面往往带着daemonize yes。在宿主机环境下这是合理的,因为作为系统服务它需要后台运行。但在容器里,daemonize yes会让 Redis 进程 fork 到后台,前台进程直接退出,而容器的生命周期绑定的是前台进程——前台进程一退出,容器就停了。你看到的现象就是:容器起来后秒退,或者一直处于Restarting状态。

在容器里的正确做法是:

daemonize no

如果配置文件里没有这一项,也可以不写,因为 Redis 默认就是daemonize no。我把这个叫作“配置文件进容器三要素”:daemonize no、appendonly按需开启、bind按需设定,这三项决定了容器能不能稳跑、数据靠不靠谱、外部能不能连接。

4. 连接 Redis、验证持久化和数据卷管理

4.1 进入容器执行 redis-cli 常用命令

容器跑起来后,日常高频操作有两种:进容器敲命令,以及从宿主机或局域网电脑远程访问。

进容器用:

docker exec -it my-redis sh

my-redis换成你的容器名。由于基础镜像大多是 Debian 系列或 alpine,进入后 shell 名称可能是sh而不是bash。进到容器里,常用 Redis 命令是这样:

redis-cli ping redis-cli info server redis-cli dbsize redis-cli get somekey

这些命令实际上是在容器内直接访问 Redis 的本地环回地址,所以不需要指定 IP 和端口。

如果不进容器,只想从外部探一下 Redis 是否可用,也可以用:

docker exec -it my-redis redis-cli ping

这种方式把命令直接传给容器内执行,输出在宿主机终端展示,很适合快速健康检查。

4.2 验证持久化是否真的生效

很多人跑完持久化挂载后,什么都不验证就认为数据安全了。其实验证成本很低。

第一步,在容器里写入一个测试 key:

docker exec -it my-redis redis-cli set persistent-test "hello"

第二步,查看数据目录里是否出现 RDB 文件。进入容器执行:

docker exec -it my-redis sh -c "ls -lh /data"

正常情况下可以看到dump.rdb,或者如果你开了 AOF,会看到appendonly.aof。

第三步,重启容器再查数据:

docker restart my-redis docker exec -it my-redis redis-cli get persistent-test

如果返回"hello",说明持久化链路是通的。这一步非常值得在正式操作前跑一遍,尤其是你已经存了大量业务数据之后再排查持久化问题,成本就高了。

4.3 宿主机没有 redis-cli 时,怎么从外部访问

有些时候你不想每次都用docker exec进容器,而是想从宿主机直接用 Redis 客户端连。如果宿主机本身装了 redis-cli,直接:

redis-cli -h 127.0.0.1 -p 6379 -a yourpassword

如果宿主机没装 redis-cli,也不想为了访问 Redis 再装一个依赖,可以借用容器里的客户端。我常用的一种方式是起一个临时的 Redis 容器来当客户端:

docker run --rm -it --network host redis:7.2 redis-cli -h 127.0.0.1 -p 6379

--network host让这个临时容器直接共享宿主机网络,所以它访问 127.0.0.1 的 6379 端口就等于访问宿主机上映射的 Redis 端口。用完即删,不会在宿主机留下任何客户端软件。

讲究一点的话,也可以用图形化客户端,比如 RedisInsight 或一些其他跨平台连接工具。连接参数就是宿主机地址127.0.0.1、端口6379、密码。这类工具对查看 key 的 TTL、内存分析、慢日志非常友好,适合排查线上问题时的本地复现。

4.4 数据卷的清理和备份

容器可以随便删,但数据卷不会因为容器删除而被自动清理,这是设计上的安全机制。想清理不需要的数据卷:

docker volume ls docker volume rm redis-data

执行rm之前务必确认里面没有业务数据。在开发环境这一条还好,但曾经有同事在测试环境把 Redis 的卷误删,导致一堆开发数据丢失,那几个小时都在重新灌数据。我的建议是定期对卷做备份,方式很简单,起一个临时容器把卷内容打包出来:

docker run --rm -v redis-data:/data -v /absolute/path/backup:/backup alpine tar czf /backup/redis-data.tar.gz -C /data .

恢复时反向操作:

docker run --rm -v redis-data:/data -v /absolute/path/backup:/backup alpine tar xzf /backup/redis-data.tar.gz -C /data

5. 高频问题排查实录

5.1 端口被占用:EADDRINUSE

启动容器时报错:

bind: Address already in use

大概率是宿主机 6379 端口已经被别的进程占了。Windows 上很常见的情况是之前装过 Redis 服务并设置了开机自启;macOS 上可能是某个调试程序误用了 6379;还有一些开发框架会把 6379 作为默认端口启动本地缓存。

排查端口占用:

  • Windows:netstat -ano | findstr 6379,最后一列是 PID,再到任务管理器里查这个 PID 对应什么进程。
  • macOS:lsof -i :6379,找到占用端口的进程,kill掉或者停掉对应服务。

如果你不想动那个占用端口的进程,最省事的方案是换个宿主机端口映射:

docker run --name my-redis -p 6380:6379 -d redis:7.2

这样 Redis 容器内的 6379 保持不变,宿主机通过 6380 访问。对于本地开发来说,端口号换一下影响很小,改一下客户端连接配置就行。

5.2 容器一直在 Restarting 状态

docker ps看到一个容器,但STATUS从Up变成类似Restarting (1) ...,十有八九是启动命令或配置文件有问题。

第一步是看日志:

docker logs my-redis

如果看到:

Can't open the log file: Permission denied

说明容器内用户没有权限访问挂载的日志目录或文件,这时需要检查宿主机挂载目录的权限。Linux 和 macOS 下通常是权限位问题,Windows 下较少见。

如果看到:

# Fatal error, can't open config file

说明你在docker run末尾指定的 Redis 配置文件路径不对,或者挂载路径写错,容器里根本找不到这个文件。排查办法是先从docker exec进入容器,确认/usr/local/etc/redis/redis.conf是否存在。

还有一个高频原因就是我们前面提过的daemonize yes。日志里不一定有明确报错,但容器起来个几秒就退出,反复重启。把配置文件里的daemonize改成no,问题就解决了。

5.3 连接被拒绝或密码验证失败

本地访问 Redis 时最常遇到两种报错。

Connection refused说明 Redis 服务端没有在你访问的地址和端口上监听。先确认容器是否在跑:docker ps。再确认端口映射是否存在:docker port my-redis,如果没有任何输出,说明当时启动容器时-p参数没生效。如果端口映射在,但 Redis 的配置里写了bind 127.0.0.1且你在容器外部连接,也可能出现拒绝连接。容器内 Redis 监听的 127.0.0.1 是容器自己的 loopback 地址,外部流量到达不了那里。解决办法是修改配置:

bind 0.0.0.0

或者干脆注释掉bind行,让 Redis 监听所有网络接口。不过这样做之后,建议必须配合requirepass使用,否则同一局域网内的其他机器都能访问到你的数据。

NOAUTH Authentication required则是密码没对上。检查启动命令里是否真的传入了--requirepass,或者配置文件里的requirepass是否被注释。如果用图形化工具连接,还要注意工具保存的密码可能过期,重新输入一次再试。

5.4 防火墙或防病毒软件拦截

Windows 上还有一个容易被忽视的坑:宿主机防火墙拦截了对 6379 端口的访问。Docker Desktop 在安装时通常会添加自己的防火墙规则,但如果你换过网络类型或者手动改过防火墙策略,可能导致本机可以docker exec访问 Redis,但外部工具连接被拒。

排查思路很简单:先用docker exec -it my-redis redis-cli ping确认容器内 Redis 正常;再在宿主机上用redis-cli -h 127.0.0.1 -p 6379 ping或图形化工具测试外部访问。如果容器内正常、外部失败,优先怀疑防火墙、防病毒软件或者 WSL 网络转发问题。

5.5 镜像无法拉取或拉取非常慢

前面讲了配置公共镜像加速服务。如果配置盘中地址填错了,docker info里Registry Mirrors就不会变化。另一个需要注意的是,修改registry-mirrors后必须重启 Docker Desktop,光保存 JSON 是不生效的。

如果加速服务地址正确但拉取某些镜像仍然失败,可以尝试清空本地缓存:

docker system prune -a

这条命令会删除所有未使用的镜像和容器,缓存清掉后重新拉取。执行前确认没有正在使用的容器,避免误删。如果拉取过程总是超时,也可以换一个不同的公共镜像地址再试。加速服务的可用性有时候和运营商网络有关,同一个地址在不同网络环境下的表现可能差异很大。

6. 更进一步:用 docker compose 把 Redis 开发环境固化下来

6.1 一个可以直接落地的 compose 配置

当 Redis 的启动参数、挂载目录、配置文件组合开始变得多的时候,docker run命令会越来越长,敲着也容易出错。这时候推荐把环境定义写进docker-compose.yml,放进项目仓库,团队成员拉下来就能一键启动。

下面是一个我在模拟项目中用过的配置模板:

services: redis: image: redis:7.2 container_name: dev-redis restart: unless-stopped ports: - "6379:6379" volumes: - redis-data:/data - ./redis.conf:/usr/local/etc/redis/redis.conf:ro command: ["redis-server", "/usr/local/etc/redis/redis.conf"] healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 volumes: redis-data:

启动:

docker compose up -d

停止并移除:

docker compose down

注意docker compose down默认不会删除数据卷redis-data,所以数据不会丢。如果想连数据卷一起清理:docker compose down -v,这个操作要谨慎,会连同 Redis 中的数据一起删除。

6.2 compose 带出来的三个额外好处

第一个好处是配置进版本库。redis.conf、compose 文件都可以提交到 Git,换成新电脑或者在 CI 环境里复现 Redis 环境时,只要拉代码再up -d,环境就是一致的。

第二个好处是 healthcheck 内置了。compose 里定义的健康检查,会在 Redis 处于可以被redis-cli ping响应的状态后才标记为 healthy。配合依赖该服务的其他容器使用depends_on加condition,可以避免下游服务在 Redis 还没就绪时就开始启动。

第三个好处是方便切换配置。比如开发环境用7.2,某次需要验证一个 6.2 下的行为,改一行image: redis:6.2再up -d就能完成整体环境切换。

我自己的使用习惯是:临时验证用docker run,固定项目依赖一律用 compose。倒不是docker run不好,而是当项目里有后端服务、消息队列、Redis 等一串依赖时,compose 能让你一条命令拉起来一整条链路,这也是日常开发效率提升最明显的地方。

写在后面的一点经验

我最后想强调的其实是“带密码和持久化”这两件事。很多教程跑完docker run -d redis就结束了,但如果你只要重启一次容器或者给局域网提了一个端口转发,就会发现没配密码、没挂数据卷的 Redis 有多脆弱。至少养成两个习惯:启动命令里留好--requirepass,配置里设好appendonly yes并挂载/data。我的做法是第一次起容器时就写好一个 redis.conf 并挂载进去,把daemonize no、appendonly yes、requirepass一次性配好,之后再也不用担心容器重建时把配置重新敲一遍。如果你还打算在项目里维护这套环境,趁早把docker-compose.yml建起来,它会比一长串docker run参数可靠得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询