目录标题
-
-
- [一、第一步:为每个服务准备 Docker 镜像](#一、第一步:为每个服务准备 Docker 镜像)
- [二、第二步:让 Docker Compose 使用你的镜像](#二、第二步:让 Docker Compose 使用你的镜像)
-
- 插播知识点(关于镜像容器)
- 查看本地是否配置私有镜像仓库
-
- [1.查看 Docker 配置文件](#1.查看 Docker 配置文件)
- [2.查看 Docker 系统信息](#2.查看 Docker 系统信息)
参考之前 blog Docker Compose最巧妙的设计之一------内置的服务发现机制 里面配置文件 docker-compose.yaml
参考之前 blog 单个服务打包 对下面 第一阶段:使用Maven镜像来构建项目 有帮助
整个过程可以分为两大步:准备镜像(如何把代码变成Docker镜像)和编排服务(如何用Compose管理这些镜像)
一、第一步:为每个服务准备 Docker 镜像
docker-compose.yaml 里定义了三个服务:kms-admin, kms-plat, 以及数据库 kms-mysql 和 kms-redis。
- 数据库 (mysql, redis):直接用 Docker Hub 上的官方镜像,docker-compose.yaml 里已经是这样做的了
- 你的 Java 服务 (kms-admin, kms-plat):需要你自己动手把代码打包成镜像
把代码变成镜像,核心是写好 Dockerfile(
Dockerfile 不是 .txt 文件,它是一个没有后缀名的特殊文件,但内容确实是纯文本,你可以用任何文本编辑器(记事本、VS Code等)来写
命名规则:
- 标准名称就叫 Dockerfile(首字母大写 D,无后缀)
- 也可以自定义名字,比如 Dockerfile-admin,但构建时需要用 -f 指定
bash
docker build -t kms/kms-admin:latest -f kms-admin/Dockerfile .
)。
以 kms-admin 服务为例来说明
项目根目录下(假设是 skms/),为 kms-admin 模块创建一个 Dockerfile
下面这个示例,详细解释每步干啥
bash
# ---- 第一阶段:使用Maven镜像来构建项目 ----
#因为你要在 Docker 里编译 Java 代码,而编译需要 JDK 和 Maven,你总不能自己从头装一遍 Linux、再装 JDK、再装 Maven 吧?那太费劲了。
#Docker Hub 上已经有人帮你做好了这个"编译环境镜像",你直接 FROM 它就拥有了完整的构建能力。
#嘿 Docker,给我一个现成的、安装了 Maven 3.8 和 OpenJDK 8 的 Linux 环境,我要在这个环境里干活,并且给它起个名字叫 builder
#FROM:Dockerfile 的必备指令,指定基础镜像(相当于你在 VM 上安装一个纯净的 Ubuntu 系统)
#maven:3.8-openjdk-8:这是一个官方预装好的镜像,里面包含了:Linux 操作系统(通常是 Debian 或 Alpine),JDK 8(Java 编译和运行环境),Maven 3.8(Java 构建工具)
#AS builder:给这个阶段起个名字,方便后面引用(多阶段构建的关键)
# 1. 使用包含 Maven+JDK 的镜像作为构建环境
FROM maven:3.8-openjdk-8 AS builder
# 设置工作目录
# 2. 在镜像里创建一个 /build 目录,并 cd 进去
WORKDIR /build
# 先复制pom.xml文件,利用Docker缓存机制,避免每次构建都重新下载依赖
# 3. 把本机的 pom.xml 复制到镜像的 /build 目录下
COPY pom.xml .
# 把子模块的 pom.xml 也复制进去,保持和本地一样的目录结构
COPY kms-admin/pom.xml ./kms-admin/pom.xml
COPY kms-plat/pom.xml ./kms-plat/pom.xml # 如果plat也有依赖
# 4. 下载所有依赖包 (但不编译) (go-offline 会下载构建所需的所有依赖)
RUN mvn dependency:go-offline -B
# 5. 复制所有源代码
COPY . .
# 6.编译并打包,跳过测试
RUN mvn clean package -DskipTests -pl kms-admin -am
# ---- 第二阶段:使用轻量级JRE镜像来运行 ----
# 7. 重新从一个干净的 JRE 镜像开始
FROM openjdk:8-jre-slim
# 8. 在镜像里创建 /app 目录并进入
WORKDIR /app
# 9. 从 builder 阶段复制打好的 jar 包过来
COPY --from=builder /build/kms-admin/target/kms-admin-*.jar app.jar
# 10. 复制需要的 so 库(根据你实际情况调整)
# 从构建阶段复制你可能需要的配置文件或依赖库(根据你的实际情况调整)
COPY --from=builder /build/kms-admin/lib /app/lib
# 11. 告诉 Docker 容器启动后会监听 9088 端口(配置文件里是9088)
EXPOSE 9088
# 12. 设置启动命令
ENTRYPOINT ["java", "-jar", "app.jar"]
第一阶段重点(优化解释)

第二阶段重点(优化解释)

写好 Dockerfile 后,在存放 Dockerfile 的目录下执行构建命令:
bash
docker build -t kms/kms-admin:latest -f kms-admin/Dockerfile
这个命令会读取 Dockerfile,按照指令一步步把你的代码打包成一个名为 kms/kms-admin:latest 的镜像
二、第二步:让 Docker Compose 使用你的镜像
在/usr/kms-dev 下面的 docker-compose.yaml
之前的docker-compose.yaml 已经写了下面这两点:
关联 build 上下文:告诉 Compose 去哪里找代码和 Dockerfile 来构建镜像。
关联本地挂载(开发时方便):用 volumes 把本地的配置文件动态挂载进去,这样修改配置就不用重新构建镜像了,非常方便
详细解释所有配置
yaml
kms-admin:
#容器启动后的名字 方便识别和管理:docker logs kms-admin 直接使用这个名字,其他容器可以通过这个名字访问(在自定义网络中)
container_name: kms-admin
#如果设置了 KMS_VERSION 环境变量,就用它的值,果没有设置,默认使用 latest
image: kms/kms-admin:${KMS_VERSION:-latest}
build:
#构建上下文目录,Docker 会把此目录下的所有文件发给守护进程
context: ./kms-admin
# 指定 Dockerfile 文件名(在 context 目录下)
dockerfile: dockerfile
#设置容器内的环境变量,应用可以通过 System.getenv() 读取
environment:
- TZ=Asia/Shanghai
#SPRING_PROFILES_ACTIVE=prod 会让 Spring 加载 application-prod.yml
- SPRING_PROFILES_ACTIVE=prod
#application.yml 中如果有 ${DB_PASSWORD},会被替换成这个环境变量的值
- DB_PASSWORD=${MYSQL_ROOT_PASSWORD:-123456}
# 给予容器几乎宿主机的 root 权限,相当于容器内的 root 就是宿主机的 root。
privileged: true
#使用宿主机的 PID 命名空间,容器内可以看到宿主机所有进程。1.你的应用可能需要监控其他进程 2.或者与其他服务通过 PID 通信
pid: host
#将宿主机的串口设备映射到容器内。
devices:
- /dev/ttyAMA1:/dev/ttyAMA1
# 卷挂载格式:宿主机路径:容器内路径[:权限]
volumes:
- ./cert:/dataVolume/kms/cert
- ./kms-admin/dataVolume/kms:/dataVolume/kms
- ./kms-admin/temp:/dataVolume/temp
- ./kms-admin/log:/usr/local/skms/logs
- ./kms-admin/lib/libsgd.so:/usr/lib/libsgd.so
- ./kms-admin/lib/libsgd.so:/usr/lib64/libsgd.so
- ./kms-admin/lib/libQRNG.so:/usr/lib/libQRNG.so
- ./kms-admin/lib/libQRNG.so:/usr/lib64/libQRNG.so
- ./kms-admin/lib/libbusiness.so:/usr/lib/libbusiness.so
- ./kms-admin/lib/libbusiness.so:/usr/lib64/libbusiness.so
- ./kms-admin/lib/libplatform.so:/usr/lib/libplatform.so
- ./kms-admin/lib/libplatform.so:/usr/lib64/libplatform.so
- ./kms-admin/lib/libsdf_api.conf:/etc/libsdf_api/libsdf_api.conf
- ./kms-admin/jar/application.yml:/dataVolume/kms/application.yml # 测试用于经常更新application.yml的情况
- /etc/sysconfig/network-scripts:/etc/sysconfig/network-scripts
- /usr/sbin/ifconfig:/usr/sbin/ifconfig
- /usr/bin/cd:/usr/bin/cd
- /usr/local/bin/docker-compose:/usr/bin/docker-compose
- /usr/bin/docker:/usr/bin/docker
- /var/run/docker.sock:/var/run/docker.sock
- ./:/usr/kms
- /dev:/dev
ports:
- ${ADMIN_BIND_IP:-0.0.0.0}:9088:9088
depends_on:
- kms-mysql
- kms-redis
# links:
# - kms-mysql
# - kms-redis
cap_add:
- NET_ADMIN
network_mode: host # 可选
# 容器异常退出时自动重启,宿主机重启后,Docker 启动时会自动启动此容器
restart: always
卷挂载部分(最复杂)看截图





插播知识点(关于镜像容器)
插播一个自己问的愚蠢问题:这里配置文件的的image 从哪里来的? image: kms/kms-admin:${KMS_VERSION:-latest}
有两种可能
-
从远程仓库拉取(如果存在)
Docker 会尝试从 Docker Hub 或配置的私有仓库拉取 kms/kms-admin 镜像。镜像名称格式为
-
仓库:kms/(可能是 Docker Hub 上的用户/组织名)
-
镜像名:kms-admin
-
标签:由环境变量 KMS_VERSION 决定,默认为 latest
-
-
通过 build 构建
因为你配置中同时有 build 字段,所以实际行为是:
yaml
image: kms/kms-admin:${KMS_VERSION:-latest}
build:
context: ./kms-admin
dockerfile: dockerfile
当 image 和 build 同时存在时:
- 如果本地没有该镜像,Docker Compose 会先执行 build,从 ./kms-admin 目录使用 dockerfile 构建镜像
- 构建完成后,镜像会被打上指定的 tag:kms/kms-admin:${KMS_VERSION:-latest}
- 如果后续再运行,会直接使用这个已构建的镜像,除非加了 --build 参数强制重新构建
镜像指令
bash
# 查看本地是否存在这个镜像
docker images | grep kms-admin
# 查看容器实际使用的镜像ID
docker inspect kms-admin | grep Image
# 查看镜像详细信息(包括镜像ID、大小、创建时间)
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.Size}}\t{{.CreatedAt}}"
# 查看构建历史
docker history kms/kms-admin:latest
# 镜像的存储位置(docker数据目录)
# 查看 Docker 数据根目录
docker info | grep "Docker Root Dir"
# 通常输出: Docker Root Dir: /var/lib/docker
# 查找特定镜像的存储位置
# 先获取镜像ID
IMAGE_ID=$(docker images -q kms/kms-admin:latest)
# 查找该镜像的层存储位置
find /var/lib/docker -name "*${IMAGE_ID}*" 2>/dev/null
# 镜像实际存储位置(overlay2 驱动)
ls -la /var/lib/docker/overlay2/ | grep -i $(echo $IMAGE_ID | cut -c1-12)
##输出示例
##/var/lib/docker/image/overlay2/imagedb/content/sha256/78a7772e2f79446d0a3f20a57d60856269a11664dc9ecbf0aa39bc54251f50c8
##/var/lib/docker/image/overlay2/imagedb/metadata/sha256/78a7772e2f79446d0a3f20a57d60856269a11664dc9ecbf0aa39bc54251f50c8
查看本地是否配置私有镜像仓库
1.查看 Docker 配置文件
bash
# 查看 Docker 守护进程配置(主要配置位置)
cat /etc/docker/daemon.json
# 如果存在,查看是否有 insecure-registries 或 registry-mirrors 配置
# 示例输出:
{
"insecure-registries": ["192.168.1.100:5000", "harbor.example.com"],
"registry-mirrors": ["https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"]
}
registry-mirrors 和 insecure-registries 区别(不明觉厉)

当配置了多个 registry-mirrors 时,Docker 的行为是
1.拉取顺序
- 首先尝试配置的镜像加速器(按配置顺序)
- 如果所有镜像加速器都失败,再尝试从原始仓库拉取
注意:不是简单的"按顺序一个一个试",而是:
- Docker 会并行或轮询尝试这些镜像加速器
- 实际顺序可能不是严格的配置顺序,取决于网络条件和响应速度
- 哪个镜像源响应快就用哪个
2.查看 Docker 系统信息
bash
# 查看 Docker 的仓库配置信息
docker info | grep -A 5 "Registry"
三、第三步:一键启动,见证奇迹(一些docker-compose常见指令)
所有配置就绪后,就该 Compose 登场了。在存放 docker-compose.yaml 的目录下,执行以下命令,它会自动完成构建和启动:
bash
# 如果修改了 Dockerfile 或代码,想要强制重新构建镜像
docker-compose up -d --build
# 如果只是想启动(镜像已存在)
docker-compose up -d
补充点docker-compose 指令 和其中一个指令 解析
| 命令 | 作用 |
|---|---|
| docker-compose ps | 查看当前运行状态 |
| docker-compose logs -f | 实时查看所有日志 |
| docker-compose logs xxx(服务名) | 只看某个服务的日志 |
| docker-compose down | 停止并删除所有容器 |
| docker-compose down -v | 停止并删除容器 + 删除卷(小心数据丢失!) |
命令拆解:docker-compose up -d
-
第一部分:docker-compose
这是命令行工具的名称,表示"我要用 Docker Compose 来管理容器"。
前提:
当前目录下必须有 docker-compose.yml 或 docker-compose.yaml 文件
或者用 -f 指定其他文件:docker-compose -f my-compose.yml up -d
-
第二部分:up
这是核心子命令,意思是"启动所有在 compose 文件中定义的服务"。

-
第三部分:-d
这是 --detach 的缩写,意思是"在后台运行"。

常用 docker-compose up 变体
| 命令 | 作用 | 适用场景 |
|---|---|---|
| docker-compose up | 前台启动,显示日志 | 调试、看启动错误 |
| docker-compose up -d | 后台启动 | 正式运行服务 |
| docker-compose --build | 启动前强制重新构建镜像 | 代码有修改,需要更新 |
| docker-compose up -d --build | 后台启动 + 强制构建 | 部署新版本代码 |
| docker-compose up 服务名 | 只启动某个服务 | 无 |
| docker-compose up -d 服务名 | 后台启动某个服务 | 无 |
docker-compose up 和 (先后台运行 docker-compose up -d 在看日志 docker-compose logs -f --tail=100),两者效果差不多