恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Docker Compose 部署 Redis:从配置到持久化的完整实践
首页
资讯中心
/
Docker Compose 部署 Redis:从配置到持久化的完整实践
Docker Compose 部署 Redis:从配置到持久化的完整实践
发布时间:2026/10/19 9:33:46
自己电脑上装Redis敲几条命令就完事。可一旦要面对几台服务器、多个环境还要求版本一致、配置可复现事情就完全变了样。手动编译要处理编译依赖和系统库兼容直接用系统包管理器安装又常常拿到很老的版本更别提团队里每个人跑个容器环境还得先折腾半天。用 docker compose 把 Redis 跑起来是我这些年比较省心的一套方案镜像官方维护、配置跟着文件走、数据通过卷挂在宿主机上新机器拉下代码后一条命令就能把完整环境拉起来。这篇文章没有多高深的东西纯粹是把我安装 Redis 时的实际过程和踩过的坑拿出来一步步拆给你看。里面用到的 compose 配置和 redis.conf 都是可以直接复制修改的版本不管你是刚上手 Docker还是已经在生产环境用容器跑服务应该都能从中找到有用的细节。1. 为什么推荐用 docker compose 管理 Redis1.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 ar /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 组省得每次敲命令都要带sudosudo 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: - TZAsia/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 yourpasswordbind 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参数一起思考如果容器分配到 512MRedis 自己的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 memoryinfo里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 redisdown -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.0protected-mode yes改成no然后docker compose restart redis。如果配置没问题还连不上查宿主机防火墙或安全组。6379 端口可能在防火墙上没放行。提示如果 Redis 跑在云服务器上除了本机防火墙还要看安全组规则。特别是默认只放行 22 或 80 的场景6379 极容易漏掉。5.2 持久化报权限错误一次典型的报错是Cant 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-lruallkeys-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 的部署和维护真的可以很省心。