网站公告

本次更新:没啥更新的

“钱塘江上潮信起,今日方知我是我”

Skip to content

Dockerfile ​

字数: 0 字 时长: 0 分钟

1. 自定义镜像概述 ​

Docker Hub 中已经提供了大量常用软件的官方镜像,例如 Nginx、MySQL、Redis 等,这些镜像可以直接拉取并使用。

但对于我们自己开发的项目,通常没有现成的镜像可以直接使用,因此需要根据项目的运行环境、依赖、配置和启动方式,构建属于自己的 Docker 镜像。

简单来说:

官方镜像解决“别人已经做好的软件怎么运行”,自定义镜像解决“我自己写的项目怎么运行”。

自定义镜像的过程,本质上就是把应用程序以及运行所需的环境、依赖、配置等内容按照一定规则组合起来,最终构建成一个可以被 Docker 运行的镜像。

而描述这些构建规则的文件,就是 Dockerfile。


2. 镜像结构 ​

Docker 镜像采用 分层结构(Layer)。

一个完整的镜像通常以基础镜像(Base Image)为起点,在其上逐步添加运行环境、依赖、应用程序和配置等内容,最终形成可以创建容器的镜像。

Docker 镜像分层结构

一个应用镜像的构建过程可以简单理解为:

text
基础镜像
   ↓
安装运行环境和依赖
   ↓
复制应用程序
   ↓
添加配置
   ↓
设置启动命令
   ↓
最终镜像

其中常见的几个概念如下:

概念作用人话理解
Base Image作为镜像构建的基础,提供基础文件系统和运行环境镜像的“地基”,例如 Ubuntu、Alpine、JDK 镜像
Layer镜像构建过程中形成的只读分层在基础镜像上,一层一层加入程序、依赖和配置
ENTRYPOINT设置容器启动时默认执行的程序或命令告诉 Docker:容器启动后要运行什么

镜像中的多个 Layer 会按照顺序叠加,最终共同组成一个完整的文件系统。

例如:

text
应用程序与配置        Layer 3
       ↑
安装依赖              Layer 2
       ↑
运行环境              Layer 1
       ↑
Base Image

每一层只记录相对于上一层发生的变化,并且镜像层本身是只读的。

简单来说,构建镜像就是以一个基础镜像为起点,把应用运行所需要的环境、依赖、程序和配置逐步添加进去。


3. Dockerfile 基础 ​

Dockerfile 是一个普通的文本文件,其中通过一系列指令描述 Docker 镜像应该如何构建。

例如:

dockerfile
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设置容器启动时默认执行的命令容器启动后真正运行什么

其中最重要的是:

dockerfile
FROM

Dockerfile 通常需要从某个基础镜像开始构建。

例如:

dockerfile
FROM ubuntu

表示基于 Ubuntu 构建。

也可以直接使用已经包含 Java 运行环境的基础镜像:

dockerfile
FROM eclipse-temurin:17-jre-alpine

这样就不需要自己在镜像中安装 JDK。


4. 构建 Java 项目 ​

4.1 基于 Ubuntu 手动构建 Java 项目 ​

下面通过一个教学案例,了解如何从操作系统基础镜像开始,逐步构建 Java 应用镜像。

准备目录:

text
docker-demo/
├── Dockerfile
├── docker-demo.jar
└── jdk8.tar.gz

Docker Demo 目录

准备 JDK:

准备 JDK

创建 Dockerfile:

创建 Dockerfile

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 的构建过程可以理解为:

text
Ubuntu 基础镜像
      ↓
复制 JDK
      ↓
安装 JDK
      ↓
复制 Java JAR
      ↓
配置 Java 环境
      ↓
设置启动命令
      ↓
Java 应用镜像

这种方式主要用于理解 Dockerfile 的构建过程。实际项目中通常不会自己从 Ubuntu 开始安装 JDK,而是直接使用已经准备好 Java 运行环境的基础镜像。


4.2 基于 Java 基础镜像构建 ​

如果基础镜像已经包含 Java 运行环境,那么 Dockerfile 可以简单很多。

目录结构:

text
docker-demo/
├── Dockerfile
└── app.jar

Dockerfile:

dockerfile
FROM eclipse-temurin:17-jre-alpine

COPY ./app.jar /app/app.jar

EXPOSE 8090

ENTRYPOINT ["java", "-jar", "/app/app.jar"]

整个过程就是:

text
Java 基础镜像
      ↓
复制 app.jar
      ↓
设置启动命令
      ↓
Java 应用镜像

相比从 Ubuntu 手动安装 JDK,这种方式更加简单,也更适合实际项目。


5. 构建和运行镜像 ​

准备好 Dockerfile 和项目文件后,进入 Dockerfile 所在目录。

例如:

text
docker-demo/
├── Dockerfile
└── app.jar

5.1 构建镜像 ​

执行:

bash
docker build -t javaweb:1.0 .

构建 Java 镜像

命令格式:

text
docker build -t javaweb:1.0 .
             │       │     │
             │       │     └── Build Context:当前目录
             │       │
             │       └── 镜像版本 Tag
             │
             └── 镜像名称

其中:

参数作用
docker build根据 Dockerfile 构建镜像
-t设置镜像名称和 Tag
javaweb:1.0镜像名称和版本
.指定当前目录作为构建上下文

这里最后的:

text
.

非常重要,它表示:

Docker 构建时可以使用当前目录中的 Dockerfile、JAR 包以及其他相关文件。

构建完成后,可以查看镜像:

bash
docker images

5.2 运行容器 ​

使用刚刚构建的镜像创建容器:

bash
docker run \
    --name web \
    -p 8090:8090 \
    -d \
    javaweb:1.0

运行 Java 容器

其中:

text
javaweb:1.0

就是刚刚通过 Dockerfile 构建出来的自定义镜像。

整个过程可以理解为:

text
Dockerfile
    ↓
docker build
    ↓
javaweb:1.0 镜像
    ↓
docker run
    ↓
web 容器
    ↓
Java 应用运行

6. 小结 ​

Dockerfile 是描述 Docker 镜像构建过程的文本文件,通过不同指令告诉 Docker:

text
使用什么基础镜像
        ↓
复制哪些文件
        ↓
安装哪些依赖
        ↓
配置什么环境
        ↓
容器启动后运行什么

常用指令:

text
FROM         指定基础镜像
WORKDIR      设置工作目录
COPY         复制文件
RUN          构建时执行命令
ENV          设置环境变量
EXPOSE       声明端口
ENTRYPOINT   设置容器启动命令

构建镜像:

bash
docker build -t javaweb:1.0 .

运行容器:

bash
docker run --name web -p 8090:8090 -d javaweb:1.0

可以简单记住:

Dockerfile 描述镜像怎么造,docker build 负责把镜像造出来,docker run 再根据镜像启动容器。

Noctiflorous Garden · MIT License