使用Docker打包镜像并发布

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

1、docker介绍

        Docker 是一个开源的应用容器引擎以镜像的形式进行发布。docker的图标是一个大鲸鱼驮着许多集装箱在海上航行。大鲸鱼就是docker集装箱就是一个个容器。容器是完全使用沙箱机制相互之间不会有任何接口每个容器都有自己独立的环境环境设置、网络、文件系统等就像一个个集装箱隔离开来彼此没有任何联系。而每个箱子又可以打包成一个新的镜像放到其它服务器的docker环境中直接运行不再需要重复安装程序运行环境。

1.1、docker镜像

        docker镜像其实就类似于虚拟机镜像操作系统镜像。是一个只读的模板一个独立的文件系统包括运行容器所需的数据可以用来创建新的容器。我的理解镜像就相当于安装包安装文件这种你docker pull下来的是一个安装包然后docker会自动给你安装上去。

1.2、docker容器

        docker容器每一个单独的容器其实就相当于一台独立的服务器docker通过容器技术把这个服务器划分为一个个单独的互不干扰的子服务器。好处在于每个容器都是独立的有自己独立的环境设置如果不用容器的话我一台服务器要装jdk要装tomcat要装mysql要装rabbitMQ等等每装一个软件/中间件我都有可能要单独去配置环境变量这种。有可能装着装着不同的软件之间有版本冲突什么的可能装了这个结果那个就装不上了什么的还要做兼容性配置。当然出于成本的考虑你不可能一个服务器就装一个软件吧。所以最好的方法就是通过虚拟化技术把一个大的服务器拆分成一个个小的独立的服务器每个小服务器分别装相应的软件/中间件一个小服务器就只装单独一个软件。当然也可以在服务器里面再搭虚拟机不过这样很麻烦不如用docker一步到位好。

1.3、docker仓库

        docker仓库我的理解其实就和maven仓库Git仓库的作用差不多吧。反正就是一个专门放置镜像的地方。可以先在docker里配置仓库的地址要哪些镜像直接就从这个docker仓库里pull下来。比如docker镜像加速

         其实那些所谓的镜像就是一个个docker仓库嘛。说到这个仓库我突然联想到之前2021年的时候有个叫什么“懒人专用全网VIP视频免费去广告、全网音乐.....”的一个基于浏览器的脚本。反正就是可以让你免费看各个网站会员的视频音乐这种。其实那个所谓的脚本我用了以后发现其实原理很简单首先他那个脚本可以检测到你当前正在观看的视频音乐的名称然后出现一个悬浮图标你点了以后就会从他的资源仓库中找到相应的资源再播放给你看。反正不是真的破解网站会员。一开始还蛮好用的不过后来开始收费了而且不开会员还给你限速我就没再用了。我感觉国内的很多镜像地址也应该是类似的原理吧因为我们国家互联网防火墙的存在所以普通人无法或者速度很慢去访问下载一些外网的资源。所以嘛镜像地址要么就是像那个什么“懒人的脚本”一样建一个自己的资源库收纳各种资源你要用直接从他的资源库里面拿。要么可能一些企业是被政府授权有专门的通道可以访问外网你用他们的镜像地址相当于就是“借道”。

1.4、docker镜像和容器

     关于docker镜像和容器之间的关系我看网上有两种说法

  1. docker镜像相当于类而容器相当于类new出来的一个对象。
  2. docker镜像是一个程序程序是静态的只是一串代码而容器是程序启动后的一个正在运行的进程。

        

        我个人比较认同第二种说法。

2、在linux上配置docker环境

        我使用的是linux是Ubuntu装在VMWare虚拟机里面的下载iso镜像可以去清华大学开源软件镜像站 | Tsinghua Open Source Mirror

 2.1、安装docker适用于Ubuntu

sudo apt-get update

 sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

--然后添加GPG秘钥
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg


--加入官方仓库
echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

--用apt安装
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

--启动docker
systemctl start docker


--查看docker版本出来docker版本信息则说明docker安装成功了
docker version

--删除容器
docker rm xxx 

--删除镜像
docker rmi xxx

