Dockerfile 常用指令怎么写?5 个最常用指令一次讲清

编程狮(w3cschool.cn) 2026-10-07 07:04:57 浏览数 (32)
反馈

Dockerfile 常用指令5 个最常用怎么写?

Dockerfile 常用指令是写出第一个可运行镜像必须掌握的最小集合:FROM 指定基础镜像,RUN 装依赖,COPY 放代码,CMD 定启动命令,EXPOSE 声明端口。本文基于 Docker 24 与 26 验证,把这 5 个指令逐一拆开讲,并给出一个能直接拿来用的完整示例。看完你不但知道每条指令怎么写,还明白它们为什么这样排,下次写镜像不再照抄网上的神秘配置。今天这篇文章,编程狮就把这块讲透。无论你是刚装好 Docker 想打出第一个镜像,还是被网上互相矛盾的 Dockerfile 配置搞晕,这篇都能让你按图索骥、照着写就能跑通。

先看结论

指令 作用 出现位置
FROM 指定基础镜像,必须是第一条 文件开头
RUN 构建时执行命令,装环境 中间
COPY 把本地文件复制进镜像 中间
CMD 容器启动时默认执行的命令 结尾
EXPOSE 声明容器监听的端口 结尾

一句话:FROM 打地基,RUN 装环境,COPY 放代码,CMD 定入口,EXPOSE 只做声明不真正端口映射。

一、先弄清楚:Dockerfile 到底是什么

Dockerfile 是一个纯文本构建脚本,每一行是一条指令,Docker 按顺序执行后产出一层镜像。把它想象成做菜的菜谱:FROM 是「用什么锅」,RUN 是「开火炒哪一步」,CMD 是「最后端上桌怎么吃」。

1.1 镜像是一层一层叠出来的

每条会改动文件系统的指令(FROM、RUN、COPY)都会生成一个只读层,最终叠成完整镜像。层数越多体积越大,所以要把变动少的指令放前面,利用构建缓存。

1.2 指令的执行顺序

Dockerfile 从上往下执行,前面层的产物后面层才能看到。先理解整体流程,再看单条指令会更清楚,建议配合 Docker 教程 的镜像章节一起读。

二、FROM 与 RUN:打地基与装环境

在 Dockerfile 常用指令中,FROM 是打地基的那一步。Dockerfile FROM 指令必须是文件第一条,它决定了你的镜像站在谁的肩膀上。优先选带版本号的小体积镜像,比如 node:20-alpine。

# 以 Node 20 的 Alpine 版本为基础
FROM node:20-alpine

镜像构建阶段 RUN 指令执行命令,这是 Dockerfile 常用指令里最常被误用的地方,常见用途是装系统包或项目依赖。多条 RUN 会各自成层,所以相关的安装最好合并到一条里:

# 合并安装,减少层数也更可读
RUN apk add --no-cache python3 make g++ \
    && npm install -g typescript

Dockerfile 构建分层流程

三、COPY 与 CMD:放代码与定入口

COPY 指令把宿主机构建上下文里的文件复制进镜像。注意它只复制,不做解压,路径相对于构建上下文。

# 把当前目录的应用代码复制进镜像的 /app
COPY . /app
WORKDIR /app

CMD 指令定义容器启动时默认跑什么,一个 Dockerfile 只能有一个生效的 CMD。它可以被 docker run 后面的参数覆盖,所以适合放「默认行为」:

# 容器启动后默认执行 node 服务
CMD ["node", "server.js"]

这两条的区别容易混:COPY 指令发生在构建阶段,把文件搬进镜像;CMD 指令在运行阶段才生效。更多写法示例见 use_docker 教程。

四、EXPOSE 与完整 Dockerfile 示例

EXPOSE 只做「声明」,告诉读镜像的人这个容器打算监听哪个端口,并不会自动做端口映射,真正映射要靠 docker run -p。

# 声明服务监听 3000 端口
EXPOSE 3000

