Dockerfile知识点梳理,你要搞懂的都在这

前言

距离上一篇《你真的搞明白我们为什么要使用 docker 了么》发布已过去一年。如果这一年里你很少接触 Docker,大概率已经记不清 Dockerfile 的配置细节了 ------90% 的人都会这样,包括我自己,甚至偶尔会恍惚 "当初为什么要用 Docker 来着?"。

想要快速重拾记忆,最有效的方法莫过于联想法:把抽象的技术概念和日常场景绑定,理解起来会更轻松。

什么是Dockerfile

先简单回顾:

  • 从日常视角看,Dockerfile就像一份菜谱:做一道菜需要按步骤准备食材、调味、烹饪,Dockerfile 则定义了构建镜像的 "食材"(基础环境、依赖)和 "步骤"(配置、打包、启动)。
  • 从技术视角看,它类似 "打包 exe 的过程":通过一系列指令将应用及其依赖打包成标准化镜像,确保在任何环境都能 "一键运行"。

Dockerfile 常用命令详解

下面结合前端(React)和后端(FastAPI)的实际案例,拆解常用命令。

在此之前,先理清两个容易混淆的概念:

CMD和RUN的不同

两者都用于执行命令,但核心差异在于执行时机:

RUN:在构建镜像时执行(比如安装依赖、编译代码),作用是 "准备镜像内容",结果会被永久保存在镜像层中。 CMD:在容器启动时执行(比如启动服务、运行脚本),作用是 "定义容器的默认行为",构建镜像时不会执行。

--from=builder是什么意思?

这是 Docker多阶段构建的核心语法,作用是 "从指定的构建阶段复制文件到当前阶段"。

用 "做菜" 比喻:

第一阶段(比如命名为builder)像 "备菜区":用复杂工具(如 Node 环境)处理原料(源代码),生成半成品(如 React 的 build 文件夹)。 第二阶段像 "装盘区":用轻量容器(如 Nginx)直接盛放半成品,省去备菜时的工具(如 Node 环境)。 --from=builder就像 "从备菜区把切好的菜端到装盘区",最终只保留成品,避免工具占用空间。

例子1: 我们先来一个React 前端应用的dockerfile文件

js 复制代码
## 第一阶段 (构建react应用)
# 第一步:选择基础镜像, 使用alpine版本的镜像,可以减少打包的体积,加快打包速度
FROM node:18-alpine

# 第二步:设置工作目录, 相当于在容器内的服务器上创建app目录,后续的CMD,RUN命令都在app目录中执行
WORKDIR /app

# 第三步:复制 package.json 和 package-lock.json
COPY package*.json package-lock.json ./

# 第四步:安装依赖, npm ci是安装依赖的命令,可以安装更快
RUN npm ci

# 第五步:复制项目所有文件
COPY . .

# 第六步:构建 React 应用
RUN npm run build

## 第二阶段(运行react应用)
# 第一步:选择基础镜像, 使用alpine版本的镜像,可以减少打包的体积,加快打包速度
FROM nginx:alpine

# 第二步:把第一阶段的构建结果放到nginx静态文件中
COPY --from=builder /app/build /usr/share/nginx/html

# 第三步:暴漏接口, 供外部访问
EXPOSE 80

# 第四步:启动nginx
CMD ["nginx", "-g", "daemon off;"]

例子2: 我们再来一个Fastapi后端应用的Dockerfile

js 复制代码
# Python 3.11(指定版本)
FROM python:3.11-slim

# 复制到 /app 目录
WORKDIR /app

# 复制依赖清单 requirements.txt
COPY requirements.txt .

# 安装依赖
RUN pip install --no-cache-dir -r requirements.txt

# 复制源代码
COPY . .

# 暴露 8000 端口
EXPOSE 9001

# 开火:启动 FastAPI 服务(类似"小火慢炖")
CMD ["python3", "run.py"]

docker的缓存机制是什么样子的?

Docker 的缓存机制:像餐厅的 "半成品储备" Docker 会把每一步指令(FROM、RUN、COPY等)的执行结果缓存为 "中间镜像"。下次构建时:

如果指令和之前完全相同,直接复用缓存,跳过执行(像 "加热现成的半成品")。 一旦某一步指令变化(比如COPY的文件内容修改),这一步及后续所有步骤的缓存都会失效,必须重新执行(像 "某道菜的原料变了,后面步骤全得重做")。

优化技巧:把 "不常变的步骤"(如安装依赖)放前面,"常变的步骤"(如复制源代码)放后面,最大化利用缓存,加快构建速度。

如何减少docker镜像体积

  1. 多阶段构建:像 React 案例那样,构建阶段用复杂环境,运行阶段只用轻量环境,剔除冗余工具(如 Node、编译器)。
  2. 选轻量基础镜像:优先用alpine(极小 Linux 发行版)或slim(精简版),比如node:18-alpine比node:18小 80% 以上。
  3. 用.dockerignore文件:排除不需要打包的文件(如.git、node_modules、日志),避免污染镜像。
  4. 清理缓存:安装依赖后删除缓存文件(如rm -rf /var/lib/apt/lists/*、--no-cache-dir)。
  5. 调整步骤顺序:利用缓存机制,减少重复构建(前面已讲)。

总结

Dockerfile 的核心是 "按步骤定义镜像构建逻辑",理解命令的执行时机(如RUN vs CMD)和缓存机制后,写起来并不复杂。

如今 AI 工具能快速生成 Dockerfile,我们的角色更偏向 "审核者":看懂每一行的作用,能根据实际需求调整(比如换基础镜像、修改端口),就足够应对大部分场景了。

参考

相关推荐
KevinPedri1 小时前
测试:uk8s创建监控和告警同步飞书等渠道
docker·kubernetes·云计算·1024程序员节
qq_327395031 小时前
ubuntu 24.04 x86_64安装docker
docker
不惑_3 小时前
如何使用 Ansible 安装 Docker
docker·github·ansible
Shannon Law3 小时前
Docker连接超时的解决方法
docker·容器
侯喵喵6 小时前
Jetson orin agx配置ultralytics 使用docker或conda
yolo·docker·1024程序员节·ultralytics
小彭律师8 小时前
Docker/K8s部署MySQL的创新实践与优化技巧大纲
mysql·docker·kubernetes
lastHertz8 小时前
Docker 占用导致 C 盘空间不足的排查与解决
运维·docker·容器
专家大圣8 小时前
Docker+Redis监控新方案:cpolar让远程管理“零配置”
网络·redis·docker·容器·内网穿透
chen_note12 小时前
Dockerfile及其部署镜像步骤
docker·容器·镜像·dockerfile
杨浦老苏18 小时前
开源云文件存储服务器MyDrive
docker·群晖·网盘