详细安装教程可参考Ubuntu Docker 安装 | 菜鸟教程 (runoob.com)

Ubuntu 18.04 安装docker2021最新_PWN_my_ass的博客-CSDN博客_ubuntu18.04安装docker

2.2、安装mysql镜像

         docker version看到版本信息则说明docker安装成功了。

--下载mysql镜像没加版本号默认就是最新的docker pull mysql:5.7.27
docker pull mysql

--创建并运行一个名叫ErpMySQL的mysql容器
docker run --name ErpMySQL -e MYSQL_ROOT_PASSWORD=123456 -d -p 3306:3306  mysql

--运行指定容器
docker start ErpMySQL

关于docker常用的一些命令可参考菜鸟教程Docker 命令大全 | 菜鸟教程 (runoob.com)

如果权限不够出现permission denied提示的话记得在命令前加上sudo

运行docker ps可以查看当前正在运行的容器

3、本地调试

3.1、 本地连接linux虚拟机上的mysql镜像将.sql数据导入docker上安装的mysql镜像中去。

3.2、修改配置文件

        修改项目中ymlxml等一些配置文件中配置的mysql、redis、rabbitMQ的地址信息当然因为我的这个项目是单体应用所以需要手动修改每个配置文件如果是微服务架构的话可以直接通过配置中心解决。

3.3、启动本地Springboot项目

         启动成功是本地访问但mysql连的是docker上面的mysql。

4、使用docker打包发布

4.1、本地Springboot项目打成jar包注意打包时去掉test的代码

把打好的jar包直接上传到linux服务器上

4.2、新增Dockerfile文件

        Dockerfile 是一个用来构建镜像的文本文件文本内容包含了一条条构建镜像所需的指令和说明。

 Dockerfile

FROM openjdk:8-jre
EXPOSE 8080

VOLUME /tmp

ENV TZ=Asia/Shanghai
RUN ln -sf /usr/share/zoneinfo/{TZ} /etc/localtime && echo "{TZ}" > /etc/timezone

ADD erp.jar  /app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-jar","/app.jar"]

  • FROM openjdk:8-jre        表示基于java8环境的
  • EXPOSE 8080        表示对外暴露的端口为8080
  • VOLUME /tmp        表示挂载数据卷到/temp目录因为容器删除后数据也会丢失因此需要有个地方存放数据通过把容器的数据卷内容挂载在主机的指定目录从而实现容器的持久化
  • ENV TZ=Asia/Shanghai        设置时区环境变量配置
  • RUN ln -sf /usr/share/zoneinfo/{TZ} /etc/localtime && echo "{TZ}" > /etc/timezone        设置容器时区
  • ADD erp.jar  /app.jar        表示把jar包复制到镜像服务里面的根目录并改名称为app.jar
  • RUN bash -c 'touch /app.jar'        表示执行创建app.jar
  • ENTRYPOINT ["java","-jar","/app.jar"]        表示执行启动命令java -jar

4.3、把jar包构建成docker镜像

--不指定镜像版本直接构建
docker build -t erp .

--指定镜像版本1.0构建
sudo docker build -t erp:1.0 .


--docker build命令结构
docker build -t  isoName:tag   -f  /Dockerfile
 
isoName:镜像名称
tag    :版本号
Dockerfile:dockerfile文件

         注意如果在build镜像的时候出现如下问题有可能是Dockerfile里面写的不对比如哪里多了空格,tab什么的建议Dockerfile直接在Ubuntu界面复制粘贴内容不要通过vim在命令行里面编辑。

--启动镜像docker link 把运行的容器进行关联起来再进行访问比如这里的link ErpMySQL:erpmysql就是在启动这个erp镜像的时候关联docker上的mysql镜像创建的容器ErpMySQL
docker run -p 8080:8080 --name erp --link ErpMySQL:erpmysql -d erp

--查看镜像启动日志
docker logs -f erp

 

 没有报错启动成功

不过我在访问的时候报了一个错

