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

Docker 作为一种新兴的虚拟化方式,它可以更高效的利用系统资源,不需要进行硬件虚拟以及运行完整操作系统等额外开销。
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
最重要的是一致的运行环境。Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性。从而达到真正意义上的 一次构建,到处执行。
二、构建镜像
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仓库。
查看镜像
$ 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

-END-
相关文章:
SpringBoot + Docker 实现一次构建到处运行
一、容器化部署的好处 Docker 作为一种新兴的虚拟化方式,它可以更高效的利用系统资源,不需要进行硬件虚拟以及运行完整操作系统等额外开销。 传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行宿主内…...
Spring-Cloud-Gateway如何自定义断言工厂?
遇到这么一个面试题:如何在网关做配置,实现只有在早晨9点到下午18点之间接口才允许访问,其他时间访问都是404。 我们知道网关的一个重要的作用就是路由转发,路由表的配置大概是这个样子: spring:cloud:gateway:routes:- id: user…...
Android平台如何高效率实现GB28181对接?
技术背景 GB28181协议是一种用于设备状态信息报送的协议,可以在不同设备之间进行通信和数据传输。 在安卓系统上实现GB/T 28181非常必要,GB28181协议实现分两部分,一部分是信令,另外一部分就是媒体数据的编码。 信令主要包括S…...
vue2 实现后台管理系统左侧菜单联动实现 tab根据路由切换联动内容,并支持移动端框架
效果图: pc端 移动端 由于代码比较多,我这里就不一一介绍了,可以去我的git上把项目拉下来 git地址https://gitee.com/Flechazo7/htglck.git 后台我是用node写的有需要的可以评论联系...
一本通1910:【00NOIP普及组】计算器的改良题解
今天是编程集训的第二天,也是我来到CSDN整整1年。感谢所有阅读过我的文章的人,谢谢。 今天的比赛难度略低于昨天,但这道题也卡了我好久。 进入正题 题目: 题目描述: NCL是一家专门从事计算器改良与升级的实验室&a…...
golang网络编程学习-1rpc
网络编程主要的内容是: 1.TCP网络编程 2.http服务 3.rpc服务 4.websocket服务 一、rpc RPC 框架----- 远程过程调用协议RPC(Remote Procedure Call Protocol)-----允许像调用本地服务一样调用远程服务。 RPC是指远程过程调用,也就是说两台服…...
【MQTT】Esp32数据上传采集:最新mqtt插件(支持掉线、真机调试错误等问题)
前言 这是我在Dcloud发布的插件-最完整Mqtt示例代码(解决掉线、真机调试错误等问题),经过整改优化和替换Mqtt的js文件使一些市场上出现的问题得以解决,至于跨端出问题,可能原因有很多,例如,合法…...
基于PyQt5的UI界面开发——对基本控件的介绍
基本控件介绍 在PyQt中,控件是用户界面上的可见元素。控件可以包括按钮、标签、文本框、进度条等。每个控件都有自己的属性和方法,可以通过编程方式进行调整和操作。 以下是一些常用的PyQt控件: QLabel(标签)&#…...
flink 报错:Caused by: java.lang.RuntimeException: Assigned key must not be null!
问题描述 不同情况下需要找对应的解决方法,这里介绍的解决方法不能拓展到别的场景。 场景描述: flink job 的开发过程中遇到这样的需求,需要先 map 处理,然后把返回的 DataStream 作为输入,流入别的 map 中。这里我们遇…...
AN OVERVIEW OF LANGUAGE MODELS RECENT DEVELOPMENTS AND OUTLOOK
LLM系列相关文章,针对《AN OVERVIEW OF LANGUAGE MODELS: RECENT DEVELOPMENTS AND OUTLOOK》的翻译。 语言模型综述:近年来的发展与展望 摘要1 引言2 语言模型的类型2.1 结构化LM2.2 双向LM2.3 置换LM 3 语言单元3.1 字符3.2 单词和子单词3.2.1 基于统…...
ArcGIS、ENVI、InVEST、FRAGSTATS等多技术融合提升
专题一 空间数据获取与制图 1.1 软件安装与应用讲解 1.2 空间数据介绍 1.3海量空间数据下载 1.4 ArcGIS软件快速入门 1.5 Geodatabase地理数据库 专题二 ArcGIS专题地图制作 2.1专题地图制作规范 2.2 空间数据的准备与处理 2.3 空间数据可视化:地图符号与注…...
fastapi初使用,构建自己的api
文章目录 1、安装2、api实现2.1、 app.get("/1")2.2、app.get("/{a}")2.3、app.get("/{a}{b}")2.4、函数和api分离 3、运行 原文链接:https://wangguo.site/posts/d98bb3c9.html fastapi 是一个基于 Python 的 API 构建框架ÿ…...
Html基础知识学习——圣杯布局、margin负值、等高布局(十七)
文章目录 圣杯布局margin负值等高布局 圣杯布局 两边页面固定中间页面宽度随着浏览器大小自适应 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-widt…...
从一长串字符串中找出图片,查看是否符合md5要求
/**检查内容中的图片否含有外部链接*/ function checkExternalLinks(content){var pattern /<img[^>]src["]([^"])["][^>]*>/g;var match;var index 0;while ((match pattern.exec(content)) ! null) {var imageUrl match[1];var regex /\/sto…...
新手小白如何学好UI设计?一般学多久? 优漫动游
学习UI设计首先就是软件:PS、AI、CDR等但是掌握了软件不等于就掌握了UI设计,设计的思维也是很重要的网上很多关于UI设计的教程视频,可以多去看看 广州平面设计培训 要多久这个看个人的学习能力吧,有些人天资聪慧,很快…...
实现 Rollup 插件alias 并使用vitest提高开发效率
本篇文章是对 实现 Rollup 插件 alias | 使用 TypeScript 实现库的基本流程 | 使用单元测试提高开发效率 的总结。其中涉及到开发一个组件库的诸多知识点。 实现一个经常用的 rollup 插件 alias 首先执行npm init命令初始化一个package.json文件,因为插件使用了ty…...
【DSL】ES+DSL 查询语法
【DSL】ESDSL 查询语法 一、前言二、定义1.基本介绍2.语法说明(1)关键字(Keywords)(2)标识符(Identifiers)(3)表达式(Expressions)(4)运算符(Operators)(5)函…...
Vue第三篇:最简单的vue购物车示例
本文参考:Vue Cli(脚手架)实现购物车小案例 - - php中文网博客 效果图: 编写流程: 1、首先通过vue/cli创建工程 vue create totalprice 2、改写App.vue代码如下: <template><div><div v…...
MFC 基于数据库的管理系统
文章目录 初始化设置菜单 添加数据库类创建数据库配置数据库 全部代码 初始化 创建文件选择基于CListView 初始化数据 public:CListCtrl& m_list;CSQLView::CSQLView() noexcept:m_list(GetListCtrl()) {// TODO: 在此处添加构造代码}void CSQLView::OnInitialUpdate() {C…...
EfficientNet论文笔记
EfficientNet论文笔记 通过NAS平衡了channel,depth,resolution,发现在相同的FLOPs下,同时增加 depth和 resolution的效果最好。 数据集效果小于resolution怎么办? EfficientNet—b0框架 表格中每个MBConv后会跟一个…...
Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具
文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...
