SpringBoot + Docker 实现一次构建到处运行~
一、容器化部署的好处

图片
Docker 作为一种新兴的虚拟化方式,它可以更高效的利用系统资源,不需要进行硬件虚拟以及运行完整操作系统等额外开销。
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
最重要的是一致的运行环境。Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性。从而达到真正意义上的 一次构建,到处执行。
基于 Spring Boot + MyBatis Plus + Vue 3.2 + Vite + Element Plus 实现的前后端分离博客,包含后台管理系统,支持文章、分类、标签管理、仪表盘等功能。
GitHub 地址:https://github.com/weiwosuoai/WeBlog
Gitee 地址:https://gitee.com/AllenJiang/WeBlog
二、构建镜像
2.1、Dockerfile
接着我们开始使用 Dockerfile 来定制我们的镜像,从而达到容器化的目的。Dockerfile 的本质就是将一系列修改、安装、构建、操作的命令整合到一起,去构建一个个性化的镜像,以达到一次构建,到处运行。接下来我们就来构建自定义镜像。
在my-project-server模块下创建docker目录,在docker目录下创建Dockerfile。代码如下:
FROM openjdk:8-jreMAINTAINER Micromaple <micromaple@qq.com>RUN mkdir /appCOPY my-project-server-1.0.0-SNAPSHOT.jar /app/app.jarENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/app/app.jar", "--spring.profiles.active=prod,druid-prod"]EXPOSE 8899
-
FROM:指定基础镜像,项目是使用jdk8开发的项目,所以我们指定的基础镜像为openjdk:8-jre -
MAINTAINER:项目维护人员 -
RUN:执行命令,在根目录下创建app目录 -
COPY:将宿主机当前目录下的my-project-server-1.0.0-SNAPSHOT.jar文件拷贝到app目录下,并重命名为app.jar -
ENTRYPOINT:指定容器启动程序及参数 -
EXPOSE:指定运行时容器提供服务的端口
2.2、开始构建
在虚拟机创建目录
mkdir -p /usr/local/docker/my-project/docker
将打包后的my-project-server-1.0.0-SNAPSHOT.jar文件和Dockerfile文件上传至该目录。

图片
执行镜像构建命令
docker build -t my-project-server:v1 .
构建成功
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-project-server v1 ed30386b06d2 11 seconds ago 334MB
openjdk 8-jre 26ac3f63d29f 9 months ago 273MB
三、搭建私服
3.1、搭建 Docker Registry
创建目录
mkdir -p /usr/local/docker/registry
在该目录下创建Docker Registry 的 docker-compose.yml。内容如下:
cd /usr/local/docker/registry
version: '3.1'
services:registry:image: registryrestart: alwayscontainer_name: registryports:- 5000:5000volumes:- ./data:/var/lib/registry
启动容器
docker-compose up -d
3.2、搭建 Docker Registry WebUI
创建目录
mkdir -p /usr/local/docker/docker-registry-frontend
在该目录下创建Docker Registry 的 docker-compose.yml。内容如下:
cd /usr/local/docker/docker-registry-frontend
version: '3.1'
services:frontend:image: konradkleine/docker-registry-frontend:v2ports:- 8080:80volumes:- ./certs/frontend.crt:/etc/apache2/server.crt:ro- ./certs/frontend.key:/etc/apache2/server.key:roenvironment:- ENV_DOCKER_REGISTRY_HOST=192.168.110.158(Docker仓库的IP)- ENV_DOCKER_REGISTRY_PORT=5000
需要将
ENV_DOCKER_REGISTRY_HOST的值更改为自己搭建的DockerRegistry服务的IP
启动容器
docker-compose up -d
浏览器访问http://192.168.110.158:8080/,效果如下:

