想使用 docker 创建一个可以运行 jar 包的镜像文件,然后一键运行。具体怎么做呢?
第一步,准备一个专门的文件夹
比如我在D盘,创建一个专门的文件夹:
D:\docker-data\jar
把打包好的xxx.jar放进去。
第二步,创建 Dockerfile 文件
在这个文件夹里,新建一个名为Dockerfile的文件,注意:没有扩展名!
内容如下:
# 使用官方的 Java 运行环境镜像,适用于大多数 JAR 文件
FROM openjdk:17-jdk-alpine
# 设置工作目录
WORKDIR D:/docker-data/jar
# 复制当前目录下的 jar 包到容器中
COPY register-center.jar register-center.jar
# 设置容器启动时执行的命令
ENTRYPOINT ["java", "-jar", "register-center.jar", "--spring.profiles.active=peer1"]
FROM
指定我所使用的基础镜像,这里用了体积小的 Alpine 版 Java 17。
WORKDIR
是容器里的工作目录。
COPY
把 xxx.jar 文件复制到镜像中。
ENTRYPOINT
是容器启动时运行的命令。
第三步,构建 Docker 镜像
打开命令提示符(cmd)或PowerShell,切换到jar包目录:
cd D:\docker-data\jar
然后运行以下命令构建 Docker 镜像(比如我们叫它my-java-app):
docker build -t register-center .
-t 是一个参数选项,全称是 --tag,用于给构建的镜像指定一个名称和可选的标签。
-t 的格式:
-t <镜像名>:<标签>
如果只提供 <镜像名> 而不指定 <标签>,Docker 会默认使用 latest 作为标签。
等待几秒钟报了一个错误:
换了三种镜像,依旧报错,网络这么不好吗?
直接拉 jdk 正常。
docker pull openjdk:17-jdk-alpine
再次构建镜像,等待几秒钟,Docker 会根据 Dockerfile 创建镜像。
镜像创建成功,但好像有个错误,应该不打紧,继续。
第四步,运行容器并启动Java 应用
构建成功后,可以用这个命令运行容器:
docker run --rm register-center
--rm表示运行结束后自动删除容器。
如果需要开放端口,可以加-p参数:
docker run -d -p 8761:8761 --rm register-center
-d 标识在后台运行。
第五步,同一个jar运行多次
加大难度,调整 Dockerfile 配置:
# 使用官方的 Java 运行环境镜像,适用于大多数 JAR 文件
FROM openjdk:17-jdk-alpine
# 设置工作目录
WORKDIR D:/docker-data/jar
# 复制当前目录下的 jar 包到容器中
COPY register-center.jar register-center.jar
# 设置容器启动时执行的命令
ENTRYPOINT ["java", "-jar", "register-center.jar"]
# 默认参数
CMD ["--spring.profiles.active=peer1"]
在最后增加了一个CMD,可以设置多个参数,在运行命令时进行覆盖。
ENTRYPOINT 和 CMD 都是用于定义容器启动时运行的命令。
ENTRYPOINT是定义容器启动时的主命令(容器的主要执行逻辑),不可被 docker run 直接覆盖,除非用 --entrypoint 覆盖。
CMD是定义主命令的默认参数(可被覆盖的默认行为),可以被 docker run 后的参数完全覆盖。
第一次执行命令:
docker run -d -p 8761:8761 --rm register-center
第二次执行命令,但是设置了参数:
docker run -d -p 8762:8762 --rm register-center --spring.profiles.active=peer2
在这个命令中,我们使用使用 --spring.profiles.active=peer2 覆盖了 cmd 中的默认参数。
现在就有两个容器在运行了。
第六步,运行有启动顺序的多个jar
目录结构图:
先调整Dockerfile文件:
# 使用官方的 Java 运行环境镜像,适用于大多数 JAR 文件
FROM openjdk:17-jdk-alpine
# 设置工作目录
WORKDIR D:/docker-data/jar
# 复制当前目录下的 jar 包到容器中
COPY register-center.jar .
COPY configer-server.jar .
COPY api.jar .
COPY start.sh .
# 给 start.sh 添加执行权限,确保脚本可执行
#RUN chmod +x start.sh
# Windows 换行符 CRLF
RUN sed -i 's/\r$//' start.sh && chmod +x start.sh
# 设置容器启动时执行的脚本
CMD ["./start.sh"]
运行脚本增加一个start.sh 配置:
#!/bin/sh
# 启动 JAR
java -jar register-center.jar --spring.profiles.active=peer1 &
java -jar register-center.jar --spring.profiles.active=peer2 &
# 等待 8761 或 8762 任一端口就绪(最多 60 秒)
timeout=60
while ! (nc -z localhost 8761 || nc -z localhost 8762); do
sleep 2
timeout=$((timeout - 2))
if [ $timeout -le 0 ]; then
echo"错误:app1 未在 60 秒内启动(8761 或 8762 端口未就绪)"
exit 1
fi
echo"等待 app1 启动(检测端口 8761 或 8762)..."
done
# 启动接下来的 jar
java -jar configer-server.jar &
# 等待 8800 端口就绪
while ! nc -z localhost 8800; do
echo"等待配置中心启动..."
sleep 2
done
# 启动接下来的 jar
java -jar api.jar --spring.profiles.active=peer1 &
java -jar api.jar --spring.profiles.active=peer2 &
# 防止容器退出
#tail -f /dev/null
# 等待所有后台任务
wait
& 表示后台运行,wait 会等所有后台进程结束。
由于是多个jar的启动,jar包和jar包又有依赖关系,因此,在这里设置了一个等待时间,只有当第一个和第二个jar都运行成功时,才运行第三个jar,第三个运行成功后再运行最后两个jar。
构建镜像:
docker build -t multi-jar .
运行容器:
docker run -d --name multi-jar -p 8761:8761 -p 8762:8762 -p 8800:8800 -p 8101:8101 -p8102:8102 --rm multi-jar
为了方便操作容器,启动容器的时候可以通过 --name 给容器命名。
-d 在后台运行。
--name 给将要启动的容器命名。
-p 映射容器端口可以在本机访问。
-rm 停止容器后删除容器。
通过浏览器访问:
在docker容器里查看启动详细信息:
第一个镜像就这样构建完成了,看似有点麻烦,实则一点不简单,但这一步搭建好了,后面用起来就方便多了。
希望本文对你有所帮助。
领取专属 10元无门槛券
私享最新 技术干货