Ezio's Blog
Posts Categories Tags Music Mood About
Ezio's Blog· Light
☰ Menu
Posts Categories Tags Music Mood About
Expand all Back to top Go to bottom

Dockerfile

Author: Ezio Date: May 9, 2026  15:22:32 Category: Docker

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 —— 设置工作目录

1
WORKDIR /app
  • 相当于 cd /app,后续命令都在这个目录下执行。
  • 目录不存在会自动创建。
  • 建议一开始就设,避免到处写绝对路径。

COPY —— 把本地文件拷进镜像

1
2
COPY app.jar /app/app.jar
COPY . /app
  • 格式:COPY 源路径 目标路径
  • COPY . /app 表示把当前目录所有文件拷进 /app。
  • 配合 .dockerignore 排除不需要的文件。

ADD —— 和 COPY 类似,但不推荐

1
ADD app.tar.gz /app/
  • 会自动解压 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 —— 声明端口(只是声明)

1
EXPOSE 8080
  • 只是告诉别人「这个容器想用 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
# 阶段一:构建(大,带 Maven)
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

# 阶段二:运行(小,只有 JRE)
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/

作用:构建时忽略这些文件,加快速度、防止密钥泄露。

Author: Ezio

Permalink: https://ezioy.cn/2026/05/09/Dockerfile/

License: Copyright (c) 2019 CC-BY-NC-4.0 LICENSE

Slogan: Nothing is true,Everything is permitted

Tag(s): # Docker
back · home
Docker Compose Vibe Coding项目开发流程
Ezio © 2019 - 2026 | Powered by Hexo & Chic | 访客数量:   浏览次数: | 渝公网安备50011302222043 | 渝ICP备2023013933号-1