文章目录
前言
在ubuntu系统上部署java程序,可以通过java -jar xxx.jar命令启动,也可以通过sh文件将多行命令写入一个sh文件,通过./xxx.sh启动程序。但以上两种程序都需要用户进入控制台手动输入命令,对不熟悉linux系统的用户不是很友好。
于是选择通过docker制作java程序镜像,通过镜像和容器启动java程序。
部署程序
打包程序
我通过Maven打包的springboot框架程序,程序中引入了一个依赖。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>testmaven00</artifactId>
<groupId>com.hzx</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>testJava02</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.0.RELEASE</version>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
我把jar包放到了/www/wwwroot/test/java01目录下
编辑Dockerfile
在jar包的同目录下创建Dockerfile文件。在创建文件前,需要取得root权限
cd /www/wwwroot/test/java01
vim Dockerfile
编辑Dockerfile文件
FROM openjdk:8
ADD testJava02.jar /www/wwwroot/test/java01/testJava02.jar
ENTRYPOINT ["java","-jar","/www/wwwroot/test/java01/testJava02.jar"]
ENV TZ=Asia/Shanghai
下面解释一下Dockerfile中的关键字
FROM openjdk:8
java运行环境,需要提前通过docker pull openjdk:8拉取jdk镜像到docker中
ADD testJava02.jar /www/wwwroot/test/java01/testJava02.jar
将jar包复制到docker容器中
ENTRYPOINT ["java","-jar","/www/wwwroot/test/java01/testJava02.jar"]
需要执行的启动程序的命令
ENV TZ=Asia/Shanghai
指定时区,否则程序记录的时间会比东八区慢8个小时
创建docker镜像
编辑完Dockerfile后,创建程序的docker镜像
docker build -t java01 .
java01 镜像名称,可通过“:”添加镜像版本,例如java01:1.0
命令最后还有一个“.”,不能忘记
查看镜像
启动镜像
使用命令运行镜像
docker run -d -v /www/wwwroot/test/java01/application.yml:/application.yml -v /www/wwwroot/test/java01/logs:/www/wwwroot/test/java01/log02/ --restart=always java01
-d 表示后台运行
-v 表示挂载,将application.yml文件以及日志目录挂载到docker中。一行命令中可以有多个-v
--restart=always 表示自动启动
java01 为镜像名称,也可以换成IMAGE ID,即上图中的c5e153e0b53c
查看容器
镜像运行后,在docker容器中就可以看到java01的启动情况
以后需要手动启动关闭程序时可通过命令
docker start [CONTAINER ID] docker stop [CONTAINER ID],直接操作容器
docker start a31409ed521d
docker stop a31409ed521d
用docker部署java程序调用MVS海康相机
海康威视相机SDK二次开发(JAVA语言),将做好的程序包打包后,通过docker部署,因为这个程序引用了外部jar包,所以在部署时遇到了很多问题,在这里记录一下。
配置MVS环境
已经安装好了MVS相机环境,直接解压从官网下载的tar文件,解压后运行setup.sh文件,可在opt目录下找到MVS相关内容。
/etc/profile 文件中也自动添加了环境变量,记住LD_LIBRARY_PATH动态环境变量,后面会用到。
直接运行jar包
二次开发的海康相机程序,需要导入一个外部包。
这里在写代码时,直接通过依赖导入,通过Maven install打包
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>testmaven34hikvision</artifactId>
<groupId>com.hzx</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>original_save_image</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!--导入相机外部包-->
<dependency>
<groupId>com.hzx</groupId>
<artifactId>MvCameraControlWrapper</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/MvCameraControlWrapper.jar</systemPath>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.yml</include>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.0.RELEASE</version>
<configuration>
<fork>true</fork>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>
直接运行jar包,发现程序可以正常运行。这里因为我并没有连接相机,所以程序输出“No devices found!”,属于正常现象。
按照上述方法配置Dockerfile文件并且启动docker镜像
vim Dockerfile
FROM openjdk:8
ADD save_image.jar /www/wwwroot/test/cameraDocker/save_image.jar
ENTRYPOINT ["java","-jar","/www/wwwroot/test/cameraDocker/save_image.jar"]
ENV TZ=Asia/Shanghai
启动镜像
docker run -v /www/wwwroot/test/cameraDocker/application.yml:/application.yml -v /www/wwwroot/test/cameraDocker/logs:/www/wwwroot/test/cameraDocker/log02/ saveimage
可以看到启动失败,程序运行报错
Caused by: java.lang.UnsatisfiedLinkError: no MvCameraControlWrapper in java.library.path
说明没有找到外部依赖包中的指定方法。
但是通过输出的java.library.path,将MVS开发包复制到了/opt/MVS/lib/64目录中,依旧报错。
于是在Dockerfile文件中,指定动态库的路径
添加一行:ENV LD_LIBRARY_PATH=/usr/java/packages/lib/amd64:$LD_LIBRARY_PATH
FROM openjdk:8
ADD save_image.jar /www/wwwroot/test/cameraDocker/save_image.jar
ENV LD_LIBRARY_PATH=/opt/MVS/lib/64:$LD_LIBRARY_PATH
ENTRYPOINT ["java","-jar","/www/wwwroot/test/cameraDocker/save_image.jar"]
ENV TZ=Asia/Shanghai
删除原先的容器和镜像,重新配置镜像启动程序
依旧出现了一样的错误。分析还是没有将动态库的地址挂载到docker内部,所以在启动镜像时,将动态库地址也挂载到docker中。
docker run -v /www/wwwroot/test/cameraDocker/application.yml:/application.yml -v /www/wwwroot/test/cameraDocker/logs:/www/wwwroot/test/cameraDocker/log02/ -v /opt/MVS/lib/64:/opt/MVS/lib/64 saveimage
这次可以看到启动成功了。
其他问题
实际运行的过程中又遇到了其他问题
日志输出No devices found!
直接通过命令启动程序,可以看到相机列表,但是用Docker运行,就查不到相机列表。
是由于docker的网络模式导致的,默认为桥接模式,相机跟宿主机在同一个局域网,但是由于桥接模式导致无法找到相机。Docker网络配置
解决方法:在启动镜像命令中添加
--network=host
设置了图片保存路径,但没有图片保存
不要忘记图片保存路径也需要挂载到Docker容器中
-v /media/hello/data1/catch-image/bottle_1:/media/hello/data1/catch-image/bottle_1