图片
3.3、客户端配置
在需要上传 Docker 镜像的客户端需配置daemon.json,完整路径在 /etc/docker/daemon.json
vi /etc/docker/daemon.json
需增加如下内容:
"insecure-registries": ["Docker仓库的IP:5000"
]
完整daemon.json内容:
{"registry-mirrors": ["https://xxx.mirror.aliyuncs.com"],"insecure-registries": ["192.168.110.158:5000"]
}
-
registry-mirrors:为镜像加速地址,这里为我自己申请的加速地址。大家可以自己申请一个,也可以在网上找一个。 -
insecure-registries:Docker仓库的IP。
重新启动服务
systemctl daemon-reload
systemctl restart docker
3.4、上传私服
搭建以及配置完成后,需要将我们之前构建的镜像上传至我们自己的Docker仓库。
小哈开源的,基于 Spring Boot + MyBatis Plus + Vue 3.2 + Vite + Element Plus 实现的前后端分离博客,包含后台管理系统,支持文章、分类、标签管理、仪表盘等功能。跪求 Star 呀~
GitHub 地址:https://github.com/weiwosuoai/WeBlog
Gitee 地址:https://gitee.com/AllenJiang/WeBlog
查看镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
my-project-server v1 6af7d633afb7 5 seconds ago 334MB
openjdk 8-jre 26ac3f63d29f 9 months ago 273MB
1)、镜像标记
使用 docker tag 将 my-project-server:v1 这个镜像标记为 192.168.110.158:5000/my-project-server:v1。
192.168.110.158为我的Docker仓库的IP。
格式为:docker tag IMAGE[:TAG] [REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]
命令如下:
docker tag my-project-server:v1 192.168.110.158:5000/my-project-server:v1
标记后,查看镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.110.158:5000/my-project-server v1 6af7d633afb7 3 minutes ago 334MB
my-project-server v1 6af7d633afb7 3 minutes ago 334MB
openjdk 8-jre 26ac3f63d29f 9 months ago 273MB
2)、镜像上传
使用 docker push 上传镜像。
$ docker push 192.168.110.158:5000/my-project-server
The push refers to repository [192.168.110.158:5000/my-project-server]
5b9e874b9f9c: Pushed
e87c042d22f8: Pushed
b4cfcb8385a8: Pushed
2b730cf18c09: Pushed
edeaba958753: Pushed
8bf42db0de72: Pushed
31892cc314cb: Pushed
11936051f93b: Pushed
v1: digest: sha256:5c8a0efff409649a389d0bc74dda94ca96e67e87c92673b4c7dad0078657af40 size: 2000
3)、查看镜像
使用 curl 查看 192.168.110.158:5000/v2/_catalog 地址,可以看到上传成功的镜像
$ curl 192.168.110.158:5000/v2/_catalog
{"repositories":["my-project-server"]}
这里我们可以成功的看到我们上传的镜像。
我们也可以在我们刚刚搭建的WebUI上可视化的查看我们的镜像。效果图如下:

图片
4)、验证
此时我们将本地镜像删除,尝试从私有仓库下载这个镜像
先删除已有镜像
docker rmi my-project-server:v1 192.168.110.158:5000/my-project-server:v1
下载镜像
docker pull 192.168.110.158:5000/my-project-server:v1
$ docker pull 192.168.110.158:5000/my-project-server:v1
v1: Pulling from my-project-server
0e29546d541c: Already exists
9b829c73b52b: Already exists
cb5b7ae36172: Already exists
99ce012bef04: Already exists
22dc2a72d098: Already exists
9c69a57e10d9: Already exists
776f54050ab5: Pull complete
65a83a9a7871: Pull complete
Digest: sha256:5c8a0efff409649a389d0bc74dda94ca96e67e87c92673b4c7dad0078657af40
Status: Downloaded newer image for 192.168.110.158:5000/my-project-server:v1
192.168.110.158:5000/my-project-server:v1
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.110.158:5000/my-project-server v1 6af7d633afb7 15 minutes ago 334MB
openjdk 8-jre 26ac3f63d29f 9 months ago 273MB
我们可以看到可以正常拉取。
四、容器启动
镜像构建并上传至完成后,可以直接使用Docker Compose来启动容器。实现一次构建到处运行。
创建目录
mkdir -p /usr/local/docker/my-project
在该目录下创建Docker Registry 的 docker-compose.yml。内容如下:
cd /usr/local/docker/my-project
version: '3.1'
services:my_project_server:image: 192.168.110.158:5000/my-project-server:v1container_name: my-project-serverrestart: alwaysports:- 8899:8899volumes:- ./logs:/logsenvironment:TZ: Asia/Shanghai
启动容器
docker-compose up -d
查看容器启动状态
docker ps -a
访问查询所有用户接口
http://ip:8899/sys-user/get/all

