📖 前言

容器化技术已经成为现代软件部署的标准实践。作为一名DevOps工程师,我在过去几年中参与了数十个项目的容器化改造,深刻体会到Docker在提升部署效率、环境一致性和运维便利性方面的巨大价值。

今天我将通过一个完整的实战案例,详细展示如何使用Docker部署一个包含Spring Boot后端、MySQL数据库和Nginx反向代理的完整Web应用,让你从零开始掌握容器化部署的核心技能!

🎯 本文你将学到:

  • Docker容器化的核心概念和最佳实践
  • Dockerfile编写技巧和优化策略
  • docker-compose多容器编排
  • Spring Boot应用的容器化实践
  • MySQL数据库容器化配置
  • Nginx反向代理和负载均衡
  • 生产环境部署和监控方案

🚀 环境准备

系统要求

# 操作系统:Linux/macOS/Windows
- Docker Engine 20.10+
- Docker Compose 2.0+
- 最少 4GB 内存
- 最少 20GB 可用磁盘空间

安装Docker

Linux (Ubuntu/CentOS):

# 安装Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker# 添加当前用户到docker组
sudo usermod -aG docker $USER# 安装docker-compose
sudo curl -L "https://github.com/docker/compose/releases/download/v2.12.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

验证安装:

docker --version
docker-compose --version

🏗️ 项目架构设计

整体架构图

┌─────────────────────────────────────────────┐
│                用户请求                      │
└─────────────────┬───────────────────────────┘│
┌─────────────────▼───────────────────────────┐
│            Nginx (Port 80)                 │
│        • 反向代理                           │
│        • 负载均衡                           │
│        • 静态资源服务                        │
└─────────────────┬───────────────────────────┘│
┌─────────────────▼───────────────────────────┐
│        Spring Boot App (Port 8080)         │
│        • REST API                          │
│        • 业务逻辑处理                        │
│        • 数据库操作                          │
└─────────────────┬───────────────────────────┘│
┌─────────────────▼───────────────────────────┐
│           MySQL (Port 3306)                │
│        • 数据持久化                          │
│        • 数据备份                            │
└─────────────────────────────────────────────┘

容器编排策略

# 服务依赖关系
nginx:depends_on: [app]app:depends_on: [mysql]mysql:# 独立启动

📦 Spring Boot应用容器化

项目结构

my-spring-app/
├── src/
│   └── main/
│       ├── java/
│       └── resources/
│           └── application.yml
├── Dockerfile
├── docker-compose.yml
├── nginx/
│   └── nginx.conf
├── mysql/
│   ├── init.sql
│   └── my.cnf
└── scripts/├── deploy.sh└── backup.sh

优化的Dockerfile

多阶段构建Dockerfile:

