Dockerfile 是一个文本文件,包含了一组用于构建 Docker 镜像的指令。通过定义基础镜像、添加文件、运行命令等步骤,Dockerfile 允许开发者描述应用的环境和依赖关系。这个文件被 Docker 引擎解释,自动构建出可执行的容器镜像。Dockerfile 的使用简化了应用的打包和分发过程,为容器化应用的部署提供了标准和可重复的方法。
Dockerfile 是自定义镜像的一套标准化规则
Dockerfile 由多条指令构成,文件中的每一条指令都会对应 Docker 镜像中的每一层

Dockerfile 中的每个指令都会创建一个新的镜像层(执行时会生成临时容器,执行完成后自动销毁)
镜像层会被缓存和复用,后续层基于前序层构建,可大幅提升构建效率
当 Dockerfile 指令被修改、复制的文件发生变化,或构建时指定的变量不同,对应层的缓存会自动失效
某一层镜像缓存失效后,其后续所有层的缓存都会同步失效
容器的修改不会影响原始镜像;若在某一层添加文件,下一层删除该文件,镜像中仍会保留该文件
下面以 Nginx 镜像为例,加深对镜像分层的理解:

文件名必须为 Dockerfile(严格区分大小写,推荐大写)
Dockerfile 中引用的所有文件,必须与 Dockerfile 位于同一级父目录下
Dockerfile 中的相对路径,默认以文件所在目录为根目录
能合并为一行的指令尽量合并,减少镜像层数,提升构建和运行效率
指令大小写不敏感,约定俗成使用大写,提升可读性
非注释行的第一行必须是 FROM 指令
工作目录支持 .dockerignore 隐藏文件,作用与 Git 的 .gitignore 一致,过滤无需上传的文件
本章节以 JDK 17 Java 应用为例,完成从 Dockerfile 编写、镜像构建、上传私有仓库到跨服务器部署的全流程。
创建工作目录
mkdir -p /usr/local/docker/myprofile使用 Maven 打包基于 JDK 17 开发的项目,将生成的 Jar 包上传至上述目录
mvn clean package -Pprod采用 OpenJDK 17 官方轻量镜像,适配现代 Java 版本,优化镜像体积与启动性能:
# Version 1.0.0
# 基础镜像:JDK 17 LTS 轻量运行时(当前主流生产版本)
# 第一次构建时会拉取该镜像
# eclipse-temurin:17-jre-alpine
# eclipse-temurin:21-jre-alpine
# eclipse-temurin:25-jre-alpine
FROM eclipse-temurin:17-jre-alpine
# 镜像元数据(替代废弃的 MAINTAINER 指令)
LABEL author="my@gmail.com"
LABEL version="1.0.0"
LABEL description="JDK 17 Java 应用镜像"
# 设置环境变量
ENV WORKPATH /usr/local/java
ENV TZ Asia/Shanghai
# 合并执行命令:设置时区 + 创建工作目录(减少镜像层,提升构建速度)
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
&& mkdir -p $WORKPATH
# 声明数据卷挂载点
VOLUME $WORKPATH
# 复制项目 Jar 包到镜像工作目录
COPY myprofile-0.0.1-SNAPSHOT.jar $WORKPATH/app.jar
# 声明服务暴露端口
EXPOSE 8080
# 设置工作目录
WORKDIR $WORKPATH
# JDK 17 适配启动命令(兼容随机数参数,无废弃配置)
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]构建镜像时直接打上 Harbor 私有仓库标签,方便后续上传:
# 构建 JDK 17 版本镜像
docker build -t 192.168.203.128/library/myprofile:latest .
# 查看构建完成的镜像
docker images输出示例:
192.168.203.128/library/myprofile latest c5b1cfb14d75 3 seconds ago 321MB登录 Harbor 并上传镜像:
# 非交互方式登录私有仓库
cat /usr/local/docker/pwd/harbor | docker login http://192.168.203.128 --username admin --password-stdin
# 上传镜像到 Harbor
docker push 192.168.203.128/library/myprofile:latest在目标服务器拉取镜像并运行,首次使用需配置 Docker 信任 HTTP 私有仓库:
配置 Docker 守护进程
vi /etc/docker/daemon.json{
"insecure-registries": ["192.168.203.128"]
}重载配置并重启 Docker
systemctl daemon-reload
systemctl restart docker编写 docker-compose.yml 部署文件
services:
myprofile:
image: 192.168.203.128/library/myprofile:latest
restart: always
container_name: myprofile
ports:
- 8080:8080
environment:
DEVOPS_MYSQL_HOST: 192.168.203.128
DEVOPS_MYSQL_PORT: 3306
DEVOPS_MYSQL_DATABASE_NAME: crmeb
DEVOPS_MYSQL_USERNAME: root
DEVOPS_MYSQL_PASSWORD: 123456启动容器并查看日志
# 启动服务
docker-compose up -d
# 实时查看服务日志
docker logs -f myprofiledocker build 命令基于 Dockerfile 和构建上下文构建镜像
构建上下文:指定路径或 Git 地址中的所有文件集合
构建过程可通过 COPY 指令引用上下文中的任意文件
构建上下文支持递归处理,会包含指定目录的所有子目录、Git 仓库的所有子模块。
使用当前目录作为上下文(最常用):
docker build .执行命令时,Docker 会将本地目录的所有文件发送到 Docker 守护进程,控制台会提示 Sending build context。
不要使用根目录 / 作为构建上下文,会将整个硬盘内容发送到守护进程
推荐使用空目录作为上下文,仅存放 Dockerfile 和必要的构建文件
构建由 Docker 守护进程执行,而非本地 CLI 工具
守护进程会逐行执行 Dockerfile 指令,每条指令生成一个新镜像层
Docker 会自动使用构建缓存加速构建,控制台出现 CACHED 即代表命中缓存
每条指令独立运行,RUN cd /tmp 不会对下一条指令产生影响
指定 Dockerfile 路径,不指定则默认读取上下文目录下的 Dockerfile
docker build -f /path/to/Dockerfile .指定镜像名称和版本标签,支持同时打多个标签
# 单标签
docker build -t myapp:v1.0.0 .
# 多标签
docker build -t myapp:1.0.2 -t myapp:latest .自定义容器 hosts 映射,支持配置多个
docker build --add-host=docker:10.180.0.1 .构建时禁用缓存,强制重新构建所有层
docker build --no-cache -t myapp:latest .指定构建过程中 RUN 指令使用的网络模式
docker build --network host -t myapp:latest .