Dockerfile 是什么
定义:Dockerfile 是一个纯文本文件,名字就叫 Dockerfile,没有扩展名。里面一行行写指令,Docker 按顺序执行,最后产出一个镜像。
类比:它就像一份「组装说明书」,从「拿一个空盒子」开始,一步步「装 Java、拷代码、编译、设置启动命令」。
举例:
1 2 3
| FROM eclipse-temurin:17-jre COPY app.jar /app/app.jar CMD ["java", "-jar", "/app/app.jar"]
|
FROM:从哪个基础镜像开始(相当于「先拿一个装好 Java 17 的空盒子」)
COPY:把本地的 app.jar 拷进镜像的 /app/app.jar
CMD:容器启动时默认跑什么命令
常用指令
FROM —— 起点,必须第一行(除注释外)
1
| FROM eclipse-temurin:17-jre
|
- 所有镜像都基于某个基础镜像。
- 常用基础镜像:
eclipse-temurin:17-jre:Java 运行环境
maven:3.9-eclipse-temurin-17:Java + Maven 构建环境
node:20-alpine:Node 环境
nginx:1.27-alpine:Nginx
python:3.11-slim:Python
alpine / slim 是精简版,体积小,推荐。
WORKDIR —— 设置工作目录
- 相当于
cd /app,后续命令都在这个目录下执行。
- 目录不存在会自动创建。
- 建议一开始就设,避免到处写绝对路径。
COPY —— 把本地文件拷进镜像
1 2
| COPY app.jar /app/app.jar COPY . /app
|
- 格式:
COPY 源路径 目标路径
COPY . /app 表示把当前目录所有文件拷进 /app。
- 配合
.dockerignore 排除不需要的文件。
ADD —— 和 COPY 类似,但不推荐
- 会自动解压 tar 包、支持 URL。
- ADD 行为不直观,容易踩坑。
RUN —— 构建时执行命令
1 2
| RUN apt-get update && apt-get install -y curl RUN mvn clean package -DskipTests
|
- 在构建镜像时执行,结果会打进镜像。
- 多条命令用
&& 连起来写一行,减少镜像层数。
- 每多一个
RUN,镜像就多一层,层数越多镜像越大。
ENV —— 设置环境变量
1 2
| ENV TZ=Asia/Shanghai ENV JAVA_OPTS="-Xms256m -Xmx512m"
|
- 容器运行时能读到这些变量。
- Java 里
System.getenv("TZ") 能拿到。
EXPOSE —— 声明端口(只是声明)
- 只是告诉别人「这个容器想用 8080」,不会真的开放端口。
- 真正开放端口要在
docker run -p 或 compose 的 ports 里写。
- 新手常误会:写了 EXPOSE 不等于能访问。
CMD —— 容器启动时的默认命令
1
| CMD ["java", "-jar", "/app/app.jar"]
|
- 一个 Dockerfile 只能有一个 CMD,写多个只有最后一个生效。
- 用数组格式(方括号),不要用 shell 字符串格式。
- 可以被
docker run 后面跟的命令覆盖。
ENTRYPOINT —— 容器启动的固定命令
1
| ENTRYPOINT ["java", "-jar", "/app/app.jar"]
|
- 和 CMD 类似,但不容易被覆盖。
- 常见组合:ENTRYPOINT 写固定命令,CMD 写默认参数。
1 2
| ENTRYPOINT ["java", "-jar", "/app/app.jar"] CMD ["--spring.profiles.active=prod"]
|
多阶段构建
1 2 3 4 5 6 7 8 9 10 11 12 13
| FROM maven:3.9-eclipse-temurin-17 AS builder WORKDIR /build COPY pom.xml . RUN mvn dependency:go-offline -B COPY src ./src RUN mvn clean package -DskipTests -B
FROM eclipse-temurin:17-jre-alpine WORKDIR /app COPY --from=builder /build/target/*.jar app.jar CMD ["java", "-jar", "app.jar"]
|
- 最终镜像只包含第二个阶段,Maven、源码都不会进去。
- 体积从 800MB 降到 200MB。
COPY --from=builder 表示从上一个阶段拷文件。
.dockerignore
和 Dockerfile 同目录,写着不需要打进镜像的文件:
1 2 3 4 5 6
| target/ node_modules/ .git/ .env *.log .idea/
|
作用:构建时忽略这些文件,加快速度、防止密钥泄露。