当前位置: 首页 > news >正文

Spring Boot+Nginx+MySQL容器化实战

文章目录

  • 一、实现目标
    • 1.1 概述
    • 1.2 表定义
    • 1.3 spring-boot程序
    • 1.4 nginx配置文件
  • 二、spring-boot程序打包
    • 2.1 生成jar包
    • 2.2 通过scp命令上传到服务器
  • 三、创建宿主机依赖路径、文件
    • 3.1 宿主机mysql初始化文件
    • 3.2 宿主机nginx配置文件
  • 四、定义docker-compose.yml
    • 4.1 nginx容器定义
    • 4.2 mysql容器定义
    • 4.3 spring-boot容器定义
    • 4.4容器依赖关系与健康检查
      • 4.4.1 概述
      • 4.4.2 健康检查
      • 4.4.3 容器依赖关系(也叫容器拓扑)
    • 4.5 容器网络定义
  • 五、启动docker-compose.yml

一、实现目标

1.1 概述

编写一个spring-boot程序,返回user表的所有数据,并且通过nginx反向代理实现。

1.2 表定义

# 文件名:init.sqlDROPDATABASEIFEXISTStest;CREATEDATABASE`test`DEFAULTCHARACTERSETutf8mb4;USE`test`;CREATETABLE`users`(`sno`int(11)DEFAULTNULL,`sname`varchar(50)DEFAULTNULL)ENGINE=InnoDBDEFAULTCHARSET=utf8mb4;INSERTINTOusers(sno,sname)VALUES(1,'hyy'),(2,'blog');

小提示:
init.sql需要存放到容器的docker-entrypoint-initdb.d路径,mysql容器会自动初始化表结构以及一些原始数据!

1.3 spring-boot程序

controller:

packagecom.example.docker_compose;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.jdbc.core.JdbcTemplate;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.ResponseBody;importorg.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/user")publicclassController{@AutowiredJdbcTemplatejdbcTemplate;@RequestMapping("/list")@ResponseBodypublicObjectUsers(){returnjdbcTemplate.queryForList("select * from users");}}

application.properties配置:

spring.application.name=docker_compose#项目名spring.datasource.url=jdbc:mysql://mysql容器名称:3306/数据库名称spring.datasource.username=root# mysql用户名spring.datasource.password=1111# mysql密码

注意:

  1. jdbc的url一定不能错,尤其是容器名称,后面我们定义容器网络,它会根据容器名称寻址(域名解析)。
  2. Docker Compose 未自定义容器名时,容器会生成默认名称,规则为:[项目目录名]-[服务名]-[容器启动序号](例如 p12_spring-mysql-1)
  3. 默认情况下,容器名称会随项目目录、启动次数变化,不建议直接用于 JDBC 配置;可以使用container_name自定义容器名称(后续会讲到)

1.4 nginx配置文件

# 文件名:myapp.conf(只要是.conf后缀都行)server{listen 80;#容器内部监听80端口access_log off;# 关闭日志记录-减少iolocation/{# /所有请求,转发到user/list路径下proxy_pass http://myapp:8080/user/list;}}

小提示:
myapp.conf文件配置到容器/etc/nginx/conf.d可以实现路径转发

二、spring-boot程序打包

2.1 生成jar包

spring-boot项目编写完后,点击maveclear清理缓存,然后点击package打包:
提示BUILD SUCCESS后,target路径下会有一个编译好的jar包:

2.2 通过scp命令上传到服务器

首先创建好服务器这边的项目路径:

pwd/root/docker_stu/docker_compose/p11_blog

后续docker-compose默认会以p11_blog命名容器

然后直接在控制台(windows终端或者idea的控制台都可以)
执行scp命令:

scpjar包路径.jar 用户名(一般都是root)@你的公网IP:你的服务器项目路径

执行完命令会提示输入服务器密码,输入完成后,即可开始传输jar

三、创建宿主机依赖路径、文件

3.1 宿主机mysql初始化文件

cd回到项目路径mkdirmysqlinitcd./mysqlinitviminit.sql

然后把刚才我们提及到的1.2中的init.sql拷贝到这个路径(宿主机路径)

3.2 宿主机nginx配置文件

cd回到项目路径mkdir-p./nginxhome/conf.dcd./nginxhome/conf.dvimmyapp.conf

1.4中的myapp.conf配置文件拷贝过去即可,功能1.4已经讲过,这里不过多赘述

四、定义docker-compose.yml