产生原因是在打jar包的时候没有把jsp打进去

         maven打包默认打的是jar包jar是java打的包jar包是用java来写的项目打包来的里面只有编译后的class和一些部署文件。通常不会包括web文件比如:html,jsp等因此需要在maven里面设置使得打jar包的时候一并把那些web文件一起带上。jar包只要有jre环境直接java -jar就可以运行了。jre里面有个自带的tomcat可以解析jar包里的web文件htmljsp等。

        而war包是javaweb打的包jdk无法直接运行运行war包需要装一个tomcat或者其他类似的服务器用来运行war包。

        一个war文件就相当于一个web应用程序而jar文件就是把类和一些相关的资源封装到一个包中便于程序中引用。

解决方法我参考了这篇SpringBoot集成jsp打包成jar包可访问jsp页面_漫漫人生路&的博客-CSDN博客

在pom.xml增加jsp的一些配置

 <!--用于编译jsp-->
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>

<!--        打成的jar包名字-->
        <finalName>erp</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>1.4.2.RELEASE</version>
                <configuration>
                    <!--启动类-->
                    <mainClass>com.springboot.erp.ErpApplication</mainClass>
                </configuration>
            </plugin>
        </plugins>

        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/**</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/**</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/webapp</directory>
                <includes>
                    <include>**/**</include>
                </includes>
                <targetPath>META-INF/resources</targetPath>
                <filtering>false</filtering>
            </resource>
        </resources>
    </build>

Reload一下maven然后重新打包然后就可以看到jsp文件被打在jar包里了

 

        在docker上把原来的容器镜像统统删掉再把新打包的jar包上传上去然后重新build镜像启动容器

docker stop erp    --停止erp容器
docker rm erp    --移除erp容器
docker rmi 643b3c00680d    --删除之前的erp.jar包build的镜像
docker build -t erp:1.0 .    --重新把新的jar包build成镜像erp:1.0
docker run -p 8080:8080 --name erp --link ErpMySQL:erpmysql -d erp:1.0    --从erp:1.0镜像中创建一个名叫erp的容器并运行该容器
docker logs -f erp    查看erp容器的日志

访问成功了

 

5、总结

        因为目前临近春节不少同事都休假去了我在公司没啥事情所以就抽空把docker过了一遍。docker我现在的公司有在用不过我在工作基本上就没有太多的对docker的使用无非就是在dashboard上面拉拉日志什么的。相对于传统的打包发布来说docker的最大特点就是方便快捷你要装啥东西几行命令就可以搞定的。比起传统的打包发布省去了很多装软件配环境的麻烦。而且docker也支持自动发布嘛使用daocloud你只要把jar包或者war包复制下来到指定的目录然后和docker进行一个关联docker会帮你自动构建镜像并运行。省去了自己直接操作docker。当然也有一种方法是写一个脚本实现自动打包。也就是说你只负责合代码到指定分支就行了剩下的打包发布交给脚本和docker了。

6、参考资料

就几条命令一键学会Docker部署SpringBoot项目 - 掘金 (juejin.cn)

Ubuntu保存退出vim编辑器_口袋里のInit的博客-CSDN博客_ubuntu退出vim编辑

Jenkins构建服务Dockerfile报错manifest for java:8-jre not found: manifest unknown: manifest unknown_TheChainsmoker的博客-CSDN博客

Docker Dockerfile | 菜鸟教程 

Docker进阶一挂载——容器数据卷 - 我永远喜欢石原里美 - 博客园 

docker镜像构建、镜像打tag、镜像推送_A-ezra的博客-CSDN博客 

如何在Docker中查看MySQL的版本_王菜鸟的博客-CSDN博客_docker 查看mysql 

SpringBoot集成jsp打包成jar包可访问jsp页面_漫漫人生路&的博客-CSDN博客 

什么是Docker看这一篇干货文章就够了 - 知乎 

Docker 教程 | 菜鸟教程 

JDK与OpenJDK区别简略通俗易懂_又是面向Java这个对象的一天的博客-CSDN博客_openjdk与jdk区别 

为什么要用docker - 知乎 

关于docker容器和镜像的区别 - jason.bai - 博客园 

jar包和war包的介绍与区别 - 简书 

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Docker