使用Docker打包镜像并发布

news2024/9/21 10:50:17

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/172269.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高级Spring之BeanFactory 与 ApplicationContext 的区别

ApplicationContext接口 SpringBootApplication public class A01 {private static final Logger log LoggerFactory.getLogger(A01.class);public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {//启动SpringBoot程序…

Python Scipy 显著性检验

Scipy 显著性检验显著性检验&#xff08;significance test&#xff09;就是事先对总体&#xff08;随机变量&#xff09;的参数或总体分布形式做出一个假设&#xff0c;然后利用样本信息来判断这个假设&#xff08;备择假设&#xff09;是否合理&#xff0c;即判断总体的真实情…

Linux基本功系列之userdel命令实战

春节马上要到了&#xff0c;大街上到处都是张灯结彩&#xff0c;喜气洋洋的景象&#xff0c;你们那里也开始了吗&#xff1f; 文章目录一. userdel命令概述二. 语法格式及常用选项语法格式及常用参数三. 参考案例3.1 删除用户但不删除家目录等相关的文件3.2 把用户彻底删除3.3 …

【Linux05-进程控制】进程创建、进程等待、进程退出、进程程序替换(附简易shell实现)

前言 本期分享进程控制的内容。 博主水平有限&#xff0c;不足之处望请斧正&#xff01; 进程的控制主要分为四点&#xff1a; 进程创建进程退出进程等待进程程序替换 进程创建 怎么创建 通过fork创建。 #fork 是什么 创建子进程的函数。&#xff08;使用已经介绍过&am…

Python基础学习 -- 概念

一、变量python的变量定义起来比较随意&#xff0c;不用定义数据类型a123b"123"系统会自动识别a为数值&#xff0c;b为字符串二、关键字定义变量名字的时候&#xff0c;要避开下面的关键字&#xff0c;但是可以通过大小写区分&#xff0c;as123;#错误定义As123;print…

阿里云服务器ECS

云服务器 ECS云服务器ECS&#xff08;Elastic Compute Service&#xff09;是一种简单高效、处理能力可弹性伸缩的计算服务。帮助您构建更稳定、安全的应用&#xff0c;提升运维效率&#xff0c;降低IT成本&#xff0c;使您更专注于核心业务创新。为什么选择云服务器ECS选择云服…

音频如何分割成两段音频?这些实用方法值得收藏

有些时候&#xff0c;我们从网上下载的音频素材可能会出现体积较大、播放时间长等情况&#xff0c;而我们却只需要其中的一小段。这个时候我们就需要借助一些音频分割软件来将重要的音频片段提取出来&#xff0c;从而有助于缩小音频文件的占比以及存储。那么如何如何分割音频呢…

JVM进修之路(一)程序计数器与虚拟机栈

JVM 定义&#xff1a;JVM:Java Virtual Machine&#xff0c;也就是Java运行时所需要的环境&#xff08;Java二进制字节码运行时所需要的环境&#xff09; 好处&#xff1a; 1.java代码一次编写&#xff0c;跨平台运行 2.自动内存管理&#xff0c;垃圾回收 3.数组下标越界检查 4…

千锋Node.js学习笔记

千锋Node.js学习笔记 文章目录千锋Node.js学习笔记写在前面1. 认识Node.js2. NVM3. NPM4. NRM5. NPX6. 模块/包与CommonJS7. 常用内置模块1. url2. querystring3. http4. 跨域jsonpcorsmiddleware&#xff08;http-proxy-middleware&#xff09;5. 爬虫6. events7. File System…

Mysql常用命令练习(一)

Mysql常用命令练习&#xff08;一&#xff09;一、数据库的三层结构二、数据库2.1、创建数据库2.2、查看、删除数据库2.3、备份和恢复数据库三、表3.1、创建表mysql常用的数据类型(列类型)创建表查看表查看表结构练习3.2、修改表修改表名修改表的字符集添加列修改列删除列练习3…

轻量级网络模型ShuffleNet

在学习ShuffleNet内容前需要简单了解卷积神经网络和MobileNet的相关内容&#xff0c;大家可以去看我之前的一篇博客MobileNet发展脉络&#xff08;V1-V2-V3&#xff09;&#xff0c;&#x1f197;&#xff0c;接下来步入正题~卷积神经网络被广泛应用在图像分类、目标检测等视觉…

易盾sdk引起项目的整体耗时问题?

大家好&#xff1a; 我是烤鸭。今年年初的时候&#xff0c;项目接入易盾sdk之后&#xff0c;随着接口调用次数增多(用到易盾sdk的接口)&#xff0c;项目整体性能变差。写篇文章做个复盘记录&#xff0c;其实同事已经写过了&#xff0c;我借鉴部分再拓展一些。 问题描述 突然收…

【JavaEE初阶】第五节.多线程 ( 基础篇 ) 线程安全问题(上篇)

目录 文章目录 前言 一、线程安全的概述 1.1 什么是线程安全问题 1.2 存在线程安全问题的实例 二、线程安全问题及其解决办法 2.1 案例分析 2.2 造成线程不安全的原因 2.3 线程加锁操作解决原子性 问题 &#xff1b; 2.3.1 什么是加锁 2.3.2 使用 synchronized关键字…

爆品跟卖商家必读:2023年快速入局TikTok选品5大关键

TikTok商业进程一直有在发展&#xff0c;开启东南亚小店&#xff0c;美国小店内邀……有吸引了不少外贸工厂和传统跨境电商卖家等玩家入局。2022年这一年&#xff0c;不管是直播带货&#xff0c;短视频带货&#xff0c;还是广告投流&#xff0c;数据都有新的变化。据报道&#…

Word 允许西文在单词中间换行,没用/无效 终极办法

有时在写论文中&#xff0c;英文的调整相当麻烦&#xff0c;为了节约版面&#xff0c;会设置允许西文在单词中间换行。但有时不希望这样&#xff0c;特别是在复制网上英文时&#xff0c;会出现单词分断换行情况&#xff0c;如何解决&#xff1a; 1.一般办法。 在Word选择要调整…

C规范编辑笔记(十)

往期文章&#xff1a; C规范编辑笔记(一) C规范编辑笔记(二) C规范编辑笔记(三) C规范编辑笔记(四) C规范编辑笔记(五) C规范编辑笔记(六) C规范编辑笔记(七) C规范编辑笔记(八) C规范编辑笔记(九) 正文&#xff1a; 又是新的一年&#xff0c;2023年的第一篇没想到隔了这么久…

MyBatis-Plus加密字段查询(密文检索)

MyBatis-Plus数据安全保护(加密解密)解释说明 1.字段加密后&#xff0c;数据库存储的字段内容为十六进制格式的密文2.条件查询时&#xff0c;若不对密文进行处理将无法匹配出想要的结果3.处理方式是借助SQL的AES_DECRYPT函数将密文解密后匹配4.SQL的解密函数只有AES_DECRYPT&am…

Java-流和IO

文章目录流InputStreamFileInputStream常用方法详情代码示例BufferInputStream常用方法详情代码示例OutputStreamFileOutputStream常用方法详情代码示例BufferedOutputStream常用方法详情代码示例ReadWriteJava的java.io库提供了IO接口&#xff0c;IO是以流为基础进行输入输出的…

云原生技能树-docker image 操作-练习篇

从Docker Hub 拉取已有镜像 一个Docker 镜像(image)包含了程序代码和程序运行所依赖的所有环境。 Docker 镜像一般存放在镜像仓库服务(Image Registry)里&#xff0c;默认的镜像仓库服务是Docker Hub。 用户可以制作、构建镜像、将镜像上传到镜像仓库服务&#xff0c;从而可以…

100w人在线的 弹幕 系统,是怎么架构的?

Shopee是东南亚及中国台湾地区的电商平台 。2015年于新加坡成立并设立总部&#xff0c;随后拓展至马来西亚、泰国、中国台湾地区、印度尼西亚、越南及菲律宾共七大市场。 Shopee拥有商品种类&#xff0c;包括电子消费品、家居、美容保健、母婴、服饰及健身器材等。 2022年第二…