Docker容器化部署实战:Spring Boot + MySQL + Nginx 一键部署完整指南

发布于:2025-06-23 ⋅ 阅读:(12) ⋅ 点赞:(0)

📖 前言

容器化技术已经成为现代软件部署的标准实践。作为一名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: false

spring:
  application:
    name: my-spring-app
  
  # 数据库配置(容器环境)
  datasource:
    url: jdbc:mysql://mysql:3306/app_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
    username: ${
   DB_USERNAME:root}
    password: ${
   DB_PASSWORD:123456}
    driver-class-name: com.mysql.cj.jdbc.Driver
    
    # 连接池配置
    hikari:
      minimum-idle: 5
      maximum-pool-size: 20
      idle-timeout: 300000
      connection-timeout: 20000
      max-lifetime: 1200000
  
  # JPA配置
  jpa:
    hibernate:
      ddl-auto: validate
    show-sql: false
    properties:
      hibernate:
        dialect: org.hibernate.dialect.MySQL8Dialect
        format_sql: false
        # 批量处理优化
        jdbc:
          batch_size: 20
        order_inserts: true
        order_updates: true
  
  # Redis配置(如果需要)
  redis:
    host: redis
    port: 6379
    database: 0
    timeout: 3000ms
    lettuce:
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0

# 监控配置
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics,prometheus
  endpoint:
    health:
      show-details: always
  health:
    redis:
      enabled: false

# 日志配置
logging:
  level:
    com.example: INFO
    org.springframework.web: WARN
    org.hibernate.SQL: WARN
  pattern:
    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.log
    max-size: 100MB
    max-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 

网站公告

今日签到

点亮在社区的每一天
去签到