docker打包jar包,构建镜像部署运行

自己有一个简单的springboot web后端项目,每次部署的时候都是上传到服务器,然后nohup java -jar 运行打包的jar包。这样每次运行都要输命令,关闭时还得找到进程id手动kill掉,觉得太烦了,干脆做成docker镜像。

编写Dockerfile

首先将需要的文件放在一个文件夹下。这里就只需要一个项目的jar包就行了,但如果想把其他用到的软件也打包进镜像,最好也要放进来。

在文件夹下创建Dockerfile文件,开始编写docker容器构建脚本。

复制代码

#依赖java8
#openjdk:8 526M
#FROM openjdk:8
#tomcat:8-jre8 240M
FROM tomcat:8-jre8
#创建者
MAINTAINER liftsail
#暴露8848
EXPOSE 8848
#不确定jar名字可以写*.jar 即为所以
ADD ddisk-1.0.0.jar /app.jar
#挂载目录
VOLUME /tmp
#容器已启动 默认运行命令 java -jar app.jar
#生产环境启动 可以写#容器已启动 默认运行命令 java -jar app.jar
#ENTRYPOINT ["java","-jar","/app.jar","--spring.profiles.active=prod"]
#解决OOM问题 指定内存初始128M 最大300M ENTRYPOINT ["java","-jar","-Xms128m","-Xmx300m","/app.jar","--spring.profiles.active=prod"]
ENTRYPOINT ["java","-jar","/app.jar"]

复制代码

FROM openjdk:15,表示本镜像的基础镜像是openjdk,版本是15,毕竟要用java命令运行jar包的。docker会从dockerhub拉取对应的镜像,服务器不需要有。

MAINTAINER liftsail,表示镜像的编写者。

ADD test.jar app.jar,表示将test.jar,也就是项目jar包,拷贝进镜像,并命名为app.jar。如果不拷贝,镜像就没jar包可运行了。

EXPOSE 8080,表示镜像将对外暴露8080端口,也就是编写项目时的运行端口。

VOLUME /file,表示将镜像的/file文件夹声明为匿名卷。这样做是因为,项目会读写文件系统的/file文件夹,如果不声明,那么项目运行后只会对镜像内的虚拟目录/file读写,而不会对主机的目录读写,等关闭容器后,写的内容就没了。所以,声明匿名卷是为了将写操作持久化。仅仅在dockerfile里声明还不够,在运行容器时还需要设置匿名卷对应的主机目录,这点我们下面会谈到。

ENTRYPOINT java -jar app.jar,表示容器运行后执行的命令。这里就只需要运行jar包就行了。

构建镜像

编写了Dockerfile,就可以构建镜像了。

docker build -t test_app:0.1 .

test_app是镜像的名字,-t代表给镜像打的标签,后面的:0.1意思就是这个镜像版本是0.1。如果不打标签,镜像的标签会自动设为latest。

最后的一个'.'代表Dockerfile所在位置,因为就在当前目录下,所以直接是一个'.'就行了。

docker会自动拉取openjdk。一会出现“Successfully built 7717b14bfe0a”,说明构建成功。

运行容器

接下来运行容器。

docker run -d --name test_app -v /home/file:/file --net=host -p 8080:8080 test_app:0.1
docker run -d -p 8848:8848 --name diskstore1 --restart=always 612d04579214

-d指在后台运行。

--name为容器起名。

-v指定容器匿名卷挂载的目录。这里/home/file:/file代表将主机的/home/file对应到容器的/file,也就是说,容器对/file目录的读写也就是对主机的/home/file读写。

--net=host指定容器的网络模式。host是最简单的模式,容器和主机共用一个网络,会互相占用端口。由于项目简单,我就没有再研究其他模式了,想研究的话可以看看官网教程。

-p 8080:8080指定端口映射。这里简单的将主机的8080端口映射到容器的8080端口。如果想要多个web程序运行在同一主机,不需要改代码里的运行端口,直接将主机的不同端口映射到容器的8080即可。

最后是容器使用的镜像,也就是刚刚构建好的test_app:0.1:也可以是容器的id。

进入容器内部   41c614982e46 为容器ID 

docker exec -it 41c614982e46  bash

 

就这样,容器成功运行了。只要docker start/stop就能控制程序运行,部署新版本时,也只要将jar包再上传到目录下,重新构建即可。

DOCKER容器常用启动参数详解

docker run [option] 镜像名 [向启动容器中传入的命令]
#例如:docker运行mysql8.0.30并设置密码为root
docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=root --restart=always --privileged=true -d mysql:8.0.30
#--restart=always 参数能够使我们在重启docker时,自动启动相关容器。
#Docker容器的重启策略如下:
#no,默认策略,在容器退出时不重启容器
#on-failure,在容器非正常退出时(退出状态非0),才会重启容器
#on-failure:3,在容器非正常退出时重启容器,最多重启3次
#always,在容器退出时总是重启容器
#unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器

#--privileged=true 使用该参数,container内的root拥有真正的root权限。
#不使用该参数,container内的root只是外部的一个普通用户权限。
#大约在0.6版,privileged被引入docker
#privileged启动的容器,可以看到很多host上的设备,并且可以执行mount。
#甚至允许你在docker容器中启动docker容器。

i 表示以“交互模式”运行容器
-t 表示容器启动后会进入其命令行。加入这两个参数后,容器创建就能登录进去。即 分配一个伪终端。
–name 为创建的容器命名
-v 表示目录映射关系(前者是宿主机目录,后者是映射到宿主机上的目录,即 宿主机目录:容器中目录),可以使 用多个-v 做多个目录或文件映射。注意:最好做目录映射,在宿主机上做修改,然后 共享到容器上。
-d 在run后面加上-d参数,则会创建一个守护式容器在后台运行(这样创建容器后不 会自动登录容器,如果只加-i -t 两个参数,创建后就会自动进去容器)。
-p 表示端口映射,前者是宿主机端口,后者是容器内的映射端口。可以使用多个-p 做多个端口映射
-e 为容器设置环境变量
–network=host 表示将主机的网络环境映射到容器中,容器的网络与主机相同

linux centos7系列关闭防火墙但是端口依然无法访问

centos7.3系统,已经关闭firewalld,但是除了22端口,其余端口无法被外界访问,本地访问正常,解决步骤:
1、先开启firewalld:systemctl start firewalld
2、放通端口:firewall-cmd --zone=public --add-port=8080/tcp --permanent
3、重新加载配置文件:firewall-cmd --reload
此时测试,端口已经能够访问了,如果不需要firewall,可以再关闭,已放通端口不受影响(为什么一开始我不放通端口直接关闭firewall不行?这点有了解的大神帮忙解答下)

注:firewall依赖本机python版本,如果自己升级了python版本,需要修改firewall配置文件(实际版本号以本机实际为准,我的为2.7):
1、vim /usr/bin/firewall-cmd, 将#!/usr/bin/python -Es 改为 #!/usr/bin/python2.7 -Es
2、vim /usr/sbin/firewalld, 将#!/usr/bin/python -Es 改为 #!/usr/bin/python2.7 -Es

posted @ 2022-04-01 15:15  liftsail  阅读(3660)  评论(0编辑  收藏  举报