☰
Docker Compose 部署 Redis:从配置到持久化的完整实践
2026/10/19 9:33:30 网站建设 项目流程

自己电脑上装Redis,敲几条命令就完事。可一旦要面对几台服务器、多个环境,还要求版本一致、配置可复现,事情就完全变了样。手动编译要处理编译依赖和系统库兼容,直接用系统包管理器安装又常常拿到很老的版本,更别提团队里每个人跑个容器环境还得先折腾半天。用 docker compose 把 Redis 跑起来,是我这些年比较省心的一套方案:镜像官方维护、配置跟着文件走、数据通过卷挂在宿主机上,新机器拉下代码后一条命令就能把完整环境拉起来。

这篇文章没有多高深的东西,纯粹是把我安装 Redis 时的实际过程和踩过的坑拿出来,一步步拆给你看。里面用到的 compose 配置和 redis.conf 都是可以直接复制修改的版本,不管你是刚上手 Docker,还是已经在生产环境用容器跑服务,应该都能从中找到有用的细节。

1. 为什么推荐用 docker compose 管理 Redis

1.1 传统安装方式的痛点

很多人最开始接触 Redis,是在自己电脑上apt install redis-server或者brew install redis,一条命令装完就能跑。这种方式在单机开发时确实省事,但换到稍微正式一点的场景就暴露问题了。

先说版本。系统源里的 Redis 版本往往滞后,比如一些长期支持版 Linux 自带的源里还是老版本,而老版本在集群支持、AOF 重写机制、内存碎片处理上都有差距。你本机测不出来,等到上集群或者迁移数据时才被发现。

再说配置同步。Redis 很多参数是部署时调的,比如maxmemory、appendonly、requirepass,这些配置散落在各台机器的/etc/redis/redis.conf里。今天在这台机器上加了个参数,三天后又换了一台新服务器,你很难保证两边的配置是一样的。我见过不止一次因为配置不同步导致的行为差异,看起来像"玄学",查到最后全是配置漂移。

还有升级回滚。直接装出来的 Redis,升级要么覆盖二进制,要么重编,出问题时想回到旧版本非常麻烦。如果你在跑生产,这种"上了就回不去"的感觉会让人很紧张。

1.2 compose 方案解决了什么问题

docker compose 给 Redis 部署带来的最大变化,是"配置即代码"。你的镜像版本、端口映射、数据目录、启动参数全写在一份docker-compose.yml里,配合一份redis.conf,整个环境就完全被"钉死"了。

这份文件可以放进 git 仓库,跟着项目代码一起管理。同事本地、测试服务器、生产服务器,只要拉同一份文件,执行docker compose up -d,跑出来的 Redis 在版本和配置上就是一致的。换机器或者重装环境时,不用再对着历史命令回忆当初是怎么配的。

另一个实际好处是镜像层级的升级回滚。想从 Redis 7.0 升到 7.2,改一下 compose 里的镜像 tag,执行docker compose up -d,容器重建后就是新版本。如果升出问题了,把 tag 改回去再执行一遍,基本就恢复了。数据因为挂在卷上,一般不受影响。

依赖隔离也很重要。Redis 本身依赖少,但如果你在一个跑着各种服务的宿主机上折腾编译,难免遇到库版本冲突。容器里面各装各的,互不干扰。

2. 部署前的环境准备

2.1 确认 Docker 与 Compose 版本

动手之前建议先确认一下环境。打开终端执行:

docker --version docker compose version

这里有第一个容易混淆的点:docker-compose(带横杠)和docker compose(空格)。老版本使用独立二进制docker-compose,是 Python 写的;新版本使用docker compose,是 Docker CLI 的原生插件,解析速度快、功能也全。如果你看到docker-compose version提示找不到命令,先试试docker compose version,不要再跑去装旧的 Python 包。

Docker Engine 版本建议 20.10 以上。Compose V2 在 20.10 之后的标准插件里基本都包含了。太老的 Docker 内核运行新镜像或使用某些卷驱动时,会遇到权限或兼容问题,升级比较省心。

还有一个注意点:Compose 文件里的version字段。在新版 compose 里,这个字段已经标记为可选,而且官方建议不要再写了。不过考虑到很多人手头还有旧模板,我在下面的示例里省略了它,如果你保留version: '3.8'也能跑,只是现在没必要。

