docker部署可执行jar包

博客介绍了如何通过创建bash文件和挂载宿主机目录来优化Docker中Java应用的部署。这种方法使得在jar包更新时,只需替换宿主机的jar包,无须重建镜像,简化了维护流程。详细步骤包括创建bash文件、构建Docker镜像、运行容器,并提供了删除无用容器和镜像的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们构建的是运行bash文件命令的镜像,而不是构建jar包的镜像。好处就是,jar包有更新,只需替换jar包或者bash文件,而无须重新构建镜像。

通常,用docker承载运行java程序,是将jar包先构建镜像,然后创建docker容器运行。如果jar包更新,就需要删除原镜像,重新来一遍,耗时耗力。有一个方案是,我们创建一个bash文件(linux的批处理文件),其内容是运行我们的jar包。然后创建运行该bash文件的docker镜像、docker容器。这样的好处是很明显的,jar包有更新,只替换jar包,甚至jar包改名了,也只是更改bash文件的内容而已,而镜像、容器,不会受到任何影响,无需作出任何改动。

一、思路

1、将docker容器中的指定文件夹挂载到宿主机上,更新jar包只需上传到宿主机指定路径,方便更新

2、利用bash文件运行jar包,并构建该bash的镜像,代替构建直接运行jar包的镜像,利于镜像与jar包解耦。
例如,app-1.0.0.jar 升级到 app-2.0.0.jar,只须更改bash文件的内容,而无须构建新的镜像。

二、准备工作

1、创建存放docker配置文件、jar包的文件夹
在宿主机上,创建文件夹:/home/admin/app,用于存放bash文件和jar包。然后在该文件夹下,创建bash文件和容器配置文件

2、创建bash文件

vi run.sh
java -jar /usr/data/app-1.0.0.jar

/usr/data是docker容器内的路径。
这是docker自己管理的,我们不需要真的到docker容器内创建这个路径。
后面会将此路径挂载到当前文件夹:/home/admin/app

3、创建容器配置文件

vi Dockerfile
FROM openjdk:8-jdk-alpine
EXPOSE 8081
ENTRYPOINT ["sh","/usr/data/run.sh"]

8081是我们这个jar包的对外端口
最后一句,有网上教程写的是 CMD [“sh”,“-c”,“/usr/data/hello.sh”],但不知道为什么,我这样写的话,容器运行后会提示没有权限!

二、构建镜像

仍然在/home/admin/app下,构建镜像。注意最后一个“.”,表示 Dockerfile 文件在当前目录下。

docker build -t myapp:1.0.0 .

-t, --tag list 以 ‘name:tag’ 的格式给镜像命名。

参数-t用于指定新构建的镜像的名称及标签。具体来说,-t参数后面可以跟一个“镜像名:标签”的格式,其中“镜像名”是你给镜像起的名字,而“标签”是你为该镜像指定的版本号或其他标识符。

默认情况下,当你使用docker build命令创建一个镜像并指定了相同的镜像名和标签时,它会覆盖已存在的同名镜像。

三、创建容器并运行

docker run -d -it --name=myapp -p 8081:8081 -v /home/admin/app:/usr/data myapp:1.0.0

如果需要docker引擎重启后自动运行(也可以理解为操作系统重启后自动运行,如果docker是开机自动运行的话),那么可以这样写:

docker run --restart=always -d -it --name=myapp -p 8082:8081 -v /home/admin/app:/usr/data myapp:1.0.0

-v,将容器内的/usr/data挂载到宿主机的/home/admin/app。以后jar包有更新,丢到宿主机的/home/admin/app,然后重启容器即可。

-d: 后台运行容器,并返回容器ID;
-d, --detach=false Run container in background and print container ID

-i: 以交互模式运行容器,通常与 -t 同时使用;
-i, --interactive=false Keep STDIN open even if not attached

-t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-t, --tty=false Allocate a pseudo-TTY

四、删除多余或失败的容器、镜像

