作为一名常年跟 Docker 打交道的人,我越来越觉得“镜像操作”这一套流程就是 Docker 的基本功,就像做菜得先会切菜一样。很多朋友问我 Redis 怎么装、容器怎么跑,其实翻来覆去就那么几条命令,但真正连贯起来用得顺手的人不多。尤其是“搜索镜像、拉取、打包、删除、重新加载、再运行”这一条完整链路,只要你能亲手走一遍,Docker 的核心逻辑基本就通了。
这篇文章我打算完全按照实操顺序来写,把每一步背后的原理、常见的坑、以及我个人的使用习惯都交代清楚。不管你是刚接触容器的小白,还是已经用了一段时间想补补基本功的开发者,这套流程你都可以直接照着敲一遍。它所涉及的场景也不局限于 Redis,MySQL、Nginx、各种中间件,换汤不换药,核心方法论是通用的。
1. 整体流程设计与思路拆解
很多人拿到 Docker 第一反应是“我直接 docker run 不就行了吗?”没错,一条命令确实能把容器跑起来。但如果只停留在这一步,你对 Docker 的理解基本是断裂的。
1.1 这套完整流程到底在解决什么问题
日常开发里,我们真正频繁遇到的情况是这几类:
-
你在本地拉了一个镜像,折腾好了环境,想把它原样搬到测试服务器上。如果服务器能访问外网,直接 pull 就行;但如果是内网环境、离线环境,你就必须先把镜像打包成文件带过去。
-
你不小心删了镜像,或者磁盘空间不够清理了一波,结果发现某个 Redis 版本再想拉取时已经下不到了,或者版本变了、配置对不上。这时如果之前有打包好的镜像文件,你随时用
docker load救回来。 -
你需要临时切换 Redis 版本,比如从 Redis 6 换到 Redis 7,或者对比不同版本的性能差异。那么“删除旧镜像 -> 加载新镜像 -> 运行新容器”就是一套标准组合拳。
所以这条流程看着简单,其实是围绕“镜像生命周期管理”展开的闭环。它把 Docker 里最核心的两个对象——镜像(Image)和容器(Container)——彻底串起来了。理解了这条链路上每一步在做什么,你对 Docker 的掌控力会上一个台阶。
1.2 镜像与容器:先搞清楚这对关系
在往下操作之前,有必要把“镜像”和“容器”这两个概念理清楚。我平时给朋友解释时喜欢用“类与实例”的类比:镜像是模板,容器是根据模板创建出来的运行实例。就像 Java 里你写了一个类,可以 new 出很多个对象;一个 Redis 镜像同样可以 run 出多个互不干扰的 Redis 容器实例。
这套流程里有一个容易被忽略的点:docker save 打包的是镜像本身,不包含运行中的数据。容器里的数据如果没做持久化,容器一删就全没了。所以当你发现自己“打了一个包”却带不走数据时,别慌,这是正常的——数据持久化靠的是 volume 挂载,和镜像打包是两码事。后面讲到运行 Redis 时我会专门展开这一点。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与镜像搜索
正式操刀之前,先把 Docker 环境确认好。这里花两分钟检查,比后面各类报错出现再排查要划算得多。
2.1 确认 Docker 环境是否就绪
如果你用的是 Linux 服务器,执行一条命令检查版本:
bash复制docker version
如果输出正常,能看到 Client 和 Server 两段信息,说明 Docker 服务正在运行。特别留意 Server 那段的 Engine 信息,如果看不到,大概率是 Docker daemon 没启动,Linux 下执行 systemctl start docker 就行。
Windows 和 Mac 用户用的多半是 Docker Desktop,安装之后有时会碰到底层虚拟化没开启导致服务起不来的问题,常见报错是"virtualization support not detected"之类。解决办法是进 BIOS 开启 VT-x/AMD-V,然后把 Docker Desktop 的 WSL 2 backend 配置好。Windows 上建议优先把 WSL 2 的版本更新到最新,很多莫名奇妙的启动失败其实和 WSL 内核版本过旧有关。
环境确认好后,顺手看一下磁盘空间:
bash复制df -h
镜像文件动辄几百兆,多个镜像叠加起来很占地方,提前确认空间够用,别等到 docker pull 到一半才报“no space left on device”。
2.2 docker search 搜索 Redis 镜像的细节
搜索镜像的命令很简单:
bash复制docker search redis
输出会返回一堆名称里包含 redis 的镜像。注意看几个字段:NAME 是镜像完整名称,STARS 是收藏数,OFFICIAL 标记是否为官方镜像,AUTOMATED 表示是否自动构建。
这里我给新手一个非常实在的建议:能用官方镜像就用官方镜像。因为 Docker Hub 上任何人都能发布镜像,第三方镜像的质量参差不齐,有的为了节省体积会把基础组件砍得很干净,有的甚至可能在层里塞了不干净的东西。你在本地用无所谓,但如果要推到生产环境,安全审计是绕不过去的坎。
我实测会遇到的情况是 docker search 只能看到镜像的基本信息,但看不到具体有哪些 tag(版本标签)。想看 Redis 都有哪些版本,推荐两种方式:
-
直接在 Docker Hub 网页上打开 redis 的官方仓库页面,查看 tags 列表。
-
用命令行工具
skopeo list-tags docker://redis查看,前提是你装了 skopeo。
另外提醒一句:实际工作中 docker search 用得并不多,因为我们心里早就有了明确的目标镜像,更多是直接 docker pull redis:7.2-alpine 这样的精确拉取。搜索功能更适合你刚接触 Docker、还在探索阶段时用,了解下有哪些现成镜像可用。
3. 拉取镜像:从官方源到自定义 tag 的完整细节
搜索只是开胃菜,从这节开始进入真正的命脉操作。
3.1 docker pull 命令与 tag 选择
拉取 Redis 官方镜像,基础命令就一行:
bash复制docker pull redis
不指定 tag 时,默认拉取 latest 标签,也就是最新版。但我强烈不建议你在任何涉及稳定性的环境里使用 latest,原因很简单:latest 是一个会变化的目标,你今天拉的和三个月后拉的可能是两个不同版本的 Redis,这种不确定性就是个定时炸弹。
合理的做法是显式指定版本号。以 Redis 为例,我常用的 tag 有这么几个:
| tag | 说明 | 适用场景 |
|---|---|---|
7.2 |
7.x 系列稳定版 | 生产环境常规使用 |
7.2-alpine |
基于 Alpine Linux,体积极小 | 本地开发、镜像瘦身需求 |
6.2 |
6.x 旧版本 | 老项目维护、版本对比 |
7.4-bookworm |
基于 Debian bookworm | 需要完整依赖链的场景 |
如果想拉取 7.2 版本:
bash复制docker pull redis:7.2-alpine
这里重点解释一下 alpine 版本为什么值得关注。Alpine 是一个极简 Linux 发行版,用它做底座的镜像体积通常只有完整版的一半甚至更少。Redis 官方 alpine 镜像大概只有 30MB 出头,而基于 Debian 的版本可能到 100MB 以上。对于只需要 Redis 服务本身、不需要额外工具链的场景,alpine 版本的分发和部署效率高得多,尤其当你后面要走 docker save 打包迁移的时候,文件小意味着传输快、占用磁盘少。
但你也要接受 alpine 的代价:它用的是 musl libc,和常见的 glibc 环境存在差异,某些依赖原生编译模块的场景可能踩坑。比如你后面想装一些 Redis 模块,在 alpine 镜像里需要额外处理,在 Debian 镜像里反而省事。所以我的建议是:开发环境图快图小用 alpine,生产环境如果不需要额外扩展,alpine 完全够用;如果牵扯到编译扩展,老老实实用 bookworm 这类完整版。
3.2 镜像加速配置与拉取失败的应对
国内环境拉取 Docker Hub 镜像慢甚至超时,是许多开发者绕不开的痛点。Docker 官方源在国外,网络延迟和吞吐都不理想。解决方法是在 Docker daemon 的配置文件里配置 registry mirror。
Linux 上配置文件在 /etc/docker/daemon.json,Windows 上通过 Docker Desktop 的 Settings -> Docker Engine 编辑同样内容。一个典型配置长这样:
json复制{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://dockerproxy.com"
]
}
配置完重启 Docker 服务,再拉镜像一般会有明显改善。不过不同加速源的稳定性和速度是动态变化的,如果你的加速源有一天突然变慢,换个源就行。
如果换了镜像源还是拉取失败,有一个土办法非常管用:先把镜像文件从一台能正常拉取的机器上用 docker save 打成 tar 包,拷贝到目标机器上用 docker load 加载。这也是今天这条完整流程中最值钱的一个应用场景——离线和弱网环境下的镜像交付。后面第四节我会完整演示。
4. 打包镜像:离线分发场景核心操作
镜像拉下来之后,最可能遇到的需求就是“把这个镜像搬到另一台机器上”。无论目标是内网服务器、云主机还是同事的电脑,只要不能直接 pull,docker save 就是标准答案。
4.1 docker save 的使用方法与输出形式
先把刚拉下来的 Redis 镜像打包成文件:假设我拉取的是 redis:7.2-alpine,执行:
bash复制docker save -o redis-7.2-alpine.tar redis:7.2-alpine
其中 -o 指定输出文件名(output),后面跟镜像名。执行完能看到当前目录下多了一个 tar 文件。
也可以同时打包多个镜像到一个文件里:
bash复制docker save -o multiple-images.tar redis:7.2-alpine nginx:1.25
这在批量迁移场景下很好用,一个 tar 包包含多个镜像,目标机器上 load 一次全部导入。
还有种常见的压缩传输方式,直接配合 gzip 一步到位:
bash复制docker save redis:7.2-alpine | gzip > redis-7.2-alpine.tar.gz
这样文件体积更小,传输成本更低。解压加载时反过来:
bash复制gunzip -c redis-7.2-alpine.tar.gz | docker load
4.2 save 与 export 的区别:别再搞混了
这是被问得最多的问题之一:docker save 和 docker export 有什么区别?两个命令都能产出 tar 包,但语义完全不一样:
| 命令 | 操作对象 | 内容 | 是否保留历史层 | 常见用途 |
|---|---|---|---|---|
docker save |
镜像 image | 镜像的层、元数据、配置 | 是 | 镜像分发、备份、迁移 |
docker export |
容器 container | 容器当前的文件系统快照 | 否 | 快速导出容器运行时的文件系统 |
用大白话讲,save 存的是“镜像模板”,用它 load 回去之后还能 run 出新的容器;export 存的是“某台容器当前的样子”,导入后是一个新的镜像,但这个镜像没有原镜像的分层结构,也没有 CMD、ENV 等运行配置。
我见过有人为了备份 Redis 容器,直接用 export 导出了正在运行的容器,以为这样数据也备份了。其实不然,如果没有挂载 volume,容器层里的数据确实会被带出来,但这种方式既笨重又不规范。正确的数据备份姿势是:镜像只负责环境,数据通过 volume 持久化,备份时直接备份 volume 目录或者用专门的备份工具。这我想说的是,理解 save 和 export 的区别,能帮你避免很多“备份了个寂寞”的尴尬。
5. 删除与重新加载镜像:镜像清理的完整姿势
镜像用久了,本地会堆积大量不再使用的镜像,占磁盘、看着乱,所以学会“删”和“重新加回来”同样重要。
5.1 删除本地镜像的两种典型场景
删除一个镜像的命令是:
bash复制docker rmi redis:7.2-alpine
但执行前先注意一个前置条件:如果有个容器仍然基于这个镜像运行着,rmi 会直接拒绝,并提示“image is being used by running container”。这时你有两条路:
-
先停止并删除那个容器:
docker stop 容器名再docker rm 容器名,然后重新docker rmi。 -
用
docker rmi -f强制删除镜像。但我不推荐优先用-f,因为它可能留下孤儿容器,而且实际场景中你往往只是想换镜像版本,而不是杀掉容器里的数据。
还有一种常见需求:清理所有没有容器在用的悬空镜像(dangling image),一句话搞定:
bash复制docker image prune
如果想直接删除所有未被使用的镜像,加 -a:
bash复制docker image prune -a
这个命令执行前会提示你确认,是个很安全的习惯性交互。我通常会定期用 docker system df 看一眼磁盘占用情况,再用 prune 清理,既不会误删正在用的镜像,又能回收大量空间。
有个细节值得留意:删除镜像前,最好先确认哪些容器依赖它。检查方式:
bash复制docker ps -a --filter ancestor=redis:7.2-alpine
这个 --filter ancestor 参数能列出所有由该镜像创建的容器。如果只想删镜像但保留容器数据,你得先考虑数据是否做了持久化,否则容器删除后数据可能就没了。
5.2 docker load 重新加载镜像
从 tar 包恢复镜像的命令:
bash复制docker load -i redis-7.2-alpine.tar
如果你之前用 gzip 压缩过,直接 load 也能识别,因为 Docker 能自动处理压缩格式:
bash复制docker load -i redis-7.2-alpine.tar.gz
load 成功后,用 docker images 确认镜像已恢复。
这里我说一个自己踩过的坑:docker load 加载的镜像如果没有 tag,你会看到 <none>:<none> 这样的镜像,也就是悬空镜像。导致这种情况的常见原因是 save 时操作不规范,或者 tar 文件本身缺失 tag 信息。解决办法是在 save 时严格使用“仓库名:标签”的形式,load 后第一时间 docker images 检查命名是否正常。
另外,很多人会在 load 之后直接 docker run,结果发现端口映射、容器名、挂载目录全忘光了。我的习惯是:每构建或加载一个镜像,都在旁边备注好对应的 run 命令,要么写成脚本,要么记入项目的 README。Docker 镜像本身没有保存“上次怎么运行”的元数据,如果你用 docker run 时把所有配置都写在命令行里,丢了就真的找不回来了。想要简化这件事,可以先用 docker create 创建容器而不启动它,再用 docker commit 生成新镜像,但这是另一个话题,这里先不展开。
6. 运行 Redis 容器:参数解析与数据持久化
镜像加载好,环境已就绪,最后一步就是真正把 Redis 容器跑起来。这一步涉及到的参数最多,也是日常使用中拼单率最高的环节。
6.1 docker run 启动 Redis 的核心参数
假设我们已经成功 load 了 redis:7.2-alpine,运行一个带密码、数据可持久化的 Redis 容器,典型的命令如下:
bash复制docker run -d \
--name my-redis \
-p 6379:6379 \
-v /opt/redis/data:/data \
-v /opt/redis/conf/redis.conf:/etc/redis/redis.conf \
-w /data \
redis:7.2-alpine \
redis-server /etc/redis/redis.conf
逐个拆解一下这些参数的作用:
-
-d:后台运行容器(detach 模式),不会抢占当前终端。 -
--name my-redis:给容器起名字。不指定的话 Docker 会随机分配一个像focused_bose这样的名字,管理起来非常痛苦。 -
-p 6379:6379:端口映射。宿主机端口在前,容器端口在后。宿主机的 6379 被你占用后,可以改成其他端口,比如-p 16379:6379,这样外部访问的是 16379。 -
-v /opt/redis/data:/data:把宿主机的/opt/redis/data目录挂载到容器的/data目录。Redis 容器默认的持久化目录是/data,RDB 快照和 AOF 日志都会写在这里。这个挂载是数据不丢的关键。 -
-w /data:设置容器的工作目录。对于 Redis 来说,配合 volume 挂载后,相对路径的持久化文件都会落在宿主机目录里。
有关密码配置,我更推荐在 redis.conf 里写:
conf复制requirepass yourpassword
appendonly yes
然后指定配置文件启动。如果只是临时测试,也可以用命令行参数:
bash复制docker run -d --name my-redis -p 6379:6379 redis:7.2-alpine redis-server --requirepass yourpassword --appendonly yes
注意这里 redis-server 是容器内执行的命令,后面的 --requirepass 和 --appendonly 都是传递给 Redis 服务的参数。它们帮你跳过“自行编写 conf 文件”这一步,适合快速验证环境;但正式环境还是建议挂载配置文件,便于后续调整。
6.2 容器启动后的验证与连接
容器跑起来后,第一件事是看它是否真的活着:
bash复制docker ps
如果 STATUS 列显示 Up 5 seconds 之类,说明容器正常运行。如果没看到,用 docker ps -a 看所有容器,再结合 docker logs my-redis 排查启动日志。
日志是最直接的反馈,Redis 启动成功会打印类似“Ready to accept connections”的提示。如果看到报错,比如 Can't open the log file: Permission denied,多半是挂载目录的权限问题,chmod 或 chown 调整一下即可。
连接验证,我习惯直接在容器内执行命令:
bash复制docker exec -it my-redis redis-cli -a yourpassword ping
如果返回 PONG,服务正常。-a 指定密码,如果你之前设置了 requirepass,这一步不能省。平时还要注意,redis-cli -a 会在进程列表里暴露明文密码,生产环境不建议这么搞,用 REDISCLI_AUTH 环境变量代替会更安全。
如果我想在宿主机上连接,需要先确认宿主机装了 Redis 客户端。没有的话用 nc 直接发送命令也可以:
bash复制echo -e "PING\r\n" | nc 127.0.0.1 6379
注意如果你设置了 requirepass,这里直接发 PING 会得到 -NOAUTH Authentication required.,正常现象。
6.3 容器生命周期管理:停止、启动、重启、删除
容器虽然跑起来了,但你早晚会遇到“我要停一下它”“我要改配置后重启”这类需求。常用的生命周期命令整理如下:
bash复制# 停止容器
docker stop my-redis
# 启动已停止的容器
docker start my-redis
# 重启容器
docker restart my-redis
# 停止并删除容器
docker rm -f my-redis
docker stop 会给容器发送停止信号,等待它优雅退出;如果你等不及,docker kill 是直接强杀。两者都可能导致数据写入中断,但 Redis 有持久化机制兜底,一般不会丢太多数据。
重点提醒:docker rm -f 是“停止并删除容器”的组合操作,误执行后容器就没了。所以删除容器前,一定确认数据已经通过 volume 持久化到宿主机了。验证方式很简单:删除容器后,看宿主机挂载目录里是否还有文件,如果有,数据就还在,下次运行容器时重新挂载同一目录即可恢复。
7. 常见问题与排查技巧实录
这几条经验是我自己在用 Redis 容器过程中总结出来的,附上排查思路,希望能帮你少走弯路。
7.1 端口冲突
启动容器时提示:
text复制Bind for 0.0.0.0:6379 failed: port is already allocated
原因很明显:宿主机 6379 端口已经被占用。可能是宿主机自己装了一个 Redis,也可能是另一个容器占用了端口。
排查三步走:
bash复制# 查看端口被哪个进程占用
lsof -i :6379
# 查看端口被哪个容器占用
docker ps --filter publish=6379
# 快速验证端口是否可连接
nc -vz 127.0.0.1 6379
解决办法就两个:停掉占用端口的服务,或者换端口启动容器。换端口最简单,比如 -p 16379:6379。
7.2 镜像拉取超时或失败
如果你在 pull 阶段已经卡了很久,然后又报 net/http: TLS handshake timeout,多半是网络到 Docker Hub 不通畅。优先检查镜像加速源是否配置成功,以及加速源本身是否可用。加速源经常是时好时坏的,所以多备几个,并写成数组形式,Docker 会按顺序尝试。
另一个被忽略的因素是代理环境变量。如果你在宿主机设置了 HTTP_PROXY/HTTPS_PROXY,Docker daemon 不一定继承这些变量,有时反而会因为这些变量配置不规范导致拉取失败。验证方式是把环境变量临时清掉再试。
7.3 容器启动后立刻退出
这是一个极其常见又容易让新手抓狂的问题:docker ps 看不到容器,docker ps -a 却发现容器状态是 Exited (0) 或 Exited (1)。
排查优先级如下:
第一,看日志:
bash复制docker logs my-redis
如果日志里 Redis 正常启动但立即收到停止信号,可能是容器启动方式不对。很多人会这样启动 Redis:
bash复制docker run -d --name my-redis redis:7.2-alpine /bin/bash
结果容器秒退,因为 bash 没有前台进程保持运行,容器没有任务可干,自然退出。Redis 镜像的设计是默认启动 redis-server,所以你如果不指定命令,它就能一直挂着;如果你手动覆盖命令为 /bin/bash,那 bash 执行完就结束了。
第二,检查前台/后台模式。有些镜像要求前台运行才能保持容器存活,比如 Nginx 需要 daemon off,Redis 默认就是前台运行,所以一般不用特意处理。
第三,权限问题。挂载的 /data 目录如果属于 root,但容器内进程以 redis 用户运行,就可能因为写权限不足直接启动失败。解决办法是把挂载目录的 owner 调整为容器内用户,或者干脆 chmod 777(临时调试用,生产别学)。
7.4 数据不再持久化或重启就丢
这是最大的噩梦:容器删了,数据没了。回头看是不是没有挂载 /data 目录。
如果当初启动命令里没有 -v,Redis 的数据全部写在容器可写层,容器一删,数据就随风消散。即便你用了 docker commit 把容器提交为镜像,也只在提交的那一刻做快照,之后的新写入照样丢失。
所以 Redis 容器化运行,必须建立这个肌肉记忆:
-
RDB 快照和 AOF 文件默认写入
/data目录。 -
启动容器时用
-v 宿主机目录:/data将数据目录挂载到宿主机。 -
搭配配置文件时,把
appendonly yes也设置好,避免只有 RDB 导致丢失最近几秒的写入数据。
还有一种情况是 Redis 进程因为内存不足触发 OOM,容器被杀。排查方法:dmesg | tail 看内核日志里有没有 OOM 记录,或者用 docker inspect 查看容器的内存限制。如果是宿主机内存吃紧,适当限制 Redis 的 maxmemory,避免它把宿主机的内存打满。
7.5 重新加载后的镜像名变为 <none>:<none>
之前提过一次,这里再强调一下:docker load 之后如果镜像名显示为 <none>:<none>,说明 tar 包里缺少完整的仓库名和标签信息。常见原因是 save 时用的不是“仓库名:标签”的格式,比如只用 docker save 镜像ID 就打包了,load 出来自然没名字。
解决办法是 save 时严格写全名。如果已经出了这种镜像,可以用 docker tag 补一个标签:
bash复制docker tag <镜像ID> redis:7.2-alpine
当然,这里 <镜像ID> 是你 load 出来的那个镜像是的真实 ID,用 docker images 查看。
8. 工具选型与进阶建议
到这里,一条完整的“搜索 -> 拉取 -> 打包 -> 删除 -> 加载 -> 运行”流程已经结束了。不过既然主题是实战,我还想延伸聊几个能提升 Docker 使用体验的工具和习惯。
8.1 docker compose:多容器场景的更好选择
如果你已经能熟练操作 Docker 命令,下一个需要掌握的就是 Docker Compose。像 Redis 这种单容器应用,用命令直接跑问题不大;但假如你要同时跑 Redis、MySQL、Nginx、后端服务,再用一条条命令去拼,维护成本会直线上升。
举个最简单的 docker-compose.yml 例子:
yaml复制version: "3.8"
services:
redis:
image: redis:7.2-alpine
container_name: my-redis
ports:
- "6379:6379"
volumes:
- /opt/redis/data:/data
- /opt/redis/conf/redis.conf:/etc/redis/redis.conf
restart: unless-stopped
然后执行 docker compose up -d,整个容器环境和配置都固化在了文件里。下次换服务器,复制这个 yml 过去,up -d 一把梭,省去敲长命令和记参数的麻烦。
8.2 镜像瘦身与安全建议
我上文推荐过 alpine 版本的镜像,这其实就是一种瘦身思路。除了选镜像之外,自己构建镜像时也要注意控制体积:尽量使用多阶段构建、清理 apt/ apk 缓存、避免把不必要的开发依赖打进生产镜像。体积小不单单是省磁盘,更意味着网络传输快、冷启动快、暴露的攻击面更小。
安全方面,提醒几件事:
-
Redis 容器不要裸奔在公网上。默认无密码的 Redis 一旦被扫到,轻则数据被删,重则被写入恶意任务。所以设置 requirepass 是底线,不是可选项。
-
尽量使用非 root 用户运行 Redis 容器。官方 Redis 镜像已经默认创建了
redis用户,如果自己不放心,可以在 Dockerfile 里显式USER redis,或者运行时用--user参数指定。 -
定期用
docker scan或者第三方镜像扫描工具检查镜像漏洞。Redis 这种基础组件一旦有 CVE 爆炸,影响面会非常大,提早发现并升级镜像版本是必要的运维习惯。
8.3 从这套流程中延伸出的学习路径
如果你把今天这条链路从头到尾手动敲过一遍,并且理解了每一步在做的事情,那么下一步我建议你按这个顺序进阶:
-
用 Dockerfile 自己构建一个定制 Redis 镜像,比如加入自己的配置文件、扩展模块。
-
用 docker compose 组织一套真实业务环境,比如 Web + Redis + MySQL。
-
学习 Docker 网络模型,搞清楚 bridge、host、overlay 这几种模式的区别和应用场景。
-
再往后就是 Kubernetes 了,但不用急,把 Docker 的地基打牢,学 K8s 时很多概念会感觉似曾相识,反而轻松很多。
我个人在实际操作中的体会是:这套流程最容易被轻视,但恰恰是最值得反复练习的。很多复杂问题上手前,你只需要静下心把镜像这一层理顺,就已经解决了大半。最后再分享一个小技巧:每次跑容器之前,先想清楚“这个容器的数据到底存放在哪里”,带着这个问题去写参数,你会发现自己少踩很多坑。