2.2 安装 Docker 并启用 Compose 插件

如果是全新机器,直接安装带 compose 插件的那一套。以 Debian 系为例,核心安装步骤大致是:

sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod a+r /etc/apt/keyrings/docker.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

这里的docker-compose-plugin就是 compose V2 的插件包。装完再验证:

docker compose version

能输出版本号就说明 Compose 部分没问题。其它 Linux 发行版的安装方式大同小异,主要差别在包管理器和仓库地址的配置上。如果是 mac 或 Windows,直接装桌面版 Docker 就行,里面已经内置了 compose。

安装完成后,建议顺手把当前用户加入 docker 组,省得每次敲命令都要带sudo:

sudo usermod -aG docker $USER

这个操作需要退出重新登录一次才生效。我没有在任何容器环境里用 root 直接跑的习惯,但如果你用的是 root 系统,这步可以跳过。

2.3 项目目录规划

Redis 虽然是一个服务,但我不建议直接裸跑docker run,生产环境或者长期维护的项目,还是把目录结构先规划好比较舒服。我常用的结构是这样:

mkdir -p ~/docker/redis/{data,conf}

data目录用来放 Redis 的持久化文件,conf目录放redis.conf。接下来写的 compose 文件和数据卷挂载,都围绕这两个目录展开。这样的好处是整个 Redis 的运行环境收敛到一个文件夹里,备份、迁移、随手打包都很方便。

3. compose 文件与核心配置解析

3.1 最小可用的 docker-compose.yml

下面这份是我目前在用的基础模板,直接复制修改即可:

services: redis: image: redis:7.2-alpine container_name: redis restart: unless-stopped ports: - "6379:6379" volumes: - ./data:/data - ./conf/redis.conf:/etc/redis/redis.conf:ro command: ["redis-server", "/etc/redis/redis.conf"] environment: - TZ=Asia/Shanghai

逐个参数解释一下。

image: redis:7.2-alpine用的是官方 redis 镜像的 Alpine 变体,体积小,跑起来资源占用也低。如果不需要 Alpine,直接redis:7.2也行,区别是默认带的是 Debian 基础系统,系统工具多一点。实际使用中,Alpine 版本在绝大多数场景完全够用。

container_name我建议写固定名称。好处是后面执行docker exec redis redis-cli ping之类的命令时,不用每次查容器名。如果你打算在一台机器上同时跑多个 Redis 实例,那就去掉这个字段,让 compose 自动生成带项目前缀的名字,避免冲突。

restart: unless-stopped表示容器异常退出时自动拉起,但如果你手动执行过docker compose stop,它不会被拉起来。这个策略比较贴合常驻服务的需要。

端口映射"6379:6379",左边是宿主机端口,右边是容器端口。如果宿主机端口被占用,改成"16379:6379"就能规避。注意如果 Redis 配置里改了端口,右边要跟着改。

卷挂载这里有两个:./data:/data把宿主机 data 目录挂到容器内 Redis 官方镜像默认的数据目录;./conf/redis.conf:/etc/redis/redis.conf:ro把配置文件只读挂载进容器。这里加:ro很有必要,防止容器内部意外修改配置,想改配置时直接在宿主机改完再重启容器。

最后通过command覆盖默认的启动命令,让 redis-server 用我们挂载进去的配置文件启动。这是整个 compose 里比较关键的一步,不加这个,容器会用镜像内置的默认配置,外面挂载的 redis.conf 就不生效。

3.2 redis.conf 中该开哪些配置

这是我常用的conf/redis.conf基础内容:

bind 0.0.0.0 protected-mode no port 6379 appendonly yes appendfilename "appendonly.aof" save 900 1 save 300 10 save 60 10000 loglevel notice # requirepass yourpassword

bind 0.0.0.0这条要特别说。容器里 Redis 的视角是容器内网,默认 bind 127.0.0.1 的话,外面永远连不进来。很多新手在这卡很久:进容器里redis-cli ping是通的,宿主机或者别的程序就是连不上,原因就在这。

protected-mode在外部访问和没有密码的场景下会干扰连接,我这里直接关掉。如果你为 Redis 设置了密码,也建议按实际网络环境确认是否需要调整。

appendonly yes打开 AOF 持久化。这个放到下面单独讲。save那几行是 RDB 快照策略,维持默认就是。logfile ""表示日志输出到标准输出,这样docker compose logs redis就能看到日志。