# 第一阶段:构建阶段
FROM maven:3.8.6-openjdk-17-slim AS builder# 设置工作目录
WORKDIR /app# 复制Maven配置文件,利用Docker缓存
COPY pom.xml .
COPY src ./src# 构建应用
RUN mvn clean package -DskipTests# 第二阶段:运行阶段
FROM openjdk:17-jre-slim# 创建非root用户
RUN groupadd -r appuser && useradd -r -g appuser appuser# 安装必要的工具
RUN apt-get update && apt-get install -y \curl \jq \&& rm -rf /var/lib/apt/lists/*# 设置工作目录
WORKDIR /app# 从构建阶段复制jar包
COPY --from=builder /app/target/*.jar app.jar# 创建日志目录
RUN mkdir -p /app/logs && chown -R appuser:appuser /app# 切换到非root用户
USER appuser# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \CMD curl -f http://localhost:8080/actuator/health || exit 1# 暴露端口
EXPOSE 8080# JVM优化参数
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:+UseContainerSupport"# 启动应用
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

应用配置优化

application.yml (容器化配置):

server:port: 8080# 关闭Tomcat访问日志(由容器日志管理)tomcat:accesslog:enabled: falsespring:application:name: my-spring-app# 数据库配置(容器环境)datasource:url: jdbc:mysql://mysql:3306/app_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=trueusername: ${DB_USERNAME:root}password: ${DB_PASSWORD:123456}driver-class-name: com.mysql.cj.jdbc.Driver# 连接池配置hikari:minimum-idle: 5maximum-pool-size: 20idle-timeout: 300000connection-timeout: 20000max-lifetime: 1200000# JPA配置jpa:hibernate:ddl-auto: validateshow-sql: falseproperties:hibernate:dialect: org.hibernate.dialect.MySQL8Dialectformat_sql: false# 批量处理优化jdbc:batch_size: 20order_inserts: trueorder_updates: true# Redis配置(如果需要)redis:host: redisport: 6379database: 0timeout: 3000mslettuce:pool:max-active: 8max-idle: 8min-idle: 0# 监控配置
management:endpoints:web:exposure:include: health,info,metrics,prometheusendpoint:health:show-details: alwayshealth:redis:enabled: false# 日志配置
logging:level:com.example: INFOorg.springframework.web: WARNorg.hibernate.SQL: WARNpattern:console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"file: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"file:name: /app/logs/application.logmax-size: 100MBmax-history: 30

🗄️ MySQL数据库容器化

MySQL配置文件

mysql/my.cnf:

[mysqld]
# 基本配置
user = mysql
default-storage-engine = InnoDB
socket = /var/lib/mysql/mysql.sock
pid-file = /var/lib/mysql/mysql.pid# 字符集配置
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
init_connect = 'SET NAMES utf8mb4'# 连接配置
max_connections = 200
max_connect_errors = 6000
open_files_limit = 65535
table_open_cache = 128
max_allowed_packet = 64M
binlog_cache_size = 1M
max_heap_table_size = 8M
tmp_table_size = 16M# 查询缓存配置
query_cache_size = 8M
query_cache_type = 1
query_cache_limit = 2M# InnoDB配置
innodb_additional_mem_pool_size = 4M
innodb_buffer_pool_size = 256M
innodb_data_file_path = ibdata1:10M:autoextend
innodb_write_io_threads = 4
innodb_read_io_threads = 4
innodb_thread_concurrency = 0
innodb_purge_threads = 1
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 2M
innodb_log_file_size = 32M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120# 慢查询日志
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/mysql-slow.log
long_query_time = 3# 二进制日志
log-bin = mysql-bin
binlog_format = mixed
expire_logs_days = 7[mysql]
default-character-set = utf8mb4[client]
default-character-set = utf8mb4

数据库初始化脚本

mysql/init.sql:

-- 创建应用数据库
CREATE DATABASE IF NOT EXISTS app_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;-- 创建应用用户
CREATE USER IF NOT EXISTS 'app_user'@'%' IDENTIFIED BY 'app_password_2024!';
GRANT ALL PRIVILEGES ON app_db.* TO 'app_user'@'%';
FLUSH PRIVILEGES;-- 使用应用数据库
USE app_db;-- 创建用户表
CREATE TABLE IF 

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分布式选举算法<一> Bully算法

分布式选举算法详解:Bully算法 引言 在分布式系统中,节点故障是不可避免的。当主节点(Leader)发生故障时,系统需要快速选举出新的主节点来保证服务的连续性。Bully算法是一种经典的分布式选举算法,以其简…

高效调试 AI 大模型 API:用 Apipost 实现 SSE 流式解析与可视化

借助 AI 大模型的实时接口(如 OpenAI GPT 或其他第三方模型 API),开发者可以通过 SSE(Server-Sent Events)流式处理数据,实时获取模型的逐步输出。这一技术已广泛应用于实时问答、代码生成等领域。本文将基…

【网络产品经营】园区网络

园区网络的产品经营逻辑发生显著变化,从传统的“连接功能”导向转向“业务体验驱动”,并结合行业场景化需求、技术架构革新及智能化能力提升,形成多维度的产品策略升级。 一、技术架构变革:从多层复杂到极简全光 传统架构的瓶颈与…

EasyExcel 4.X 读写数据

文章目录 EasyExcel与SpringBoot集成读数据读取数据的流程定义实体类简单读取自定义监听器 读取指定sheet和所有sheet多行头读取数据格式转换列表数据实体类自定义转换器自定义监听器数据读取 写数据简单数据写出存储到磁盘返回前端下载 写出指定列宽,和数值精度丢失…

JVM内存管理<一>:Java内存异常问题排查

一、 内存溢出问题的排查 1. 使用工具 - jdk自带 jmapvisualvm 2. 流程 堆转储: (1) 方法一:程序运行时,采用:jmap -dump:formatb,filed:\\data\\xxlJob.hprof 23300 进行堆文件的转储 (2) 方法二:在内存溢出的时候…

Android中Glide.with().load().into() 应付面试源码解析

1. with(this):生命周期绑定 Glide.with(Activity/Fragment/Context) 核心机制:创建与 UI 生命周期绑定的 RequestManager 底层实现: 通过 RequestManagerRetriever 获取单例 非 Application 上下文: 向 Activity/Fragment 添加…

#### es相关内容的索引 ####

倒排索引 结构 #### es倒排索引的结构 ####-CSDN博客 向量索引 结构应用 #### es向量检索 的 结构及应用_es 向量 文本检索-CSDN博客 ann算法 ann算法的种类有哪些,之间的区别,各自的适用场景-CSDN博客 地理信息索引 es地理信息索引的类型以及geo_po…

小飞电视:智能电视与移动设备的娱乐新选择

在数字娱乐时代,人们对于影视内容的需求日益增长,不仅追求丰富多样的节目选择,还希望获得便捷、个性化的观看体验。小飞电视正是这样一款专为智能电视和移动设备设计的视频娱乐应用,它凭借海量的影视资源、高清流畅的播放效果以及…

删除node并且重装然后重装vue

参考第一篇文章 node.js卸载与安装超详细教程_node卸载重装-CSDN博客 第二篇文章安装vue Vue安装与配置教程(非常详细)_安装vue-CSDN博客

基于YOLOv10算法的交通信号灯检测与识别

目录 一.🦁 写在前面1.1 实现模块划分1.2 优化与实时性支持 二.🦁 相关技术与理论基础2.1 各版本yolo对比2.2 YOLOv10网络结构 三.🦁 结果分析3.1 训练损失与验证损失分析3.2 精确率(Precision)、召回率(Re…

洪水风险图制作全流程:HEC-RAS 与 ArcGIS 的耦合应用

技术点目录 一、HER-RAS理论二、一维数学模型基本地形导入三、恒定流、非恒定流一维数学模型水流计算四、一维数学模型计算结果分析五、一维数学模型增设构筑物六、二维河道水动力模拟七、HEC-RAS在溃坝模型中的应用八、HEC-RAS在洪水风险图中的应用了解更多 —————————…

视觉大语言模型未能充分利用视觉表征

视觉大语言模型未能充分利用视觉表征 FesianXu 20250612 at Wechat Search Team 前言 这两天看到一篇新挂在arxiv上的文章 [1],讨论了下视觉大语言模型的视觉表征退化问题。先前的研究将VLM缺陷归咎于视觉编码器薄弱,并提出集成编码器方案以弥补不足&am…

SSRF3 任意文件读取

一.任意文件读取 http://192.168.112.12/pikachu-master/vul/ssrf/ssrf_curl.php?urlfile:///etc/passwd 读取文件使用 file://文件路径即可,这里我们换协议为file,然后从根目录开始读取。 /etc/passwd 我们这样修改完url路径后查看结果可以看到文件内…

洛谷P3953 [NOIP 2017 提高组] 逛公园

洛谷P3953 [NOIP 2017 提高组] 逛公园 洛谷题目传送门 题目背景 NOIP2017 D1T3 题目描述 策策同学特别喜欢逛公园。公园可以看成一张 N N N 个点 M M M 条边构成的有向图,且没有 自环和重边。其中 1 1 1 号点是公园的入口, N N N 号点是公园的出…

Vue3+TypeScript+Element Plus 表格展开行优化方案

在 Vue3 TypeScript Element Plus 项目中优化表格展开行的内存使用,主要从 渲染优化、数据管理 和 内存回收 三方面入手。以下是最佳实践和完整解决方案: 1. 懒加载展开内容(核心优化) 只当行展开时才渲染内容,避免…

OpenCV——直方图与匹配

直方图与匹配 一、直方图简介二、直方图统计三、直方图比较四、直方图均衡化五、自适应的直方图均衡化六、直方图反向投影七、模板匹配 一、直方图简介 图像直方图(Histogram)是一种频率分布图,它描述了不同强度值在图像中出现的频率。图像直…

通义大模型在文档自动化处理中的高效部署指南(OCR集成与批量处理优化)

1. 传统OCR解决方案常面临识别精度低、版面分析能力弱、处理效率瓶颈等问题。通义大模型凭借其多模态理解和生成能力,为文档处理领域带来革命性突破。本文将深入探讨如何高效部署通义大模型实现端到端的文档自动化处理,特别聚焦OCR集成与批量处理优化两…

Ubuntu20.04通过ssh协议配置远程终端

一、在目标计算机(即被连接的计算机)上操作: 1、安装 OpenSSH 服务器: sudo apt update sudo apt install openssh-server3、启动并设置 SSH 服务开机自启: sudo systemctl enable --now ssh二、在源计算机&#xf…

《HTTP权威指南》 第7章 缓存

带着问题学习: 缓存如何提高性能如何衡量缓存的有效性缓存置于何处作用最大HTTP如何保持缓存副本的新鲜度缓存如何与其他缓存及服务器通信 web缓存是可以自动保存常见文档副本的HTTP设备。 缓存优点 减少冗余的数据传输,节省网络费用缓解网络瓶颈问题&…

第十三章 模板

函数模板 函数模板使用 函数模板注意事项 自动类型推导,必须推导出一致的数据类型T,才可以使用 模板必须要确定出T的数据类型,才可以使用 普通函数和函数模板的类型转化 普通函数隐式类型转化(char转int) 函数模板正常使用不会发生…