题目
什么是 Dockerfile?
答案
Dockerfile 是一个文本文件,包含了一系列**指令(Instructions)**,用于定义如何自动构建一个 **Docker 镜像**。镜像可以看作是一个轻量级、可执行的软件包,包含运行应用程序所需的一切(代码、运行时环境、系统工具、库等)。通过 Dockerfile,开发者可以精确描述镜像的构建步骤,确保环境一致性。 ### Dockerfile 的核心作用 1. **标准化环境**:消除“在我机器上能运行”的问题,确保开发、测试、生产环境一致。 2. **自动化构建**:通过一条命令(`docker build`)即可生成镜像,无需手动配置。 3. **分层存储**:每个指令生成一个镜像层,层复用提升构建效率和存储优化。 ### Dockerfile 的常见指令 以下是 Dockerfile 的关键指令及其用途: | **指令** | **作用** | **示例** | | :------------- | :----------------------------------------------------------- | :-------------------------------------------------------- | | `FROM` | 指定基础镜像(必须作为第一条指令)。 | `FROM ubuntu:22.04` | | `RUN` | 在镜像中执行命令(安装软件、配置环境等)。 | `RUN apt-get update && apt-get install -y nginx` | | `COPY` / `ADD` | 将文件从宿主机复制到镜像中(`ADD` 支持自动解压和远程 URL)。 | `COPY ./app /app` | | `WORKDIR` | 设置工作目录(后续指令的默认执行路径)。 | `WORKDIR /app` | | `ENV` | 设置环境变量。 | `ENV NODE_ENV=production` | | `EXPOSE` | 声明容器运行时监听的端口(需通过 `-p` 映射到宿主机)。 | `EXPOSE 80` | | `CMD` | 指定容器启动时默认执行的命令(只能有一条,可被 `docker run` 覆盖)。 | `CMD ["nginx", "-g", "daemon off;"]` | | `ENTRYPOINT` | 类似 `CMD`,但参数不可被 `docker run` 覆盖(通常与 `CMD` 结合使用)。 | `ENTRYPOINT ["java", "-jar"]` + `CMD ["app.jar"]` | | `USER` | 指定运行容器时的用户(避免使用 root 提升安全性)。 | `USER node` | | `VOLUME` | 定义数据卷挂载点(持久化数据或共享数据)。 | `VOLUME /data` | | `HEALTHCHECK` | 定义容器健康检查规则(检测服务是否正常)。 | `HEALTHCHECK --interval=30s CMD curl -f http://localhost` | ### Dockerfile 示例 以下是一个 SpringBoot 应用的 Dockerfile 示例: ```yaml # ========== 第一阶段:构建应用 ========== # 使用 Maven 官方镜像作为构建环境 FROM maven:3.8.6-openjdk-17 AS builder # 设置工作目录 WORKDIR /app # 先复制 POM 文件(利用 Docker 缓存层加速构建) COPY pom.xml . # 下载依赖(如果 pom.xml 未变化,会复用该层缓存) RUN mvn dependency:go-offline -B # 复制源代码 COPY src ./src # 构建应用(打包为 JAR) RUN mvn package -DskipTests # ========== 第二阶段:运行应用 ========== # 使用轻量级 OpenJDK 运行时镜像 FROM openjdk:17-jdk-alpine # 设置容器内工作目录 WORKDIR /app # 从构建阶段复制生成的 JAR 包 COPY --from=builder /app/target/*.jar app.jar # 设置非 root 用户(安全最佳实践) RUN addgroup -S springboot && adduser -S springboot -G springboot USER springboot # 暴露端口(与 application.properties 中配置的端口一致) EXPOSE 8080 # 健康检查(可选) HEALTHCHECK --interval=30s --timeout=3s \ CMD curl -f http://localhost:8080/actuator/health || exit 1 # 启动命令(可配置 JVM 参数) ENTRYPOINT ["java", "-jar", "app.jar"] # 如果需要指定 JVM 内存参数: # ENTRYPOINT ["java", "-Xmx512m", "-jar", "app.jar"] ``` ### Dockerfile 构建与运行 使用以下命令根据 Dockerfile 构建镜像并运行容器: ```bash # 构建镜像 docker build -t my-spring-app:1.0 . # 运行容器(映射端口 8080) docker run -d -p 8080:8080 --name my-app my-spring-app:1.0 ```