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 安装docker(2021最新)_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、修改配置文件

        修改项目中yml,xml等一些配置文件中配置的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文件(html,jsp等)。

        而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包的介绍与区别 - 简书

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