Dockerfile
字数: 0 字 时长: 0 分钟
1. 自定义镜像概述
Docker Hub 中已经提供了大量常用软件的官方镜像,例如 Nginx、MySQL、Redis 等,这些镜像可以直接拉取并使用。
但对于我们自己开发的项目,通常没有现成的镜像可以直接使用,因此需要根据项目的运行环境、依赖、配置和启动方式,构建属于自己的 Docker 镜像。
简单来说:
官方镜像解决“别人已经做好的软件怎么运行”,自定义镜像解决“我自己写的项目怎么运行”。
自定义镜像的过程,本质上就是把应用程序以及运行所需的环境、依赖、配置等内容按照一定规则组合起来,最终构建成一个可以被 Docker 运行的镜像。
而描述这些构建规则的文件,就是 Dockerfile。
2. 镜像结构
Docker 镜像采用 分层结构(Layer)。
一个完整的镜像通常以基础镜像(Base Image)为起点,在其上逐步添加运行环境、依赖、应用程序和配置等内容,最终形成可以创建容器的镜像。

一个应用镜像的构建过程可以简单理解为:
基础镜像
↓
安装运行环境和依赖
↓
复制应用程序
↓
添加配置
↓
设置启动命令
↓
最终镜像其中常见的几个概念如下:
| 概念 | 作用 | 人话理解 |
|---|---|---|
Base Image | 作为镜像构建的基础,提供基础文件系统和运行环境 | 镜像的“地基”,例如 Ubuntu、Alpine、JDK 镜像 |
Layer | 镜像构建过程中形成的只读分层 | 在基础镜像上,一层一层加入程序、依赖和配置 |
ENTRYPOINT | 设置容器启动时默认执行的程序或命令 | 告诉 Docker:容器启动后要运行什么 |
镜像中的多个 Layer 会按照顺序叠加,最终共同组成一个完整的文件系统。
例如:
应用程序与配置 Layer 3
↑
安装依赖 Layer 2
↑
运行环境 Layer 1
↑
Base Image每一层只记录相对于上一层发生的变化,并且镜像层本身是只读的。
简单来说,构建镜像就是以一个基础镜像为起点,把应用运行所需要的环境、依赖、程序和配置逐步添加进去。
3. Dockerfile 基础
Dockerfile 是一个普通的文本文件,其中通过一系列指令描述 Docker 镜像应该如何构建。
例如:
FROM eclipse-temurin:17-jre-alpine
COPY app.jar /app/app.jar
EXPOSE 8090
ENTRYPOINT ["java", "-jar", "/app/app.jar"]常用指令如下:
| 指令 | 作用 | 人话理解 |
|---|---|---|
FROM | 指定基础镜像 | 从哪个镜像开始构建 |
WORKDIR | 设置工作目录 | 后面的命令默认在哪个目录执行 |
COPY | 将文件复制到镜像中 | 把项目文件放进镜像 |
RUN | 在构建镜像时执行命令 | 安装软件、创建目录、执行脚本等 |
ENV | 设置环境变量 | 给镜像配置环境变量 |
EXPOSE | 声明应用使用的端口 | 告诉别人这个应用通常监听哪个端口 |
ENTRYPOINT | 设置容器启动时默认执行的命令 | 容器启动后真正运行什么 |
其中最重要的是:
FROMDockerfile 通常需要从某个基础镜像开始构建。
例如:
FROM ubuntu表示基于 Ubuntu 构建。
也可以直接使用已经包含 Java 运行环境的基础镜像:
FROM eclipse-temurin:17-jre-alpine这样就不需要自己在镜像中安装 JDK。
4. 构建 Java 项目
4.1 基于 Ubuntu 手动构建 Java 项目
下面通过一个教学案例,了解如何从操作系统基础镜像开始,逐步构建 Java 应用镜像。
准备目录:
docker-demo/
├── Dockerfile
├── docker-demo.jar
└── jdk8.tar.gz
准备 JDK:

创建 Dockerfile:

Dockerfile 内容:
# 指定基础镜像
FROM ubuntu:16.04
# JDK 安装目录
ENV JAVA_DIR=/usr/local
# 复制 JDK 和 Java 项目
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 安装 JDK
RUN cd $JAVA_DIR \
&& tar -xf ./jdk8.tar.gz \
&& mv ./jdk1.8.0_144 ./java8
# 配置 Java 环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 声明应用端口
EXPOSE 8090
# 容器启动命令
ENTRYPOINT ["java", "-jar", "/tmp/app.jar"]这个 Dockerfile 的构建过程可以理解为:
Ubuntu 基础镜像
↓
复制 JDK
↓
安装 JDK
↓
复制 Java JAR
↓
配置 Java 环境
↓
设置启动命令
↓
Java 应用镜像这种方式主要用于理解 Dockerfile 的构建过程。实际项目中通常不会自己从 Ubuntu 开始安装 JDK,而是直接使用已经准备好 Java 运行环境的基础镜像。
4.2 基于 Java 基础镜像构建
如果基础镜像已经包含 Java 运行环境,那么 Dockerfile 可以简单很多。
目录结构:
docker-demo/
├── Dockerfile
└── app.jarDockerfile:
FROM eclipse-temurin:17-jre-alpine
COPY ./app.jar /app/app.jar
EXPOSE 8090
ENTRYPOINT ["java", "-jar", "/app/app.jar"]整个过程就是:
Java 基础镜像
↓
复制 app.jar
↓
设置启动命令
↓
Java 应用镜像相比从 Ubuntu 手动安装 JDK,这种方式更加简单,也更适合实际项目。
5. 构建和运行镜像
准备好 Dockerfile 和项目文件后,进入 Dockerfile 所在目录。
例如:
docker-demo/
├── Dockerfile
└── app.jar5.1 构建镜像
执行:
docker build -t javaweb:1.0 .
命令格式:
docker build -t javaweb:1.0 .
│ │ │
│ │ └── Build Context:当前目录
│ │
│ └── 镜像版本 Tag
│
└── 镜像名称其中:
| 参数 | 作用 |
|---|---|
docker build | 根据 Dockerfile 构建镜像 |
-t | 设置镜像名称和 Tag |
javaweb:1.0 | 镜像名称和版本 |
. | 指定当前目录作为构建上下文 |
这里最后的:
.非常重要,它表示:
Docker 构建时可以使用当前目录中的 Dockerfile、JAR 包以及其他相关文件。
构建完成后,可以查看镜像:
docker images5.2 运行容器
使用刚刚构建的镜像创建容器:
docker run \
--name web \
-p 8090:8090 \
-d \
javaweb:1.0
其中:
javaweb:1.0就是刚刚通过 Dockerfile 构建出来的自定义镜像。
整个过程可以理解为:
Dockerfile
↓
docker build
↓
javaweb:1.0 镜像
↓
docker run
↓
web 容器
↓
Java 应用运行6. 小结
Dockerfile 是描述 Docker 镜像构建过程的文本文件,通过不同指令告诉 Docker:
使用什么基础镜像
↓
复制哪些文件
↓
安装哪些依赖
↓
配置什么环境
↓
容器启动后运行什么常用指令:
FROM 指定基础镜像
WORKDIR 设置工作目录
COPY 复制文件
RUN 构建时执行命令
ENV 设置环境变量
EXPOSE 声明端口
ENTRYPOINT 设置容器启动命令构建镜像:
docker build -t javaweb:1.0 .运行容器:
docker run --name web -p 8090:8090 -d javaweb:1.0可以简单记住:
Dockerfile 描述镜像怎么造,
docker build负责把镜像造出来,docker run再根据镜像启动容器。