ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Docker部署Redis保姆级教程:密码配置与持久化实战

Docker部署Redis保姆级教程:密码配置与持久化实战 说实话Redis 在服务器上跑起来本身不难难的是把“能用”和“生产可用”区分开。很多朋友一开始都是在本地电脑上装个 Redis 练手等真要部署到服务器、要配置密码、要保证重启之后数据不丢的时候才发现坑一个接一个。这篇文章我就把我自己在服务器上用 Docker 部署 Redis 的完整过程写下来。你会看到我怎么选镜像、怎么挂数据卷、怎么把密码访问和两种持久化机制配好以及部署完之后我踩过的那些坑和排查思路。全程保姆级照着抄就行。适合看这篇的朋友主要是这几类一是刚接触服务器和 Docker想把 Redis 部署到云服务器上做测试或小项目二是公司或团队要求 Redis 必须带密码、必须配置持久化但又不想手动编译安装想统一用容器管理三是已经用 Docker 跑过 Redis但每次容器一删数据就没了或者 redis-cli 连不上、密码失效这类问题还没彻底搞明白。不管你属于哪种读完这篇应该都能把一台带密码访问 数据持久化的 Redis 服务稳稳跑起来。1. 为什么用 Docker 部署 Redis从难点到方案选定1.1 自装 Redis 和 Docker 部署的真实差别先聊聊本质区别。直接在服务器上用 apt install redis-server 或者编译安装 Redis本质上就是把 Redis 二进制装进操作系统数据目录、配置目录都散落在系统里卸载、升级、换机器的时候都挺麻烦。而且一台服务器上如果要跑多个 Redis 实例比如不同项目、不同环境你就要手动管理多个端口、多个配置目录稍微一多就乱。Docker 部署的逻辑完全不同。Redis 被打包成一个镜像容器内部就是一个完整的 Redis 运行环境配置、数据目录都可以通过挂载卷映射到宿主机指定位置。这样有几个非常实际的好处升级 Redis 版本就是换镜像标签回滚也很容易多实例之间互相隔离配置各管各的整个 Redis 环境跟着 Dockerfile 和挂载配置走换个服务器拉起容器就行。这些优点在单机测试时感受不明显但一上生产、一上多机环境差距就非常明显。当然Docker 部署也不是没有代价。多了一层容器网络和存储的抽象出问题的时候排查链路变长了。比如连接不上可能是端口映射的问题也可能是容器内部 Redis 配置的问题还可能是防火墙的问题。所以后面第 5 部分我会专门把排查思路整理成一套清单帮你快速定位。1.2 这套部署方案的适用场景与前置条件我这里说的“服务器版”指的是 Linux 云服务器或自建虚拟机不是本地 Windows/Mac 上的 Docker Desktop 体验环境。虽然命令通用但生产实践上服务器环境更接近真实业务。核心目标只有两个第一Redis 必须带密码访问杜绝没有认证就能读写数据的“裸奔”状态第二数据必须持久化容器删掉、重新拉起来之后数据还在。围绕这两个目标下文会涉及三种核心手段密码配置requirepass、持久化机制RDB 和 AOF、容器与宿主机的数据卷映射。前置条件其实就两条。第一条服务器上已经装好 Docker 并能正常启动docker version 能看到 Client 和 Server 的信息。第二条你有操作 Docker 的权限要么是 root要么你的用户加入了 docker 用户组。这两条不满足的话后面所有操作都会卡在最开始的环节。如果你对服务器不熟建议先用 root 操作踩一遍熟悉之后再创建普通用户并加入 docker 组。2. 部署前的环境检查与镜像准备2.1 服务器上的 Docker 环境核查部署的第一步不是急着拉镜像而是先检查环境。我把我的核查流程写一下你可以直接照做。docker version docker compose version第一个命令能看到 Docker 的客户端和服务端版本。注意服务端版本也就是 Server 那一栏一定要正常显示不然说明 docker 没有正确启动。第二个命令是确认 docker compose 插件是否可用。虽然单容器部署用 docker run 就够但 docker-compose.yml 方式管理起来更清晰尤其是后面要加配置映射、数据卷、重启策略的时候一个文件全搞定。我强烈建议你装好 compose 插件。然后是检查磁盘和内存。Redis 本身不占多少内存但持久化的时候要写磁盘数据量大的话 RDB 快照、AOF 文件会占空间。用 df -h 看看挂载目录的剩余空间用 free -h 看看内存。这里有个容易被忽略的问题就是 Docker 默认的数据目录在 /var/lib/docker如果你的挂载卷也放在系统盘而系统盘比较小比如某些云主机默认 40GRedis 数据量一大就可能把磁盘写满。建议把数据卷挂到独立的数据盘上后面我会专门讲。2.2 选择 Redis 镜像版本与拉取实操镜像版本的选择直接关系到后续的稳定性和兼容性。我见过很多朋友喜欢追最新标签直接 docker pull redis:latest但其实这种习惯在生产环境里并不推荐。latest 标签会随官方发布变化今天你拉的是 7.x过段时间可能就变成了更新的版本行为变更可能导致你的配置出现问题。我的建议是日常测试可以用 redis:7生产方式最好固定到具体的小版本比如 redis:7.2-alpine。为什么用 alpine 版本因为它体积小基础依赖少运行时资源占用更低。当然 alpine 也有缺点比如排查问题时容器里的工具集相对少但 Redis 本身不依赖太多东西日常运维基本不受影响。docker pull redis:7.2-alpine执行完可以用 docker images 确认镜像已经拉到本地并且记一下镜像 ID 和大小。如果你的服务器网络拉取官方仓库比较慢可以给 Docker 配置镜像加速地址这个网上有不少资料配置完之后重启 docker 服务再拉取。我实际操作时发现改了加速源之后拉取速度从几分钟降到了十几秒非常明显。2.3 准备数据目录与配置映射重点镜像拉好之后先别急着创建容器。这一步是很多新手失败的关键数据目录和配置文件的准备。Redis 在容器里默认的数据目录是 /data默认配置文件在 /usr/local/etc/redis/redis.conf官方镜像的默认路径。如果我们什么都不映射容器创建的数据都在容器内部删除容器时如果加了 -v 删除数据就永远消失了。所以必须把 /data 挂载到宿主机的一个目录让 Redis 的 RDB 快照和 AOF 日志写到宿主机磁盘上这样即使容器删除重建宿主机目录里的数据还在。我习惯把 Redis 相关的所有文件放到一个独立目录结构这样规划/opt/redis ├── data # 数据文件目录 └── conf └── redis.conf # 自定义配置创建目录并准备配置文件mkdir -p /opt/redis/data /opt/redis/conf配置文件不用从头手写。最稳妥的办法是先从官方镜像里把默认配置拷出来再在默认基础上修改。这比从网上随便找一份配置要可靠因为默认配置一定匹配你拉取的镜像版本。执行id$(docker create redis:7.2-alpine) docker cp $id:/usr/local/etc/redis/redis.conf /opt/redis/conf/redis.conf docker rm $id这里 docker create 只是创建容器但不启动它目的是为了让容器文件系统里生成配置文件再通过 docker cp 拷出来。拷完之后把这个临时容器删掉这个文件就是你的基准配置。注意网上很多教程让你直接挂载宿主机上的自定义 redis.conf 到容器路径但如果你把配置目录挂载成空目录或者挂载了一个不完整的配置文件Redis 会因为没有默认配置而采用内置默认设置这时候你写的很多参数可能不生效。这就是我坚持先拷默认配置再改的原因。3. 开启密码访问两种方式的配置细节3.1 启动参数方式简单但不够灵活开启密码访问最快速的方式就是在 docker run 命令里直接加 --requirepass 参数覆盖 Redis 启动命令。docker run -d \ --name redis-server \ -p 6379:6379 \ -v /opt/redis/data:/data \ redis:7.2-alpine \ redis-server --requirepass MyStr0ngPass2024注意这个命令里最后的 redis-server --requirepass 是覆盖容器默认 CMD 的启动命令。启动之后容器内的 Redis 就是以 requirepass MyStr0ngPass2024 运行的。用 redis-cli 连接时也需要带密码否则会直接报 NOAUTH Authentication required。这种方式的好处是命令短、适合快速验证。缺点也很明显密码直接写进 docker run 命令会在 shell 历史记录里留下痕迹这也是一个安全隐患而且如果后续要改密码你需要删除容器重新创建。如果你只是临时测试用这种方式没问题但如果是服务器上长期运行的服务我强烈建议用配置文件方式。3.2 配置文件挂载方式推荐做法第二种方式是我在实际部署中采用的方式把密码和其他关键参数统一写进 redis.conf然后通过 -v 挂载到容器内部。这样配置集中管理、可追溯改完配置后重启容器就能生效。首先修改上一步拷到 /opt/redis/conf/redis.conf 的配置文件。打开文件后找这几个关键项# 设置访问密码Redis 5.0 之后的版本用 requirepass requirepass MyStr0ngPass2024 # 允许所有 IP 连接是否对外提供服务需要配合防火墙控制 bind 0.0.0.0 # 保护模式关闭否则默认情况下 Redis 只允许本机访问 protected-mode nobind 和 protected-mode 这两个参数我要多说两句。默认的 redis.conf 里 bind 通常是 127.0.0.1这表示 Redis 只监听本机回环地址外部服务器根本无法连接。如果你把 bind 改成 0.0.0.0表示监听所有网络接口让 Docker 的端口映射能够把外部请求转发进容器。同时要把 protected-mode 设置为 no否则即使 bind 改成了 0.0.0.0Redis 在没有密码或密码默认配置时仍会拒绝远程连接这是 Redis 自带的一层保护机制。但请注意即便有了密码也不要轻易让 Redis 暴露到公网后面安全部分我会细说。配置写好后启动命令变成docker run -d \ --name redis-server \ -p 6379:6379 \ -v /opt/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf \ -v /opt/redis/data:/data \ redis:7.2-alpine \ redis-server /usr/local/etc/redis/redis.conf再次注意最后一行redis-server 后面跟的是容器内的配置路径。docker run -v 把宿主机 /opt/redis/conf/redis.conf 挂到容器的这个路径然后启动时指定加载它。这套方式下你改宿主机上的配置文件然后重启容器配置变更就会生效不需要重建容器。3.3 密码安全建议如何不被爆破密码好了但普通密码没有安全感给 Redis 密码的安全强度建议避免被人用扫描工具爆破。首先绝对不要用 root、123456、redis 这种常见密码。我见过不止一个服务器因为 Redis 用了弱密码结果被扫描工具发现后写入挖矿程序CPU 直接被拉满。密码建议至少 16 位包含大小写字母、数字和特殊符号。其次生产环境的密码要独立管理不要和其他服务共用同一个密码。我自己的做法是把 Redis 的密码放在专门的密钥管理工具或者环境变量文件里部署脚本从里面读取避免明文密码在脚本和命令行里反复出现。说到这里就自然带出用 Docker secrets 或者环境变量方式管理密码的进阶玩法。比如在 docker-compose.yml 里通过 ${REDIS_PASSWORD} 引用 .env 文件里的变量这样 docker run 命令里不会出现密码明文配置文件里也不用硬编码。我这里给一个简化版的 docker-compose.yml 作为参考services: redis: image: redis:7.2-alpine container_name: redis-server restart: always ports: - 6379:6379 volumes: - /opt/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf - /opt/redis/data:/data command: redis-server /usr/local/etc/redis/redis.conf用 compose 方式的好处是restart: always 保证重启后自动拉起容器这比 docker run 单独加 --restart 参数更清晰。写好之后 docker compose up -d 就启动后面直接 docker compose restart 就能应用新的配置。不过我还是要提醒一点目前这个简化版配置里如果密码还是写在 redis.conf 里那么密码仍然是明文挂载进容器的。如果你有更高级的安全诉求可以考虑使用 Redis 的 ACL 特性单独配置用户权限或者结合外部的密钥管理服务下发配置这属于进阶话题我在这里先点到为止。4. 数据持久化把内存变成磁盘上的保险柜4.1 RDB 和 AOF 到底怎么选Redis 本质是内存数据库数据默认放在内存里进程一退出数据就没了。数据持久化就是把内存里的数据以某种方式写入磁盘这样 Redis 重启之后可以从磁盘把数据恢复回来。Redis 提供了两种持久化机制RDB 快照和 AOF 追加日志。RDB 是在指定时间间隔内把内存数据集生成一份二进制快照保存到 dump.rdb 文件。它的优点是恢复速度快、文件紧凑适合做备份和容灾缺点是快照之间有间隔如果 Redis 突然宕机最后一次快照之后写入的数据会丢失。默认配置是开启 RDB 的比如 save 900 1 表示 900 秒内至少有 1 次键变化就生成快照。AOF 则是以日志形式记录每次写操作追加到 appendonly.aof 文件里。Redis 重启时重放这些日志就能恢复数据。优点是数据安全性更高可以配置每秒同步一次最多丢失 1 秒数据缺点是文件体积比 RDB 大恢复速度相对慢一些。在实际部署时怎么选如果是缓存场景能容忍少量数据丢失RDB 就够了如果是需要较高数据可靠性的业务数据建议 AOF 和 RDB 同时开启让 Redis 优先用 AOF 恢复数据AOF 数据更新同时用 RDB 做冷备。Redis 4.0 之后还支持混合持久化默认 AOF 重写时生成 RDB 内容加增量命令兼顾恢复速度和文件体积。4.2 落盘配置与数据卷挂载实操在配置文件里找到并确认这几个持久化相关配置# 开启 AOF appendonly yes # AOF 文件名默认 appendonly.aof appendfilename appendonly.aof # AOF 同步策略每秒钟同步一次性能和数据完整性相对平衡 appendfsync everysec # 开启 RDB save 900 1 save 300 10 save 60 10000 # RDB 文件名 dbfilename dump.rdb # 数据文件目录默认就是 /data dir /datadir /data 这个配置很关键。它告诉 Redis 把 dump.rdb 和 appendonly.aof 都写到容器的 /data 目录。再加上 docker run 或 compose 里把宿主机 /opt/redis/data 挂载到这个 /data数据就真正落到宿主机了。配置完成后我用的是 compose 文件里挂载目录的方式。启动容器之后可以进到宿主机 /opt/redis/data 目录看看ls -lh /opt/redis/data正常情况下能看到 dump.rdb 和 appendonly.aof 两个文件并且文件大小会随着写入数据而变化。如果你看到这些文件说明持久化已经生效。如果目录是空的那就说明你的 dir 配置可能不对或者容器数据没有挂对位置需要回头检查。4.3 容器重启与数据恢复验证持久化配置完之后我强烈建议你做一次完整的验证防止“配置了但没生效”这种最坑的情况。我的验证步骤如下。往 Redis 里写几条数据docker exec -it redis-server redis-cli -a MyStr0ngPass2024 set user:name zhangsan docker exec -it redis-server redis-cli -a MyStr0ngPass2024 set user:age 25接着验证当前能查到docker exec -it redis-server redis-cli -a MyStr0ngPass2024 get user:name然后模拟重启容器docker restart redis-server重启后再查数据docker exec -it redis-server redis-cli -a MyStr0ngPass2024 get user:name如果返回 zhangsan说明重启后数据保留持久化生效。更狠一点的验证是直接删除容器再重新创建因为 docker restart 只是重启同一容器数据卷挂载还在。删除重建才能排除容器层面缓存数据的干扰docker stop redis-server docker rm redis-server docker compose up -d再用同样的命令查数据。如果数据还在说明你的数据卷挂载和持久化配置都没问题。这一步验证一定要做很多人部署完觉得一切正常结果某天服务器重启、容器被误删才发现数据全没了就是因为没做删除重建的验证。还有一个容易忽略的点写 AOF 之后文件增长会很快Redis 会自动执行 AOF 重写压缩文件体积。你可以在配置文件里看到 auto-aof-rewrite-percentage 100 和 auto-aof-rewrite-min-size 64mb 这两个参数含义是当 AOF 文件比上次重写时增长了 100% 且超过 64MB 时Redis 自动触发 AOF 重写。一般保持默认就行不需要动。5. 常见问题与排查技巧实录5.1 端口起不来、连接超时怎么办我实际操作中被问得最多的就是连接问题。症状通常是 redis-cli -h 服务器IP -p 6379 连接超时或者客户端连接报 Connection refused。排查时我习惯按这个顺序逐层排除。第一步确认容器在不在跑docker ps | grep redis-server如果容器没在列表里先看 docker logs redis-server 输出确认启动是否报错。第二步确认容器内部 Redis 是否正常监听docker exec -it redis-server redis-cli -a MyStr0ngPass2024 ping如果容器内 ping 通了返回 PONG说明 Redis 没问题问题出在网络层。第三步确认宿主机端口映射是否生效ss -tlnp | grep 6379如果这里没有 6379 监听说明 docker run 或 compose 里的 -p 6379:6379 没生效检查端口是否被占用。如果宿主机有监听但外部仍然连不上那就是服务器防火墙或云安全组的问题。阿里云、腾讯云这些服务器默认都有安全组规则需要在控制台放行 6379 端口这一步经常有人漏掉。5.2 数据卷反复丢失的排查另外一个高频问题数据目录挂载了容器也显示正常但重启后数据还是没。我遇到过的原因主要有三个。第一个是挂载路径写错了。宿主机路径和容器路径写反或者容器路径写错导致 Redis 写的是容器内另一个目录。检查方法很简单启动容器后执行docker inspect redis-server -f {{ .Mounts }}查看挂载信息里宿主机路径和容器路径是否和你配置的一致。第二个是容器不是从你的 compose 文件创建的。有些朋友之前手动 docker run 创建过一个容器后面再用 compose 重建时容器名冲突compose 可能复用了旧容器应用的是旧的挂载配置。建议先 docker rm -f redis-server 清理干净再重新 compose up -d。第三个是 dir 配置问题。如果 redis.conf 里 dir /data 没设置对Redis 会把数据文件写到其他位置。我排查时会进到容器里看看实际文件落到哪了docker exec -it redis-server ls -lh /data docker exec -it redis-server find / -name *.aof -o -name *.rdb 2/dev/null找到文件的真实位置再回头调整 dir 配置或挂载路径。这种问题不复杂但定位路径时很容易绕弯路。5.3 安全加固别让 Redis 裸奔公网最后说一个特别重要的安全话题也是很多教程容易漏掉的。密码访问只是 Redis 安全的第一道门槛绝对不意味着开启密码就能放心暴露到公网。Redis 官方都明确说在没有保护的情况下不能暴露到公网因为弱点探测工具对 Redis 的扫描是常态一旦密码被爆破或被利用那就是服务器被人拿去挖矿、开代理的经典事故。我的建议是Redis 的 6379 端口只对需要访问它的内网 IP 或应用服务器 IP 开放不要在云安全组里对所有来源放行。更简单的做法是Redis 直接不监听公网接口改为只监听内网地址应用服务通过内网访问。如果你一定要通过公网管理 Redis可以加一层 SSH 隧道或者使用专用的访问工具但不要直接把 Redis 端口暴露到公网。除此之外给容器加上 restart: always再把 Docker daemon 本身的 TLS 连接注意一下这些都是运维层面的基本安全习惯。用我上面给的 compose 配置跑起来以后你这个 Redis 服务基本就处于一个“有密码、能持久化、重启自恢复、端口受控”的相对稳妥状态了。我在实际项目中一直沿用这套部署方案。最明显的体会是当 Redis 变成容器之后升级版本、迁移机器、备份恢复都变得非常省心。数据目录独立、配置集中管理、密码可控这套结构完全能够支撑从开发环境到小规模生产环境的平滑过渡。如果你刚上手建议先在自己服务器上完整操作一遍把“删除容器重建数据还在”的验证跑通后面真正用到生产时心里就有底了。
返回列表