第八篇:《Dockerfile 指令精讲(一):FROM、RUN、COPY、ADD》

Dockerfile 是定义镜像构建过程的脚本。掌握常用指令,你可以将任何应用打包成可复用的镜像。本文从最基础的 FROM、RUN、COPY、ADD 开始,详细讲解每个指令的语法、最佳实践和常见陷阱。

一、Dockerfile 基础概念

Dockerfile 是一个文本文件,包含一系列指令,每条指令构建镜像的一层。Docker 会按顺序执行这些指令,并缓存中间层以加速后续构建。

构建命令:

bash 复制代码
docker build -t myimage:tag .

-t:指定镜像名称和标签。

.:构建上下文(当前目录),Docker 会将此目录下的文件发送给 Docker 守护进程。

二、FROM:指定基础镜像

语法:

dockerfile

FROM --platform= : AS

作用:所有 Dockerfile 必须以 FROM 开头(除了 ARG 指令)。它定义了构建起点。

最佳实践:

优先选择官方镜像,如 alpine、ubuntu、node:18-alpine。

明确指定 tag,避免 latest(不可预测)。

多阶段构建时使用 AS 命名阶段。

示例:

dockerfile

FROM alpine:3.18

FROM node:18-alpine AS builder

FROM scratch # 用于构建极简镜像

三、RUN:执行命令

语法:

dockerfile

shell 形式(默认 /bin/sh -c)

RUN

exec 形式(推荐,避免 shell 解析问题)

RUN "executable", "param1", "param2"

作用:在构建过程中运行命令,通常用于安装软件包、编译代码、设置权限等。每一条 RUN 会创建新的一层。

最佳实践:

将多个 RUN 命令合并为一条,使用 && 连接,减少镜像层数。

清理临时文件(如 apt-get clean、rm -rf /var/lib/apt/lists/*)在同一层进行,避免残留。

示例:

dockerfile

不推荐:多层

RUN apt-get update

RUN apt-get install -y curl

RUN rm -rf /var/lib/apt/lists/*

推荐:合并

RUN apt-get update && apt-get install -y curl

&& rm -rf /var/lib/apt/lists/*

四、COPY:复制文件

语法:

dockerfile

COPY --chown=: <源路径>... <目标路径>

COPY --chown=: "\<源路径\>",... "\<目标路径\>" # 路径含空格时使用

作用:将构建上下文中的文件/目录复制到镜像中。

特点:

源路径必须是构建上下文内的相对路径。

目标路径可以是绝对路径或相对于 WORKDIR 的相对路径。

支持通配符(*、?)。

自动创建目标路径中不存在的目录。

最佳实践:

优先使用 COPY,除非需要自动解压(ADD 的特权)。

指定 --chown 以设置正确的文件所有者,避免权限问题。

复制时注意 .dockerignore 文件,排除无用内容。

示例:

dockerfile

COPY . /app # 复制所有文件到 /app

COPY --chown=node:node package.json /app/

COPY *.txt /app/data/

五、ADD:增强版 COPY

语法:同 COPY,但额外支持:

源路径可以是 URL(自动下载)。

源路径若是 tar 压缩包(.tar、.tar.gz 等),自动解压到目标路径。

示例:

dockerfile

ADD https://example.com/file.tar.gz /tmp/ # 下载并解压

ADD app.tar.gz /usr/local/ # 自动解压

注意:

官方建议:除非需要自动解压,否则使用 COPY。因为 ADD 的 URL 下载和自动解压行为不够透明,且无法利用缓存。

从 URL 下载的文件不会被缓存(除非文件内容和 URL 完全不变),可能影响构建速度。

六、构建上下文与 .dockerignore

构建上下文:执行 docker build 时,指定路径下的所有文件都会被压缩发送给 Docker 守护进程。如果目录很大,构建会变慢。

.dockerignore:类似 .gitignore,用于排除不需要的文件,例如:

text

node_modules/

*.log

.git/

.DS_Store

七、综合示例:构建一个 Node.js 应用镜像

dockerfile

使用 Node.js 18 Alpine 作为基础镜像

FROM node:18-alpine AS builder

设置工作目录

WORKDIR /app

复制 package.json 和 package-lock.json(先复制依赖文件,利用缓存)

COPY package*.json ./

安装依赖

RUN npm ci --only=production

复制应用代码

COPY . .

多阶段构建:运行时镜像

FROM node:18-alpine

WORKDIR /app

从 builder 阶段复制依赖和代码

COPY --from=builder /app/node_modules ./node_modules

COPY --from=builder /app /app

暴露端口

EXPOSE 3000

启动应用

CMD "node", "server.js"

构建命令:

bash 复制代码
docker build -t my-node-app .

八、常见问题与解决

九、小结

FROM 定义基础镜像,RUN 执行构建命令,COPY 和 ADD 复制文件。熟练掌握这些指令,你已经能编写大多数应用的 Dockerfile。核心优化原则:

选择合适的基础镜像(Alpine 优先)。

合并 RUN 命令以减少层数。

利用构建缓存:将变动频率低的指令前置。

使用 .dockerignore 排除无关文件。

相关推荐
woniu_buhui_fei15 小时前
Redis实现分布式限流
数据库·redis·分布式
杜子不疼.15 小时前
从“能用“到“敢用“:DolphinDB 通过国家安全可靠测评,时序数据库国产替代迈入新阶段
数据库·oracle·时序数据库
量子-Alex15 小时前
【大模型智能体】A practical guide to building agents
大数据·数据库·人工智能
YOU OU15 小时前
Spring事务和事务传播机制
java·数据库·spring
闪电悠米15 小时前
黑马点评-优惠券秒杀-01_redis_global_id
数据库·redis·缓存
ai产品老杨16 小时前
解耦异构算力:基于 Docker 与边缘计算的 GB28181/RTSP 企业级视频智能分析平台架构实践(支持源码交付)
docker·音视频·边缘计算
“码”力全开16 小时前
打破硬件与协议壁垒:基于 Docker + 边缘计算的 GB28181/RTSP 视频智能管理平台架构设计(附源码交付)
docker·音视频·边缘计算
qq_4523962316 小时前
第七篇:《Docker 存储:Volume、Bind Mount 与 tmpfs》
运维·docker·容器
牧羊狼的狼16 小时前
MySQL 提升SQL查询性能的全套实战优化方法
数据库·sql·mysql