密码方面,我个人的习惯是能用网络隔离解决就尽量不依赖requirepass。因为密码写在配置文件里,一旦文件泄露就等于账号泄露。容器内部署时,更常见的方式是通过内网访问限制来保证安全。当然,如果你必须把 6379 暴露到公网,那requirepass一定要开,而且密码要足够长。

3.3 数据持久化:RDB 与 AOF 的取舍

Redis 持久化有两条路线,很多新手不太清楚,这里解释清楚。

RDB 是周期性快照。Redis 根据save策略把内存里的数据整体序列化,写入dump.rdb。优点是文件紧凑、恢复速度快;缺点是两次快照之间如果进程挂了,这段时间的写入会丢。

AOF 是追加日志。每个写命令都会被记录到appendonly.aof文件里,恢复时重放日志就行。数据可靠性高很多,但文件比 RDB 大,恢复速度慢一些。Redis 7.x 的 AOF 重写机制已经很成熟,文件体积膨胀的问题控制得不错。

生产环境我建议两者同时开,也就是默认的 RDB 策略保留,再把appendonly yes打开。Redis 启动时优先加载 AOF,没有 AOF 才加载 RDB。如果你的场景允许丢几秒数据,只开 RDB 也够;如果一点都不敢丢,那必须 AOF。

还有一个细节:appendfsync策略可以进一步调,默认是everysec,也就是每秒刷一次盘。追求极致性能可以改成no,追求更强可靠性可以改成always。大多数场景保持默认就好。

3.4 健康检查与资源限制

如果只是本地跑跑,compose 上面那份模板就够了。但部署到要长期运行的机器上时,我会再补两段。

健康检查:

healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 30s timeout: 5s retries: 3

这个健康检查会让 compose 定期执行redis-cli ping,能回 PONG 就认为健康。docker compose 里查看状态时,health列会显示healthy还是unhealthy,对排查问题很有用。

资源限制:

deploy: resources: limits: cpus: '0.5' memory: 512M

注意deploy在docker compose up下是生效的。限制 CPU 和内存可以防止 Redis 在内存无限增长时把宿主机拖垮。不过内存限制要配合 Redis 的maxmemory参数一起思考,如果容器分配到 512M,Redis 自己的maxmemory最好限制在 400M 以内,留一点给 Redis 自身运行开销。

4. 启动与验证全流程

4.1 首次启动与镜像拉取

进入项目目录,执行:

docker compose up -d

-d表示后台运行。首次启动会拉取镜像,时间取决于网络和镜像大小。执行完成后查看状态:

docker compose ps

输出里 STATUS 是 running,基本就正常了。如果状态是 exited,先看日志:

docker compose logs redis

日志信息量很大。比如配置文件里写了一个当前版本不认识的指令,会出现Bad directive或类似的报错。修改redis.conf后,重新执行docker compose up -d会重建容器。注意这里直接up -d会检测到配置变化并重建,不用先down再up。

4.2 连通性测试与基本操作

服务起来了,先测连通。宿主机有 redis-cli 的话:

redis-cli -h 127.0.0.1 -p 6379 ping

返回 PONG 就算通。没有 redis-cli 也没关系,用容器里的:

docker exec redis redis-cli ping

顺手写个 key 验证一下持久化链路:

docker exec redis redis-cli set hello world docker exec redis redis-cli get hello

如果开了 AOF,这时去宿主机 data 目录查看:

ls -la ~/docker/redis/data/

应该能看到appendonly.aof。里面的内容会包含set hello world这条命令的日志记录。有同学问为什么不直接看dump.rdb,因为 RDB 是二进制快照,要等触发保存策略才生成,不是每条命令都实时写。

查看运行信息:

docker exec redis redis-cli info stats docker exec redis redis-cli info memory

info里connected_clients显示客户端连接数,used_memory显示内存使用量,total_commands_processed显示累计命令数。排查性能问题或者监控运行状态,这些指标很关键。

4.3 管理命令速查

几个日常常用的:

# 停止容器 docker compose stop redis # 启动容器 docker compose start redis # 彻底移除容器(数据卷还在) docker compose down # 移除容器并且删除数据卷(慎用) docker compose down -v # 重启容器 docker compose restart redis