注意
docker-compose.yml直接放到项目路径,那么其工作目录默认就是项目路径,下面的存储卷路径默认以项目路径为基准;

4.1 nginx容器定义

# 文件名:docker-compose.ymlservices:web:image:nginx:latestvolumes:-./nginxhome/conf.d:/etc/nginx/conf.d#简洁写法,定义绑定卷ports:-8080:80#端口映射expose:-80#声明容器内部开放端口

4.2 mysql容器定义

# 文件名:docker-compose.ymlservices: web:...省略 mysql: image: mysql:5.7 container_name: mysql_container#定义容器名称volumes: - type:bind#这是完整方式定义绑定卷source: ./mysqlinit/ target: /var/lib/mysql/ read_only:truevolume: nocopy:false#若宿主机目录为空,复制容器数据到宿主机目录

4.3 spring-boot容器定义

这里我们使用openjdk镜像去驱动jar包:

# 文件名:docker-compose.ymlservices: web:....省略 myapp: image: openjdk:17#这里版本,使用和自己java版本一致的就行volumes: - ./app:/app/#简洁定义绑定卷command:java-jar/app/docker_compose-0.0.1-SNAPSHOT.jar#设置启动命令

4.4容器依赖关系与健康检查

4.4.1 概述

回到第一节的目标上,我们需要启动一个spring-boot程序,查询user表内容,并且通过nginx实现反向代理;这里涉及多个容器:myapp、mysql、nginx;
那么容器之间一定存在这样的依赖关系:

  1. myapp查询user表需要mysql
  2. nginx反向代理myapp,前提是myapp要优先于nginx启动

docker-compose.yml提供了depends_on来实现这种容器之间的依赖需求。
此外这还引入了一个问题:如何判断依赖的容器是否成功启动呢?
docker-compose.yml也很贴心,给我们提供了healthcheck来自定义容器如何算是启动成功;
接下来,我会接着用这个案例来具体显示其用法

4.4.2 健康检查

根据4.4.1的说明myappmysql是被依赖的容器,那么它们两个一定需要健康检查(虽然nginx健康检出是不必须的,但是建议也加上,实现增肌)

#文件名:docker-compose.ymlservices: mysql: healthcheck: test: mysql-uroot-p1111-e'select 1;'#mysql自带的健康检查interval: 10s timeout: 10s retries:5myapp: healthcheck: test:["CMD","sh","-c","jps -l | grep 'docker_compose-0.0.1-SNAPSHOT.jar' || exit 1"]#该命令openjdk自带的interval: 10s#检查间隔时间timeout: 5s# 定义超时时间retries:5# 重试最大次数start_period: 30s#给一个启动缓冲时间,30s之后才开始记录重试次数

4.4.3 容器依赖关系(也叫容器拓扑)

以下为省略写法(只含有依赖定义):

#文件名:docker-compose.ymlservices:web:depends_on:mysql:condition:service_healthy#condition不为headlthy则容器编排会报错myapp:condition:service_healthymyapp:depends_on:mysql:condition:service_healthy

condition健康类型的选项:

状态值含义
service_healthy依赖的服务容器状态为healthy(健康检查通过)
service_started依赖的服务容器只是running(进程启动,不校验健康状态)—— 这是默认值
service_completed_successfully依赖的服务容器已exited且退出码为 0(适用于一次性任务,如初始化脚本)

4.5 容器网络定义

还是回到第一节讲到的目标,配置Spring-boot+Mysql+Nginx容器编排,网络类型毫无疑问,bridge是最合适的;所以我们可以定义一个自定义bridge网络,让三个容器都加入该自定义网络即可:

#文件名:docker-compose.ymlservices:web:image:nginx:latest#指定容器的nginx镜像版本volumes:-./nginxhome/conf.d:/etc/nginx/conf.d#简洁写法,定义绑定卷ports:-8080:80#端口映射expose:-80#声明容器内部开放端口depends_on:mysql:condition:service_healthymyapp:condition:service_healthynetworks:-mybridge_networkmysql:image:mysql:5.7environment:MYSQL_ROOT_PASSWORD:1111container_name:mysql_containervolumes:-type:bind#这是完整定义方式source:./mysql/mysqllib/target:/var/lib/mysql/#mysql元数据存储在这里read_only:falsevolume:nocopy:false-type:bindsource:./mysql/mysqlinittarget:/docker-entrypoint-initdb.d/#自动根据ini.sql初始化数据healthcheck:test:mysql-u root-p1111-e 'select 1;'interval:10stimeout:10sretries:5networks:-mybridge_networkmyapp:image:openjdk:17volumes:-./app:/app/command:java-jar /app/docker_compose-0.0.1-SNAPSHOT.jarhealthcheck:test:["CMD","sh","-c","jps -l | grep 'docker_compose-0.0.1-SNAPSHOT.jar' || exit 1"]interval:10stimeout:5sretries:5start_period:30snetworks:-mybridge_networknetworks:mybridge_network:driver:bridge