把前面几条拼起来,就是一个能直接构建的 Node 服务镜像:

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

构建并运行:docker build -t mynode . 然后 docker run -p 3000:3000 mynode。常用指令速查可以翻 Docker 速查手册。

4.1 三个最容易踩的坑

现象 原因 修复
构建报 no such file or directory COPY 的源路径不在构建上下文 在镜像目录外执行 build,或调整 .dockerignore
镜像体积过大 把 node_modules 全打进去且未清理 用多阶段构建,只复制产物层
端口外部访问不通 只写了 EXPOSE 没加 -p 映射 运行时加 -p 宿主机:容器 参数

五个常用指令对照

动手验证清单

照着下面做一遍,确认你真的能独立产出并运行镜像,而不是只看不练(示例基于 Docker 26,未在本机执行,请按实际版本核对输出):

  1. 前置安装:先确认 Docker 已安装并能启动守护进程,执行 docker version 能看到客户端与服务端版本号;版本不一致时构建缓存的命中规则可能不同,这是常被人忽略的边界,先把环境对齐再动手。
  2. 运行构建:在放好 Dockerfile 的目录执行 docker build -t mynode .,预期看到每一步 SUCCESS 并最终生成镜像 id;顺手用 docker images 确认镜像体积,性能上把变动少的指令(FROM、依赖安装)放前面,能显著缩短二次构建时间。
  3. 配置与启动:用 docker run -p 3000:3000 mynode 把服务跑起来,检查容器状态为 Up,再用浏览器或 curl 访问 3000 端口应返回页面内容;若返回空页面或报错,先 docker logs mynode 看启动日志定位。
  4. 验证镜像分层:用 docker history mynode 查看每一层的来源与大小,对比 COPY 与 RUN 各自产生的层,理解「变动少在前」的缓存命中边界——改了代码层不会让依赖层重装,这是控制体积的关键。
  5. 失败处理与排错:若构建报 no such file or directory,多半是 COPY 的源不在构建上下文,检查 .dockerignore 或执行目录;若端口外部访问不通,确认加了 -p 映射而非只写 EXPOSE;若镜像体积过大,改用多阶段构建只复制产物层。适用场景上,本地联调可用 bind mount 挂代码热更新,交付生产则用纯镜像,两者不要混用,否则本地能跑线上却缺文件,是新手部署翻车的高发区。

总结

掌握 Dockerfile 常用指令,关键是理解每条指令发生在构建还是运行阶段。FROM 打地基、RUN 装环境、COPY 放代码、CMD 定入口、EXPOSE 只声明端口。把它们按「变动机率低在前」的顺序排,既能用上构建缓存,也更容易排查问题。

要点带走:

  • FROM 必须第一行,选带版本的小镜像更稳更安全;
  • RUN 合并同类安装,减少层数控制体积;
  • CMD 可被运行参数覆盖,适合放默认启动行为。

下一步可以把这个示例改成你自己的项目镜像,再学多阶段构建进一步瘦身。

延伸学习

这块知识系统补齐,按这个顺序来:

  1. 想边学边练,Docker 配套课程 是图文微课形式;
  2. 写好镜像后常要部署,Spring Boot 部署 Docker 给了真实项目示例;
  3. 服务器上调试容器可参考 SSH 连接 Docker。

常见问题

Q:RUN 和 CMD 到底有什么区别?

A:RUN 在镜像构建阶段执行,结果固化进镜像层;CMD 在容器运行时才执行,且能被 docker run 后的命令覆盖。一个负责「造镜像」,一个负责「跑容器」。

Q:EXPOSE 写了为什么还是访问不了?

A:EXPOSE 只是声明,不会自动做端口映射。必须在 docker run 时加 -p 宿主机端口:容器端口 才能从外部访问。

Q:一个 Dockerfile 能写多个 CMD 吗?

A:只能有一个生效,后面的会覆盖前面的。需要多命令请用 shell 脚本包裹,或用 ENTRYPOINT 配合 CMD 传参。

0 人点赞