down -v会把挂载的卷一起清理,如果你把数据目录也定义成了 volume 就会清掉,数据就没了。我平时只把./data这种 bind mount 挂在宿主机目录,所以down -v对它是无效的,比较安全。但如果你习惯使用 command 里写volumes: data:这种命名卷,一定要特别注意down -v。

5. 常见问题排查与避坑实录

5.1 容器运行但连接失败

容器状态是 running,宿主机却连不上。按这个顺序排查:

docker compose ps docker exec redis redis-cli ping

如果容器内 ping 是通的,说明 Redis 进程没问题。看配置:

docker exec redis cat /etc/redis/redis.conf

重点检查bind和protected-mode。bind 127.0.0.1改成bind 0.0.0.0,protected-mode yes改成no,然后docker compose restart redis。

如果配置没问题还连不上,查宿主机防火墙或安全组。6379 端口可能在防火墙上没放行。

提示:如果 Redis 跑在云服务器上,除了本机防火墙,还要看安全组规则。特别是默认只放行 22 或 80 的场景,6379 极容易漏掉。

5.2 持久化报权限错误

一次典型的报错是:

Can't open the append-only file: Permission denied

这是因为容器内的 Redis 进程以redis用户运行,它的 UID 通常是 999,而宿主机上挂载的 data 目录是 root 所有。解决:

sudo chown -R 999:999 ~/docker/redis/data

反过来,如果你用 root 用户运行容器,可能不会遇到这个问题,但容器里常用系统工具受限是另一回事。

5.3 版本升级和数据迁移

升级 Redis 版本时,直接改 compose 里的镜像 tag 然后docker compose up -d重建即可。但有几个坑:

第一,升级前先停掉持久化写入。如果 Redis 还在高频写入,你拉下来的备份可能处于不一致状态。稳妥做法是SAVE一下,或者在低峰期操作。

第二,备份数据目录。很多人以为 AOF 兼容性没问题就跳过备份,结果遇到不兼容就傻眼。操作前cp -r data data_backup这种动作花不了几秒,能省很多事。

第三,Redis 7.x 的 AOF 文件给低版本用,一般是不行的。降级操作前一定要确认版本之间的持久化文件兼容性,最好在测试环境先跑一遍。

5.4 内存与性能配置

默认情况下,Redis 在容器里会把宿主机可用内存都当成自己可以占用的资源。如果宿主机内存紧张,很容易出现 Redis 还没达到自己的上限,系统就开始 swap 甚至触发 OOM。

在 redis.conf 里加:

maxmemory 256mb maxmemory-policy allkeys-lru

allkeys-lru表示内存满了以后,按最久未使用优先淘汰。如果 key 都设置了过期时间,也可以用volatile-lru。

关于性能,Redis 7.x 支持多线程 IO,但默认是关闭的。绝大多数业务场景,单线程事件循环处理起来已经很快了,瓶颈一般在网络或业务逻辑。没必要为了参数好看就打开,除非压测数据告诉你这里确实是瓶颈。

6. 我的几条实操心得

用 compose 管理 Redis 这件事,在实际运维里给我最大的收获,就是"可复现"。以前部署一个环境,到处翻聊天记录、看 shell history 拼命令,现在一份docker-compose.yml加上redis.conf放进仓库,新机器git clone之后一条命令拉起来,什么东西都能对得上。

几个我实际操作中的经验,分享出来供参考。

数据目录的权限问题,早晚会遇到。建议在第一次部署的时候就把chown 999:999做掉,免得服务跑起来后才去补救。

TZ环境变量值得写上。容器默认时区是 UTC,日志时间和你本地对不上时,排查半天才发现是时区问题。在 compose 里设置成你所在时区就行。

开发环境和生产环境,我会用两套不一样的 compose。开发环境映射端口到宿主机,图方便;生产环境如果允许,宁可让 Redis 只在 compose 内部网络里被其他服务访问,不把 6379 暴露出来,安全做法反而更简单。

最后一条:别轻易用docker compose down -v。我遇到过几次同事手滑把卷删了的场景,Redis 直接回到空库。虽然我们的系统可以重新写入,但那一瞬间看到keyspace 0是真的慌。数据目录放在宿主机 bind mount 里,至少还有一层文件系统可救。

整体来说,只要把 compose 文件、redis.conf、数据目录这三件事规划明白,Redis 的部署和维护真的可以很省心。

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

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

立即咨询