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,我们的角色更偏向 "审核者":看懂每一行的作用,能根据实际需求调整(比如换基础镜像、修改端口),就足够应对大部分场景了。

参考

相关推荐
AI大模型1 小时前
基于 Docker 的 LLaMA-Factory 全流程部署指南
docker·llm·llama
tb_first3 小时前
k8sday11服务发现(2/2)
docker·云原生·容器·kubernetes·k8s
发愤图强的羔羊3 小时前
Docker 搭建 SVN 服务器
docker
Clownseven4 小时前
Docker+Nginx+Node.js实战教程:从零搭建高可用的前后端分离项目
nginx·docker·node.js
__lll_1 天前
手把手教你用 Docker 部署 Vue 项目(含国内镜像加速 + 踩坑指南)
docker
程思扬1 天前
Nextcloud容器化部署革新:Docker+Cpolar构建高效私有云远程访问新架构
docker·容器·架构
豆芽脚脚1 天前
docker compose再阿里云上无法使用的问题
阿里云·docker·容器
十行代码九行报错1 天前
Docker基础学习笔记
笔记·学习·docker
Agome992 天前
Docker之自定义jkd镜像上传阿里云
阿里云·docker·容器