图片
相关文章:
SpringBoot + Docker 实现一次构建到处运行~
一、容器化部署的好处 图片 Docker 作为一种新兴的虚拟化方式,它可以更高效的利用系统资源,不需要进行硬件虚拟以及运行完整操作系统等额外开销。 传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行…...
clang-format格式化代码
1. clang-format简介 Clang-Format可用于格式化(排版)多种不同语言的代码。其自带的排版格式主要有:LLVM, Google, Chromium, Mozilla, WebKit等; 利用style参数配置风格。通过编写 .clang-format 文件,可以实现代码风格的配置。…...
品牌宣传与媒体传播是声誉管理的主要方式之一
企业声誉是现如今影响品牌信任度、客户忠诚度的重要因素,也被视为企业的一种无形资,更影响着企业未来的发展。因此,企业声誉管理也日渐成为企业管理的重要课题之一,尤其在品牌营销管理领域。 什么是声誉管理?声誉管理有…...
2023年8月7日-8月13日,(上午熟悉公司代码,周一到周五晚上优先工作所急视频教程,其他业余时间进行ue视频教程,为独立游戏做准备)
按照规划,上午熟悉公司源码,下午进行filament和ue渲染,晚上写工作代码。回家后泛读pbrt或者其他书籍催眠。 业余学习ue的各种视频教程,为独立游戏做准备(公司也实行末位淘汰,给自己留条后路)。累…...
Vue3 第二节 Vue3的响应式
1.Vue3的响应式原理 2.ref函数和reactive函数的对比 3.setup注意点 一.Vue3的响应式原理 1.Vue2.x中的响应式原理 ① 实现原理 对象类型:通过Object.defineProperty() 对属性的读取,修改进行拦截(数据劫持)数组类型…...
通过easyui实现动态控制表格字段显示、导出表格数据
前言 学过layui前端框架的都知道,layui默认帮我们实现了控制表格字段显示以及数据的导出功能。 1、控制表格字段显示 2、数据导出 3、导出为pdf:导出按钮的右边那个按钮就是打印pdf的 那么,easyui要怎么实现这些功能呢?这篇文章就…...
JWT入门,jwt可以解密吗?
JWT 什么是 JWT JSON Web Token,通过数字签名的方式,以 JSON 对象为载体,在不同的服务终端之间安全地传输信息 官网:https://jwt.io/SDK: https://jwt.io/libraries (含Java和各种语言)Java SDK(上面的SDK链接得到): https://g…...
36.利用解fgoalattain 有约束多元变量多目标规划问题求解(matlab程序)
1.简述 多目标规划的一种求解方法是加权系数法,即为每一个目标赋值一个权系数,把多目标模型转化为一个单目标模型。MATLAB的fgoalattain()函数可以用于求解多目标规划。 基本语法 fgoalattain()函数的用法: x fgoalattain(fun,x0,goal,weig…...
EPPlus 读取和生成Excel
在项目中添加了EPPlus库的引用,你可以通过NuGet包管理器或手动将EPPlus库添加到项目中。同时,需要注意的是EPPlus库支持的是xlsx格式的Excel文件。 读取 使用EPPlus读取本地Excel文件的示例代码如下: using OfficeOpenXml;public void Rea…...
Java wait() notify() join()用法讲解
一、wait() 1. 源码: 实际调用本地方法 2. 作用 释放当前锁,并让当前线程进入等待状态;timeoutMillis为等待时间,单位毫秒,如果为0则表示无限等待下去;该方法使用前提是:当前执行线程必须持…...
新手注意事项-visual studio 来实现别踩白块儿
自己之前为了熟悉easyx练习过一个简单的项目,别踩白块儿,链接在这里,别踩白块儿,当时比较稚嫩,很多东西都不会,可以说是只知道最基本的语法,头文件都不知道,一个一个查资料弄懂的&am…...
【力扣】2810. 故障键盘 <模拟>
【力扣】2810. 故障键盘 你的笔记本键盘存在故障,每当你在上面输入字符 ‘i’ 时,它会反转你所写的字符串。而输入其他字符则可以正常工作。给你一个下标从 0 开始的字符串 s ,请你用故障键盘依次输入每个字符。返回最终笔记本屏幕上输出的字…...
Docker desktop使用配置
1. 下载安装 https://www.docker.com/ 官网下载并安装doker desktop 2. 配置镜像 (1)首先去阿里云网站上进行注册:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors (2)注册完成后搜索:容…...
第一百二十一天学习记录:线性代数:矩阵乘法运算(宋浩板书)
在编程和学习数据结构的过程中,发现有些算法会用到矩阵和矩阵的乘法运算,因此先将这一个知识点学习一下。 矩阵和行列式的区别 各种矩阵的概念 矩阵运算 乘法☆ 总结三条不满足...
模拟实现消息队列项目(系列3) -- 服务器模块(硬盘管理)
目录 前言 1. 创建项目 2. 创建核心类 2.1 Exchange 2.2 MSQueue 2.3 Binding 2.4 Message 3. 数据库设计 3.1 SQLite 配置 3.2 Mapper层代码实现 3.2.1 创建表操作 3.2.2 交换机 队列 绑定的增加和删除 3.3 实现DataBaseManager 3.4 DataBaseManager单元测试 4.…...
【iOS】锁
线程安全 当一个线程访问数据的时候,其他的线程不能对其进行访问,直到该线程访问完毕。简单来讲就是在同一时刻,对同一个数据操作的线程只有一个。而线程不安全,则是在同一时刻可以有多个线程对该数据进行访问,从而得…...
杰发科技(合肥)2021笔试题
笔试时间:2020.10.17 ,10:30-12:00。 岗位:Linux 驱动工程师。 题型:选择题8道,填空题10道,编程题4道。 杰发科技主要做汽车电子,由北京四维图新控股,对汽车电子感兴趣的有机会可以应聘试试。 选择题 1、128,4 #include<stdio.h> unsigned int getstrsiz…...
Java堆排序
目录 PriorityQueue自己实现 PriorityQueue public class PriorityQueueMain {public static void main(String[] args) {int[] temp {40, 2, 33, 26, 35, 8, 8, 26, 29, 2};PriorityQueue<Integer> priorityQueue new PriorityQueue<>();for (int i 0; i <…...
GitHub的基本使用教程
GitHub是一个基于web的版本控制和协作平台。它允许开发人员将他们的代码存储库存储在云中,并与其他人一起进行工作。GitHub还提供了各种工具和功能来帮助开发人员管理和组织他们的代码项目,包括拉出请求、问题跟踪、代码评论等等。此外,它托管…...
objectMapper.configure 方法的作用和使用
objectMapper.configure 方法是 Jackson 提供的一个用于配置 ObjectMapper 对象的方法。ObjectMapper 是 Jackson 库的核心类,用于将 Java 对象与 JSON 数据相互转换。 configure 方法的作用是设置 ObjectMapper 的配置选项,例如设置日期格式、设置序列…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
CentOS下的分布式内存计算Spark环境部署
一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架,相比 MapReduce 具有以下核心优势: 内存计算:数据可常驻内存,迭代计算性能提升 10-100 倍(文档段落:3-79…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
Redis:现代应用开发的高效内存数据存储利器
一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发,其初衷是为了满足他自己的一个项目需求,即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源,Redis凭借其简单易用、…...
Golang——6、指针和结构体
指针和结构体 1、指针1.1、指针地址和指针类型1.2、指针取值1.3、new和make 2、结构体2.1、type关键字的使用2.2、结构体的定义和初始化2.3、结构体方法和接收者2.4、给任意类型添加方法2.5、结构体的匿名字段2.6、嵌套结构体2.7、嵌套匿名结构体2.8、结构体的继承 3、结构体与…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
