Docker build创建镜像命令入门教程
一、核心概念
-
Dockerfile
定义镜像构建步骤的文本文件,包含一系列指令和配置,用于自动化创建镜像。 -
镜像层(Layer)
Docker 镜像由多层只读层叠加而成,每个指令(如RUN
、COPY
)会生成一个新的层。层可缓存,加速重复构建。 -
构建上下文(Build Context)
发送给 Docker 守护进程的文件集合,用于构建镜像。默认是 Dockerfile 所在目录。
二、Dockerfile 基础指令
1. FROM
- 用途:指定基础镜像,所有 Dockerfile 必须以
FROM
开头。 - 示例:
FROM nginx:latest # 基于官方 Nginx 镜像
2. RUN
- 用途:执行 shell 命令,生成新的镜像层。
- 示例:
RUN apt-get update && apt-get install -y curl # 安装依赖
3. COPY
- 用途:将本地文件或目录复制到镜像中。
- 示例:
COPY ./src /app/src # 复制宿主机的 src 目录到镜像的 /app/src
4. ADD
- 用途:类似
COPY
,但支持自动解压压缩文件(如.tar.gz
)和远程 URL。 - 示例:
ADD https://example.com/file.tar.gz /app/ # 下载并解压文件
5. WORKDIR
- 用途:设置工作目录,后续指令(如
RUN
、COPY
)将在此目录执行。 - 示例:
WORKDIR /app # 切换到 /app 目录
6. CMD
- 用途:定义容器启动时默认执行的命令(可被覆盖)。
- 示例:
CMD ["node", "server.js"] # 启动 Node.js 服务
7. ENTRYPOINT
- 用途:定义容器启动时执行的命令(不可被覆盖,但可通过
--entrypoint
修改)。 - 示例:
ENTRYPOINT ["python", "app.py"] # 固定执行 Python 脚本
8. EXPOSE
- 用途:声明容器监听的端口(仅文档作用,实际需通过
-p
映射)。 - 示例:
EXPOSE 8080 # 声明应用使用 8080 端口
9. ENV
- 用途:设置环境变量。
- 示例:
ENV API_URL=https://api.example.com # 定义 API 地址
三、docker build
命令详解
基本语法:
docker build [OPTIONS] PATH | URL | -
常用选项:
-t, --tag
:指定镜像名称和标签(格式:name:tag
)。-f, --file
:指定 Dockerfile 路径(默认为PATH/Dockerfile
)。--no-cache
:禁用缓存,强制重新执行所有步骤。--build-arg
:传递构建参数(需在 Dockerfile 中用ARG
定义)。
示例:
- 构建并标记镜像:
docker build -t my_app:v1 . # 当前目录为构建上下文
- 指定 Dockerfile 路径:
docker build -t my_app:v1 -f Dockerfile.prod .
- 传递构建参数:
docker build --build-arg ENV=prod -t my_app:prod .
四、构建流程示例
目标:构建一个 Node.js 应用镜像。
步骤 1:创建项目结构
mkdir -p node-app/{src,public}
touch node-app/server.js node-app/package.json
步骤 2:编写 Dockerfile
# 使用官方 Node.js 18 镜像作为基础
FROM node:18-alpine# 设置工作目录
WORKDIR /app# 复制 package.json 和 package-lock.json
COPY package*.json ./# 安装依赖
RUN npm install# 复制应用源码
COPY . .# 暴露端口 3000
EXPOSE 3000# 启动应用
CMD ["node", "server.js"]
步骤 3:构建镜像
docker build -t node-app:latest .
步骤 4:运行容器
docker run -p 3000:3000 node-app:latest
五、最佳实践
-
减少镜像层数
合并相关指令(如RUN apt-get update && apt-get install -y ...
),避免生成过多无用层。 -
使用
.dockerignore
排除构建上下文中的无关文件(如node_modules
、.git
),减少传输大小。.git node_modules *.log
-
多阶段构建(Multi-Stage Builds)
分离构建环境和运行环境,减小最终镜像体积。# 阶段 1:构建应用 FROM node:18 AS builder WORKDIR /app COPY . . RUN npm install && npm run build# 阶段 2:运行应用 FROM node:18-alpine WORKDIR /app COPY --from=builder /app/dist ./dist CMD ["node", "dist/server.js"]
-
使用轻量级基础镜像
优先选择 Alpine Linux 或distroless
镜像,减少镜像体积和安全风险。FROM node:18-alpine # 体积约 100MB,远小于默认的 Ubuntu 镜像
-
避免以 root 用户运行
创建非 root 用户,提升容器安全性。RUN adduser -D app_user USER app_user
六、调试与优化
-
查看构建日志
docker build --progress=plain -t my_app:debug . # 显示详细日志
-
跳过缓存
docker build --no-cache -t my_app:nocache .
-
分析镜像层
docker history my_app:latest # 查看各层大小和命令
-
扫描镜像漏洞
使用docker scan
或第三方工具(如 Trivy)检查安全风险。docker scan my_app:latest
七、常见问题
-
构建失败:文件未找到
- 原因:
COPY
或ADD
指令路径错误。 - 解决:检查文件是否在构建上下文中,使用绝对路径或正确相对路径。
- 原因:
-
权限拒绝(Permission Denied)
- 原因:容器内进程以非 root 用户运行,但文件权限不足。
- 解决:在 Dockerfile 中使用
RUN chown
修改文件所有者。
-
缓存未生效
- 原因:构建上下文文件变更导致缓存失效。
- 解决:尽量保持静态文件(如依赖包)不变,或合理拆分指令。
-
端口无法访问
- 原因:未通过
-p
映射端口。 - 解决:运行容器时添加
-p 主机端口:容器端口
,如docker run -p 8080:80 nginx
。
- 原因:未通过
八、总结
- Dockerfile 是镜像构建的核心,需合理设计指令顺序和层结构。
docker build
命令通过参数控制镜像名称、上下文和缓存策略。- 遵循最佳实践(如多阶段构建、轻量级镜像)可显著优化构建效率和安全性。