五、启动docker-compose.yml

启动所有容器:

cd回到项目路径dockercompose up-dWARN[0000]mountoftype`bind`should not define`volume`option[+]Running3/3 ✔ Container p11_blog-myapp-1 Healthy6.5s ✔ Container mysql_container Healthy11.0s ✔ Container p11_blog-web-1 Started13.0s root@iZ2ze8ve39i30yl0dhbqneZ:~/docker_stu/docker_compose/p11_blog# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bf059297e184 nginx:latest"/docker-entrypoint.…"48seconds ago Up37seconds0.0.0.0:8080->80/tcp,[::]:8080->80/tcp p11_blog-web-1 82746d8b74d1 openjdk:17"java -jar /app/dock…"48seconds ago Up48seconds(healthy)p11_blog-myapp-1 a69b1ac6de7d mysql:5.7"docker-entrypoint.s…"48seconds ago Up48seconds(healthy)3306/tcp,33060/tcp mysql_container

查看地址:公网IP:8080
成功回显数据:

查看网络创建情况:

dockernetworkls|grepp11 1de554ab3031 p11_blog_mybridge_network bridgelocaldockercompose down[+]Running4/4 ✔ Container p11_blog-web-1 Removed1.3s ✔ Container mysql_container Removed4.6s ✔ Container p11_blog-myapp-1 Removed1.3s ✔ Network p11_blog_mybridge_network Removed0.3s root@iZ2ze8ve39i30yl0dhbqneZ:~/docker_stu/docker_compose/p11_blog# docker network ls |grep p11 #停止并且删除容器后,再次查看,网络也已经被删除了

end
http://www.jsqmd.com/news/494380/

相关文章:

  • Kimi-VL-A3B-Thinking镜像免配置优势:预编译vLLM、预下载模型权重、开箱即用
  • 七天速刷面试-day01
  • 2026年热门的南京摄影品牌推荐:南京商业摄影/南京食品摄影精选公司 - 品牌宣传支持者
  • QWEN-AUDIO实战案例:跨境电商多语种商品介绍语音批量生成
  • 如果 AI 能读懂并调用 LabVIEW,自动化系统会发生什么?
  • OpenClaw 超级 AI 实战专栏【数据与数据集】(一)高质量数据集:从哪找、怎么选、格式要求
  • Pi0 VLA仿真闭环:Web终端+Isaac Sim/Gazebo构建端到端训练验证环境
  • 1.1 模型量化简介:从动机、对象到主流方法全景
  • centos7系统安装教程
  • 2026携程酒店数据抓取
  • 2.1 模型剪枝(Model Pruning)
  • Ultrascale+ XDMA 从零开始搭建PCIE通信
  • 寻音捉影·侠客行精彩案例:某省级电视台用其日均处理300+小时新闻素材
  • 20260311 文本编辑器
  • 2026年靠谱的凸轮式自动车床工厂推荐:自动车床送料机实力厂家推荐 - 品牌宣传支持者
  • 自助游泳馆管理系统 vue3
  • 【一点浅思】Transformer架构是否已经触及性能天花板?未来架构突破的方向在哪里?
  • 零基础也能懂!OpenClaw 2026.3.8 (原Clawdbot)最全安装
  • SQL大师之路 02 MySQL架构介绍
  • 条码管理系统+WMS:物料入库扫码即建档,库存盘点1小时完成
  • C语言、结构体
  • Claude code底层实现原理(内存管理与并发)
  • C语言、自定义类型:联合体、枚举
  • DeepSeek LeetCode 699. 掉落的方块 public List<Integer> fallingSquares(int[][] positions)
  • GraphRAG开源生态全景:6大主流开源项目,微软/蚂蚁/港大项目同台PK
  • 软件综合项目笔记
  • 2026 最新解读:AI 在数字资产管理中的 5 大应用场景与实践路径
  • DeepSeek LeetCode 710. 黑名单中的随机数 public Solution(int n, int[] blacklist) Java实现
  • 个人笔记机器学习2
  • 70.爬楼梯