尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Docker从概念到实践:镜像、容器与Compose编排实战

发布时间:2026/9/18 18:07:23

资讯中心
01
ARTICLE

Docker从概念到实践:镜像、容器与Compose编排实战

Docker从概念到实践:镜像、容器与Compose编排实战
开篇先给大家交个底这篇文章我根本没打算写成又长又绕的官方文档而是站在一个用过 Docker 两三年、踩过无数坑的普通开发者角度把“Docker 到底是个啥”和“我怎么用它干活”这两件事讲清楚。我把题目定成“从概念到实践”就是想带大家把最抽象的容器技术和最具体的安装、打包、部署动作串成一条线看完你不仅能理解镜像、容器、仓库这些名词还能亲手在 Windows 或 Linux 上装好 Docker跑起第一个容器甚至能自己写 Dockerfile 把一个 Python 服务打成镜像再用 Docker Compose 拉一套 Redis 主从环境。最近后台收到不少私信问的都是同一类问题Docker 安装教程那么多为什么我照着装完还是起不来Docker Desktop 和 WSL2 到底什么关系为什么别人的一个镜像那么小我构建出来的却几百兆这些问题我全都经历过。所以这篇文章会刻意偏“实战”把每一步操作的意图、背后的逻辑、还有那些不会写进官方文档的坑都翻出来讲。适合刚接触容器的人也适合已经会用 docker run 但还没系统理解镜像构建和服务编排的人。文章底部我还会放一套日常命令清单和排查思路建议收藏后面用得上。1. Docker 到底解决了什么问题理解容器化思维的切入点几乎每一个 Docker 教程都会先解释“容器是轻量级虚拟化”但说实话这种话对新手来说太抽象了。我更喜欢用一个场景来引出 Docker 的价值。1.1 “在我机器上是好的”这句话背后的问题你想想看团队里是不是永远有一个“跑不起来”的同事他明明照着 README 配了环境代码一运行就报数据库连不上、字体缺失、libc 版本不对。原因很简单他机器上的操作系统版本、系统依赖库、环境变量、配置文件都跟你不一样。传统虚拟机能解决一部分问题但它太重了——一个虚拟机要装完整操作系统启动要几分钟占几个 GB 内存这种开销放在现代开发和运维流程里实在不划算。Docker 的做法是把“应用”和“它需要的最小运行环境”打包成一个标准化单元。这个单元里包含代码、运行时、系统工具、库、配置文件走到哪都能用同一个方式启动。你可以把它理解成集装箱以前运一船货每个箱子大小不一、固定方式各异装卸效率很低现在所有货物都装进标准尺寸的集装箱吊机、卡车、货轮全部按标准对接整个物流效率就上来了。Docker 就是这个物流体系里的集装箱标准。1.2 Docker 和传统虚拟机的关键差异很多人问我Docker 和 VMware、VirtualBox 有什么区别这里用一个表格就能说清对比点传统虚拟机Docker 容器虚拟化层级硬件级虚拟化模拟 CPU、内存、硬盘操作系统级虚拟化共享宿主机内核启动速度分钟级要引导完整操作系统毫秒到秒级本质是启动一个进程占用空间数个 GB 起步含完整系统几十到几百 MB按镜像分层复用隔离程度强隔离每个系统独立内核进程级隔离共享内核但隔离资源资源利用率较低大量资源被系统占掉很高只多跑应用本身所以 Docker 不是“更小的虚拟机”而是一种完全不同的隔离方式。它利用 Linux 内核的 namespace 和 cgroup 机制把进程、网络、文件系统、CPU、内存分隔开。这就像一个公寓楼每个房间的人各自生活互不打扰但大家共用一套水电系统。1.3 学完这一节你该记住的核心认知Docker 的三个关键词是镜像、容器、仓库。镜像是一个只读模板容器是镜像运行后的实例仓库是存放镜像的地方。这三个概念我会在下一节展开但你心里得有根弦Docker 的全部操作几乎都是围绕“找镜像、跑容器、改配置、打包新镜像、发布到仓库”这条链路进行的。我在实际工作中的体会是一旦把思维从“装环境”转换成“拉镜像”很多部署问题就自动消失了。以前在新机器上部署一个 Java 服务要装 JDK、配 Maven、装 Redis、配 Nginx每次至少折腾半天现在一条docker run下去环境直接到位。这就是 Docker 最朴素却最大的价值——它把“环境交付”变成了“代码交付”的一部分。2. 装机前的三个核心概念镜像、容器、仓库怎么用生活类比一次讲清我知道很多人急着想安装 Docker但如果你不理解镜像和容器的关系后面写 Dockerfile 和搭 Compose 的时候一定会卡壳。所以哪怕你急也请花几分钟把这一节看完。2.1 镜像Image更像是“模具”而不是“安装包”很多教程把镜像比作安装包我觉得这个类比不够准确。安装包是“把文件复制到系统里”而镜像是“一个只读的模板”本身不带状态。我更愿意把镜像比作月饼模具模具决定了月饼的形状、花纹、大小但你每次用模具做出来的月饼是独立的可以在这个基础上有不同馅料。在技术层面镜像是由一层层只读文件系统组成的。每一层对应 Dockerfile 里的一条指令比如FROM、RUN、COPY。这些层可以被多个镜像共享复用这也是为什么你机器上只装了一个基础镜像却能跑很多基于它的应用磁盘占用并不大。一个镜像通常包含基础操作系统文件精简版、应用运行所需的运行时比如 Python、Node、应用代码、依赖包、启动命令。你可以用docker history 镜像名查看一个镜像是怎么一层层构建出来的这对排查镜像为什么那么大特别有用。2.2 容器Container是镜像的“运行态”容器是镜像跑起来之后的实例。我们可以这样理解镜像是模具容器是模具压出来的月饼镜像是类容器是对象镜像是菜谱容器是按菜谱做出来的那一盘菜。核心点在于同一个镜像可以同时启动多个容器它们彼此隔离、互不影响而且容器是可写、可变、可删除的。容器启动后你可以在里面安装工具、修改文件、跑程序但这些改动只在当前容器里生效。一旦容器被删除改动就全没了。所以正确做法是环境相关的配置用镜像管理数据用数据卷持久化临时改动只用来调试。2.3 仓库Registry就是“镜像的应用商店”仓库存放镜像并提供拉取、推送功能。Docker Hub 是默认的公共仓库里面有大量官方镜像像nginx、redis、mysql、python。国内也有不少镜像仓库服务你可以把私有镜像传上去方便团队共享。这里要提一个很实际的点直接访问 Docker Hub 拉镜像速度时快时慢所以国内环境通常要配置 registry mirror镜像源。这个配置不是“加速器”只是让 Docker 客户端优先从一个同步了官方镜像的国内仓库拉取。配置方法我们下一节讲安装的时候一起说。仓库和镜像的命名规则也很简单仓库地址/命名空间/镜像名:标签。标签tag用来区分版本常见的有latest、3.12、v1.0.0。没有写标签时默认拉latest。2.4 概念补全数据卷和网络的作用光有镜像和容器还不行因为容器删了之后数据也丢了你总不能让数据库容器一重启就清空数据。于是 Docker 引入了数据卷volume和绑定挂载bind mount用来把容器内的目录映射到宿主机上。我常把数据卷比作“外置硬盘”容器可以随时换新但硬盘里的数据一直在。网络方面Docker 默认会给容器分配独立 IP但容器重建后 IP 会变所以更可靠的做法是使用 Docker 网络中的 DNS 名称互访或者用端口映射把容器端口暴露到宿主机。后面的 Redis 主从案例里我会具体演示这两个配置怎么用。3. Windows 与 Linux 下的 Docker 环境安装实录概念有了现在进入动手环节。我按 Windows 和 Linux 两条路线分别写你根据自己情况选一条走。3.1 WindowsDocker Desktop 完整安装链路Docker Desktop 是目前 Windows 上最省心的方案它自带管理界面、命令行工具和 Kubernetes 支持。安装的完整链路如下检查系统版本Windows 10 64 位 Pro/Enterprise/EducationBuild 1903或 Windows 11。家庭版也能装但需要额外手动启用 Hyper-V 或 WSL2所以我建议直接升级到专业版或企业版。开启 WSL2以管理员身份打开 PowerShell依次执行wsl --install这一步会默认安装 WSL2 和 Ubuntu 发行版。如果系统较老可能需要手动更新 WSL2 内核。装完用wsl --set-default-version 2把默认版本设为 2。下载并安装 Docker Desktop从 Docker 官网下载安装包双击执行。安装时勾选“Use WSL 2 instead of Hyper-V”选项大多数版本默认已选。重启后启动 Docker Desktop右下角小鲸鱼图标变绿说明引擎已运行。这里有个新手最容易困惑的点为什么 Docker Desktop 在 Windows 上非要依赖 WSL2 或 Hyper-V原因是 Docker 容器本身依赖 Linux 内核特性而 Windows 内核不提供这些接口所以必须借助 WSL2 这个轻量虚拟机在后台跑一个真正的 Linux 内核所有容器都运行在那个 Linux 环境里。WSL2 和 Hyper-V 二选一我强烈推荐 WSL2因为启动更快、内存占用更少、和文件系统交互也更顺滑。3.2 Linux 服务器一条命令装好 Docker Engine在 Ubuntu/Debian 系系统上官方推荐先用 apt 配置仓库再安装。完整命令如下sudo apt update sudo apt 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 \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin装完执行sudo systemctl enable --now docker设置开机自启。国内服务器如果拉取官方 GPG 地址慢可以把download.docker.com换成清华或阿里的镜像仓库地址这个属于常规软件源替换不影响后续使用。3.3 装完必做的两项验证与 Registry 镜像源配置不管哪个平台装完第一步验证引擎是否正常docker version docker run hello-world能打印客户端和服务端版本信息并且成功输出 “Hello from Docker!” 说明环境没问题。如果docker version只显示客户端但服务端报错多半是后台引擎没启动或 WSL2 没就绪。接下来配置 Registry 镜像源。以 Docker Desktop 为例打开 Settings - Docker Engine在 JSON 配置中加入{ registry-mirrors: [ https://docker.m.daocloud.io, https://dockerproxy.com ] }Linux 下修改/etc/docker/daemon.json没有就新建一个。改完重启 Dockersudo systemctl restart docker配置完成后拉镜像速度会有肉眼可见的提升。这里提醒一句镜像源地址会变化如果你配置的源失效可以换几个公开源轮流测试用docker pull nginx:latest试速度即可。4. 第一个容器实战用 Nginx 跑通“下载-运行-访问”全流程环境准备好之后第一件事就是跑一个真正的服务。Nginx 官方镜像很小、配置简单、验证效果直观是最佳第一站。4.1 拉取镜像与创建容器的完整命令拆解先拉镜像docker pull nginx:latest拉完可以用docker images查看本地镜像列表能看到 nginx 镜像的大小大概几十 MB。接下来创建并启动容器docker run -d --name my-nginx -p 8080:80 nginx这条命令看着简单背后每个参数都有实际意义-d后台运行让容器在后台跑而不占用终端。如果不加这个参数容器会以前台方式运行你能直接看到 Nginx 访问日志但终端会被占住。--name my-nginx给容器起个名字方便后续管理。不命名的话 Docker 会随机生成一个名字特别难记。-p 8080:80端口映射宿主机 8080 端口对应容器 80 端口。nginx要使用的镜像名。启动后执行docker ps能看到容器状态为 Up。然后在浏览器访问http://localhost:8080看到 Nginx 欢迎页就说明整个链路通了。这个“通了”意味着镜像拉取成功、容器引擎正常、端口映射生效、Nginx 进程在容器内成功运行。4.2 端口映射和数据卷挂载的底层逻辑为什么一定要-p 8080:80因为容器自身在一个隔离的网络空间里外部网络默认访问不到容器的 IP 和端口。端口映射相当于在宿主机上开了个门把宿主机 8080 端口收到的流量转给容器的 80 端口。默认 Nginx 页面是容器内部的文件系统我们想修改页面内容时总不能每次docker exec进容器改文件改完容器一删就没了。正确做法是挂载数据卷docker run -d --name my-nginx -p 8080:80 -v /my/host/html:/usr/share/nginx/html nginx-v就是把宿主机的/my/host/html目录挂载到容器的/usr/share/nginx/html。以后改宿主机目录下的 HTML 文件Nginx 页面立刻生效不用再进容器。这个模式对任何需要持久化或频繁改配置的场景都适用比如后面 Redis 的持久化、MySQL 的数据目录都得靠挂载才不会丢数据。4.3 容器生命周期管理的小细节跑起来之后你一定会用到这组命令docker ps # 查看运行中的容器 docker ps -a # 查看所有容器包括已停止的 docker stop my-nginx # 停止容器 docker start my-nginx # 启动已停止的容器 docker restart my-nginx # 重启容器 docker rm -f my-nginx # 强制删除容器 docker exec -it my-nginx bash # 进入容器内执行命令这里有一个很多人犯的错误想清理容器时直接执行docker rm my-nginx结果提示容器还在运行然后就去加-f。-f确实能强制删但生产环境最好不要乱用先docker stop让容器优雅退出再docker rm这样能让进程有机会做资源回收。虽然对 Nginx 这种无状态服务影响不大但对数据库这类有状态的容器强制删除可能损坏数据文件。5. 自己动手写 Dockerfile把一个 Python 服务打包成镜像现在你已经能跑别人做好的镜像了。可实际项目中我们往往要把自己的应用打包成镜像。这一节我用一个最简单的 Python Flask 服务来演示完整流程。5.1 最小可用 Dockerfile 逐行解读假设我们的项目结构如下myapp/ app.py requirements.txt Dockerfileapp.py内容from flask import Flask app Flask(__name__) app.route(/) def hello(): return Hello, Docker! if __name__ __main__: app.run(host0.0.0.0, port5000)requirements.txtflask2.3.2接下来是核心的 DockerfileFROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY app.py . EXPOSE 5000 CMD [python, app.py]逐行拆解FROM python:3.11-slim指定基础镜像。slim是精简版去掉了很多用不到的编译工具和文档体积大幅缩小。WORKDIR /app设置容器内的工作目录。之后所有命令都在这个目录下执行。COPY requirements.txt .把本地的 requirements.txt 复制到容器内工作目录。RUN pip install --no-cache-dir -r requirements.txt安装依赖。--no-cache-dir是 pip 参数避免在镜像里缓存安装包能减少镜像体积。COPY app.py .把代码复制进去。EXPOSE 5000声明容器内服务使用 5000 端口。这个指令只是声明不实际映射端口最终端口映射仍要用-p。CMD [python, app.py]容器启动时执行的命令。CMD 在一个 Dockerfile 里只能有一个而且推荐用 JSON 数组格式直接写python app.py也可以但数组格式更规范不会经过 shell 解析避免特殊字符问题。5.2 构建镜像与 IDE 打包的实操对照在项目根目录执行docker build -t my-flask-app:v1 .-t给镜像打标签最后的.是构建上下文路径Docker 会把该目录下的文件发送给构建引擎。构建完成后运行docker run -d --name flask-app -p 5000:5000 my-flask-app:v1浏览器访问http://localhost:5000看到 “Hello, Docker!” 就成功了。很多读者问到“IDEA 打包 docker 镜像”的问题。如果你用的是 IntelliJ IDEA推荐安装官方 Docker 插件在运行配置里选择 Dockerfile 类型指定 Dockerfile 路径和镜像标签点运行效果和命令行docker build是一样的。IDE 的优势在于集成部署写好代码后一键构建镜像并启动容器不用切命令行。但底层机制没区别所以核心还是你要能看懂 Dockerfile。5.3 镜像瘦身的几个进阶技巧构建完看一下镜像大小docker imagespython:3.11-slim 基础镜像大概 100 多 MB加上 Flask 依赖最终 200 MB 左右很正常。但如果你的项目依赖很重或基础镜像用的是完整版 python:3.11300 多 MB那镜像体积可能飙到 1 GB 以上。瘦身思路有这么几条优先选slim或alpine版本基础镜像。但要注意 alpine 用的是 musl libc有些二进制包需要额外编译不是完全无代价。合并 RUN 命令减少镜像层数。RUN a b c优于三条 RUN因为每一层都会保留中间文件系统快照。及时清理临时文件。比如 apt 安装后执行apt-get clean rm -rf /var/lib/apt/lists/*。充分利用.dockerignore文件排除node_modules、__pycache__、.git等不需要的文件进入构建上下文。这里我特别想说一下.dockerignore。很多新手构建镜像是把自己本地整个项目目录全打进去结果镜像里混进了__pycache__、日志文件甚至.env密钥既臃肿又有安全风险。一个最小.dockerignore示例__pycache__/ *.pyc .git .env venv/ *.log6. 组合实战用 Docker Compose 快速拉起 Redis 主从架构单个容器好跑一旦涉及多个服务比如后端加数据库加缓存再加前端你还一个个docker run就太痛苦了。Docker Compose 就是用来做多容器编排的。它用一个 YAML 文件描述整个应用的服务、网络、依赖关系一条命令全部拉起。这里我用 Redis 主从架构来演示因为热搜词里也有“docker安装redis主从”而且这个案例非常经典。6.1 Docker Compose 文件设计思路先规划一下我们要的架构一个 Redis 主节点负责写一个 Redis 从节点负责读从节点自动同步主节点数据。在docker-compose.yml里这样写services: redis-master: image: redis:7.2 container_name: redis-master command: [redis-server, --appendonly, yes] ports: - 6379:6379 volumes: - redis-master-data:/data networks: - redis-net redis-slave: image: redis:7.2 container_name: redis-slave command: [redis-server, --slaveof, redis-master, 6379] depends_on: - redis-master ports: - 6380:6379 volumes: - redis-slave-data:/data networks: - redis-net volumes: redis-master-data: redis-slave-data: networks: redis-net:设计思路拆一下主从节点都用官方redis:7.2镜像但启动命令不同。主节点开了 AOF 持久化从节点通过--slaveof redis-master 6379指定主节点的服务名和端口。这里有个核心知识点在 Compose 创建的自定义网络里服务可以直接用服务名互相访问。所以redis-master这个主机名是由 Compose 自动解析的不需要关心容器的 IP。depends_on确保从节点在主节点启动后才创建。注意它只控制启动顺序不保证主节点已经就绪但 Redis 从节点即使连接不上主节点也会自动重试所以这个场景下足够用。两个数据卷分别挂载到/data保证容器删除重建后数据还在。6.2 启动与验证主从复制执行启动命令docker compose up -d-d同样是后台运行。查看状态docker compose ps应该看到两个容器都是 Up 状态。用小工具验证主从关系先进入主节点写入数据docker exec -it redis-master redis-cli SET mykey hello再进入从节点读取docker exec -it redis-slave redis-cli GET mykey能返回hello就说明主从复制已经生效。也可以用docker exec -it redis-slave redis-cli INFO replication查看role:slave和master_link_status:up。6.3 依赖管理视角Compose 如何解决服务编排痛点写到这里我想跳出来讲一个容易被忽略的价值Compose 其实也是一种依赖管理工具只不过它管理的是服务依赖。你不需要手动确认主节点先启动、网络先创建、数据卷先分配Compose 用声明式配置把这些依赖全部处理好了。这跟你在代码里用 pip 管理 Python 依赖、用 npm 管理前端依赖是同一个思路把“依赖”从人的记忆里摘出来写进文件可复制、可审计、可回滚。实际项目中一个典型 Web 服务的 Compose 文件往往包含前端容器、后端容器、MySQL、Redis、Nginx每加一个服务只需要在 YAML 里加一段配置然后docker compose up -d全部搞定。如果要换环境部署把整个目录和.env变量配置拷过去同样命令就能起来。这套工作流在开发一致性和交付效率上的提升是手敲命令比不了的。7. 日常使用离不开的命令清单与资源回收Docker 命令很多但日常真正常用的就那二三十个。我按场景整理了一份高频清单建议直接收藏。7.1 高频命令按场景分类镜像相关docker images # 列出本地镜像 docker pull nginx:latest # 拉取镜像 docker rmi nginx:latest # 删除镜像-f 强制 docker tag nginx:latest my-nginx:v1 # 给镜像打标签 docker build -t myapp:v1 . # 构建镜像容器相关docker ps # 查看运行中容器 docker ps -a # 查看所有容器 docker run -d -p 8080:80 --name web nginx # 创建并后台运行 docker start/stop/restart web # 启停 docker rm -f web # 删除容器 docker exec -it web bash # 进入容器 docker logs -f web # 跟踪日志 docker stats # 查看资源占用 docker inspect web # 查看容器详细信息Compose 相关docker compose up -d # 启动所有服务 docker compose down # 停止并删除容器、网络 docker compose logs -f # 聚合日志 docker compose ps # 查看服务状态 docker compose exec web bash # 进入某个服务容器网络与数据卷docker network ls docker network inspect redis-net docker volume ls docker volume prune7.2 磁盘吃紧时的清理策略Docker 用久了最烦人的就是磁盘爆满。镜像、容器日志、悬空镜像dangling image、无用的数据卷都占空间。清理姿势建议分三步走第一步安全清理不再使用的悬空资源docker system prune这会删除所有已停止的容器、无用的网络、悬空镜像和构建缓存但不会动正在使用的镜像和数据卷。如果确认数据卷也不要了可以加--volumes但生产环境慎用因为数据卷里存的是数据。第二步清理超大日志文件。容器日志默认在/var/lib/docker/containers/id/*-json.log长期不清理可能单个文件好几个 GB。运行超过一年没管过的服务器经常是日志占满了磁盘而不是镜像。建议对长期运行的容器配置日志轮转在daemon.json中加入{ log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 } }配置后新容器日志单文件超过 10 MB 自动滚动保留 3 个文件。落地这个配置能根治日志爆盘问题。第三步定期审视镜像列表用不到的镜像及时docker rmi。如果系统里已经积累了成百上千个历史镜像可以考虑docker image prune -a它会删除所有没有被容器引用的镜像比较激进但释放空间效果明显。8. 我从实践中总结的踩坑经验聊了这么多最后这一节全是我自己踩过的坑和复盘后的经验。没有排序想到哪写到哪但每条都值得你留意。8.1 Windows 上 Docker Desktop 启动不了怎么办Docker Desktop 在 Windows 上最常见的失败原因有三个一是 WSL2 没装好二是 BIOS 里虚拟化没开启三是 Docker Desktop 和 Hyper-V 冲突。排查思路建议按顺序来在 PowerShell 执行wsl --status看 WSL 版本如果不是 2 就执行wsl --set-default-version 2再打开任务管理器 - 性能看虚拟化是否显示“已启用”如果没启用重启进 BIOS 找 Intel VT-x 或 AMD-V 选项打开最后检查是否安装了其他虚拟机软件如老版 VirtualBox它们可能占用了 Hyper-V 功能。这三板斧能解决九成以上的启动失败问题。8.2 容器内时区和编码问题的处理很多应用镜像默认时区是 UTC日志时间比北京时间差 8 小时。解决方案是在运行容器时挂载宿主机的时间文件docker run -v /etc/localtime:/etc/localtime:ro -v /etc/timezone:/etc/timezone:ro ...或者在 Dockerfile 里设置时区ENV TZAsia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ /etc/timezone中文乱码问题通常是因为镜像里没装中文字体和 locale。轻量镜像为了控制体积经常砍掉了这些语言包遇到乱码先确认是不是要在容器里显示中文如果是建议在基础镜像选择时就考虑带中文字体的镜像或者接受英文输出不要在生产环境里为了乱码问题反复折腾 locale。8.3 关于依赖管理和镜像复用的个人心得最后分享一个设计层面的体会。很多人写 Dockerfile 时习惯把依赖安装和应用代码复制混在一起导致每次改一行代码都要重新下载所有依赖。这里推荐利用 Docker 构建缓存把COPY requirements.txt放在代码复制之前这样只要依赖文件没变后续构建都会命中缓存只有代码变更时才会重新构建最后一层。这个顺序的调整能让构建速度从几分钟降到几秒在频繁提交代码的开发阶段特别重要。另外如果一个项目的多个服务共用同一套基础依赖可以考虑构建一个自定义基础镜像把公共依赖放进去业务镜像FROM这个基础镜像。这比每个镜像单独安装依赖省时省磁盘升级公共依赖也只需要改基础镜像。这个思路其实跟代码里抽取公共模块是同一件事所谓“封装变化”“复用不变”放到容器化场景里同样成立。我在实际项目中见过太多把 Docker 用成“高级虚拟机”的团队手动进容器改配置、重启容器丢数据、镜像越积越臃肿。这些都是没有真正理解镜像是不可变基础设施的一种表现。学习 Docker 最有效的路径永远是先把一个镜像从零到一构建出来再跑起来再把它编排成一套服务。这篇文章的案例只要跟着做一遍你对容器的理解就会比只看文档的人深得多。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。