以上步骤,可能存在波折,不小心就创建了许多并不称心如意的容器和镜像,占用了心水名称和端口,必先删之而后快。

1、观察已经有哪些容器
docker ps -a

加上 -a 参数,可以列出没有在运行的容器。

2、删除指定容器
docker rm $name 或者 容器ID

3、观察已经有哪些镜像
docker images

4、删除指定镜像
docker rmi -f $name 或者 镜像ID

要删除镜像,首先要删除它派生的容器。

五、docker世界中的一些术语

我现在是这么理解的:

docker是一个程序,它不是容器,而是容器引擎。

我们的程序要用docker来跑,首先要创建一个开启我们程序的镜像。

docker利用这个镜像,开启并运行容器。

容器是镜像的实例,同一个镜像可以派生出多个实例。

六、补充

如上所述,我的思路是将容器内的文件夹挂载到宿主机的文件夹上,方便以后更新维护。如果没有这层考虑,其实也可以将jar包直接塞到容器里运行,不过一旦jar包有更新,需要重新构建镜像和容器。

直接塞到容器里运行的方法是Dockerfile内容稍有点不同:

FROM openjdk:8-jdk-alpine
MAINTAINER chenqu
ADD demo-0.0.1-SNAPSHOT.jar demo.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","demo.jar"]

2024.03.28

采用这种将jar包外挂在宿主机,而不是放进镜像的做法,好处是更新的时候,无须重新构造镜像,替换掉jar包即可。

这样就引出一个疑问,那么运行的时候,jar包是运行在docker容器,还是在宿主机?

答案应该是在docker容器。虽然jar包的物理真身不在容器里,但因为经过了挂靠的映射,我猜测容器启动的时候,会将这个包读进容器,缓存起来。就好比我们跑一个程序,它不一定来自本地硬盘,也有可能来自局域网的共享文件夹,对外部来说,都一样。

### 如何使用 Docker 部署 Java JAR #### 准备工作 为了成功部署Java应用程序作为Docker容器,需先准备好待打的应用程序JAR文件。确保该文件位于主机系统的指定目录下。 #### 下载基础镜像 获取官方OpenJDK镜像是必要的前置条件之一。这可以通过执行`docker pull openjdk:11`来完成[^3]。此操作将拉取适用于大多数现代Java应用的稳定版OpenJDK 11环境至本地机器上。 #### 启动并运行容器化应用 一旦拥有目标JAR文件以及适当的基础镜像之后,则可通过如下命令启动服务: ```bash docker run -d --name my-java-app \ -v /path/to/application.jar:/app/app.jar \ -p hostPort:containerPort \ openjdk:11 sh -c 'java $JAVA_OPTS -jar /app/app.jar' ``` 上述脚本中的参数说明如下: - `-d`: 表示以后台模式运行容器; - `--name my-java-app`: 给创建的新容器命名; - `-v /path/to/application.jar:/app/app.jar`: 将宿主机上的路径映射到容器内部特定位置;这里假设外部路径为`/path/to/application.jar`, 而在容器内的对应地址则设为`/app/app.jar`; - `-p hostPort:containerPort`: 定义端口转发规则,其中左边为主机开放给外界访问的实际端口号,而右侧则是容器监听的服务端口; - `sh -c 'java $JAVA_OPTS -jar /app/app.jar'`: 执行启动命令,在此处调用了Java解释器加载并初始化Web服务器实例[^1]。 #### 创建自定义Dockerfile(可选) 对于更复杂的场景或者希望简化构建过程的情况来说,编写一个简单的Dockerfile可能是更好的选择。下面是一个基本的例子: ```Dockerfile FROM openjdk:11-jre-slim VOLUME /tmp ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar ENTRYPOINT ["java","-jar","/app.jar"] ``` 这段配置指定了基于精简版OpenJDK 11镜像建立新镜像的过程,并设置了默认入口点用于自动启动内置于image中的application jar[^2]。
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值