SpringBoot应用容器化部署全流程指南
本文提供完整的SpringBoot应用Docker容器化实战指南,涵盖从基础概念到生产环境部署的全流程。通过详细的代码示例和最佳实践,帮助开发者彻底解决环境不一致问题,构建可靠、可扩展的容器化应用。
·
概述
本文提供完整的SpringBoot应用Docker容器化实战指南,涵盖从基础概念到生产环境部署的全流程。通过详细的代码示例和最佳实践,帮助开发者彻底解决环境不一致问题,构建可靠、可扩展的容器化应用。
环境准备与Docker安装
系统环境检查
在开始容器化之前,需要确保系统满足Docker运行的基本要求:
bash
#!/bin/bash
# docker_environment_check.sh - 环境检查脚本
set -euo pipefail
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m'
echo -e "${BLUE}=== Docker环境检查开始 ===${NC}"
# 操作系统检查
echo -e "\n${GREEN}1. 操作系统检查${NC}"
if [ -f /etc/os-release ]; then
source /etc/os-release
echo -e " 操作系统: $NAME $VERSION"
echo -e " 内核版本: $(uname -r)"
else
echo -e " ${YELLOW}警告: 无法确定操作系统类型${NC}"
fi
# 系统架构检查
echo -e "\n${GREEN}2. 系统架构检查${NC}"
ARCH=$(uname -m)
echo -e " 系统架构: $ARCH"
# 资源检查
echo -e "\n${GREEN}3. 系统资源检查${NC}"
MEM_TOTAL=$(free -h | awk 'NR==2{print $2}')
MEM_AVAILABLE=$(free -h | awk 'NR==2{print $7}')
echo -e " 总内存: $MEM_TOTAL"
echo -e " 可用内存: $MEM_AVAILABLE"
DISK_SPACE=$(df -h / | awk 'NR==2{print $4}')
echo -e " 根分区可用空间: $DISK_SPACE"
# Docker环境检查
echo -e "\n${GREEN}4. Docker环境检查${NC}"
check_docker_environment() {
if command -v docker &> /dev/null; then
DOCKER_VERSION=$(docker --version | cut -d' ' -f3 | tr -d ',')
echo -e " ✅ Docker已安装: $DOCKER_VERSION"
if systemctl is-active --quiet docker; then
echo -e " ✅ Docker服务运行正常"
else
echo -e " ${YELLOW}⚠️ Docker服务未运行${NC}"
fi
else
echo -e " ${RED}❌ Docker未安装${NC}"
fi
if command -v docker-compose &> /dev/null; then
DOCKER_COMPOSE_VERSION=$(docker-compose --version | cut -d' ' -f3 | tr -d ',')
echo -e " ✅ Docker Compose已安装: $DOCKER_COMPOSE_VERSION"
else
echo -e " ${YELLOW}⚠️ Docker Compose未安装${NC}"
fi
}
check_docker_environment
echo -e "\n${BLUE}=== 环境检查完成 ===${NC}"
Docker自动化安装
提供跨平台的Docker安装脚本:
bash
#!/bin/bash
# install_docker.sh - Docker自动化安装脚本
set -euo pipefail
# 日志和颜色配置
GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'
log() {
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')] $1${NC}"
}
error_exit() {
echo -e "${RED}错误: $1${NC}" >&2
exit 1
}
# 操作系统检测
detect_os() {
if [ -f /etc/os-release ]; then
source /etc/os-release
OS=$ID
VERSION=$VERSION_ID
else
error_exit "无法检测操作系统"
fi
}
# Docker安装主函数
install_docker() {
log "开始安装Docker..."
case $OS in
ubuntu|debian)
install_docker_debian
;;
centos|rhel|fedora)
install_docker_centos
;;
*)
error_exit "不支持的操作系统: $OS"
;;
esac
}
# Ubuntu/Debian安装
install_docker_debian() {
log "在Debian系系统上安装Docker..."
# 清理旧版本
sudo apt-get remove -y docker docker-engine docker.io containerd runc || true
# 安装依赖
sudo apt-get update
sudo apt-get install -y \
apt-transport-https \
ca-certificates \
curl \
gnupg \
lsb-release
# 配置Docker仓库
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Docker引擎
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
log "Docker安装完成"
}
# Docker Compose安装
install_docker_compose() {
log "安装Docker Compose..."
COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
sudo curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" \
-o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -sf /usr/local/bin/docker-compose /usr/bin/docker-compose
log "Docker Compose ${COMPOSE_VERSION} 安装完成"
}
# Docker服务配置
configure_docker() {
log "配置Docker服务..."
sudo systemctl enable docker
sudo systemctl start docker
# 用户权限配置
sudo usermod -aG docker $USER
# 镜像加速器配置
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json > /dev/null << EOF
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com"
],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m",
"max-file": "3"
}
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
log "Docker配置完成"
}
# 安装验证
verify_installation() {
log "验证安装结果..."
if docker --version && docker-compose --version; then
log "✅ Docker环境安装成功"
# 运行测试容器
if docker run --rm hello-world; then
log "✅ Docker运行测试通过"
else
error_exit "Docker运行测试失败"
fi
else
error_exit "Docker安装验证失败"
fi
}
main() {
log "开始Docker自动化安装流程"
detect_os
install_docker
install_docker_compose
configure_docker
verify_installation
log "🎉 Docker安装全部完成!"
log "请重新登录或执行 'newgrp docker' 使组权限生效"
}
main "$@"
SpringBoot应用容器化实战
示例应用开发
创建完整的SpringBoot演示应用:
java
// DemoApplication.java - 主应用类
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
@RestController
class HealthController {
@GetMapping("/health")
public Map<String, Object> health() {
Map<String, Object> healthInfo = new HashMap<>();
healthInfo.put("status", "UP");
healthInfo.put("timestamp", LocalDateTime.now().toString());
healthInfo.put("service", "SpringBoot Docker Demo");
return healthInfo;
}
@GetMapping("/info")
public Map<String, Object> info() {
Map<String, Object> info = new HashMap<>();
info.put("java.version", System.getProperty("java.version"));
info.put("os.name", System.getProperty("os.name"));
info.put("availableProcessors", Runtime.getRuntime().availableProcessors());
info.put("maxMemory", Runtime.getRuntime().maxMemory() / (1024 * 1024) + " MB");
return info;
}
}
应用配置
properties
# application.properties
spring.application.name=springboot-docker-demo
server.port=8080
# 监控端点配置
management.endpoint.health.enabled=true
management.endpoints.web.exposure.include=health,info,metrics
# 日志配置
logging.level.com.example.demo=INFO
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n
Maven构建配置
xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>springboot-docker-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
</parent>
<properties>
<java.version>11</java.version>
<docker.image.prefix>springboot-demo</docker.image.prefix>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Docker容器化配置
生产级Dockerfile
dockerfile
# 多阶段构建Dockerfile
FROM maven:3.8.6-openjdk-11 AS builder
WORKDIR /app
COPY pom.xml .
# 利用Docker缓存层加速构建
RUN mvn dependency:go-offline -B
COPY src ./src
RUN mvn clean package -DskipTests
# 运行阶段
FROM openjdk:11-jre-slim
# 安全配置:使用非root用户
RUN groupadd -r springboot && useradd -r -g springboot springboot
# 时区配置
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
WORKDIR /app
COPY --from=builder --chown=springboot:springboot /app/target/*.jar app.jar
COPY --chown=springboot:springboot health-check.sh .
USER springboot
# JVM优化参数
ENV JAVA_OPTS="-Xms512m -Xmx1024m -XX:+UseG1GC -XX:MaxGCPauseMillis=200"
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s --retries=3 \
CMD ./health-check.sh
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar app.jar"]
健康检查脚本
bash
#!/bin/bash
# health-check.sh
set -e
HEALTH_URL="http://localhost:8080/health"
TIMEOUT=5
response=$(curl -s -o /dev/null -w "%{http_code}" --max-time $TIMEOUT $HEALTH_URL || echo "000")
if [ "$response" = "200" ]; then
echo "Health check: OK"
exit 0
else
echo "Health check: FAILED (HTTP $response)"
exit 1
fi
自动化构建与部署
CI/CD构建脚本
bash
#!/bin/bash
# build_and_deploy.sh
set -euo pipefail
# 配置变量
APP_NAME="springboot-docker-demo"
VERSION="1.0.0"
REGISTRY="localhost:5000"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# 构建应用
build_application() {
log "构建SpringBoot应用..."
mvn clean package -DskipTests
}
# 构建Docker镜像
build_docker_image() {
log "构建Docker镜像..."
local image_tag="$APP_NAME:$VERSION"
docker build -t "$image_tag" .
log "✅ 镜像构建成功: $image_tag"
}
# 运行测试
run_tests() {
log "运行容器测试..."
local test_container="${APP_NAME}-test"
local image_tag="$APP_NAME:$VERSION"
docker run -d --name "$test_container" -p 8081:8080 "$image_tag"
sleep 30
# 健康检查测试
local health_response=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8081/health)
if [ "$health_response" = "200" ]; then
log "✅ 健康检查通过"
else
docker logs "$test_container"
error_exit "健康检查失败"
fi
docker stop "$test_container"
docker rm "$test_container"
}
# 部署到环境
deploy_environment() {
local environment=$1
log "部署到 $environment 环境..."
case $environment in
dev)
docker run -d --name "${APP_NAME}-dev" -p 8080:8080 "$APP_NAME:$VERSION"
;;
prod)
docker-compose -f docker-compose.prod.yml up -d
;;
esac
}
main() {
local environment=${1:-dev}
log "开始应用部署流程..."
build_application
build_docker_image
run_tests
deploy_environment $environment
log "🎉 应用部署完成!"
}
main "$@"
Docker Compose编排
开发环境配置
yaml
# docker-compose.dev.yml
version: '3.8'
services:
app:
build: .
image: springboot-docker-demo:dev
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=dev
- JAVA_OPTS=-Xms256m -Xmx512m
networks:
- app-network
mysql:
image: mysql:8.0
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=app_db
ports:
- "3306:3306"
networks:
- app-network
networks:
app-network:
driver: bridge
生产环境配置
yaml
# docker-compose.prod.yml
version: '3.8'
services:
app:
image: springboot-docker-demo:${VERSION:-latest}
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- JAVA_OPTS=-Xms512m -Xmx1024m
deploy:
resources:
limits:
memory: 1G
cpus: '1.0'
healthcheck:
test: ["CMD", "./health-check.sh"]
interval: 30s
timeout: 10s
retries: 3
nginx:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- app
监控与运维
应用监控配置
yaml
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'springboot-app'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['app:8080']
日志管理
bash
#!/bin/bash
# log_manager.sh
view_logs() {
docker logs -f springboot-app
}
export_logs() {
local timestamp=$(date +%Y%m%d_%H%M%S)
docker logs springboot-app > "logs/app_${timestamp}.log"
}
analyze_logs() {
docker logs springboot-app | grep "ERROR" | head -20
}
case "${1:-help}" in
view)
view_logs
;;
export)
export_logs
;;
analyze)
analyze_logs
;;
*)
echo "用法: $0 {view|export|analyze}"
;;
esac
安全加固配置
安全增强Dockerfile
dockerfile
FROM openjdk:11-jre-slim # 安全更新 RUN apt-get update && apt-get upgrade -y && apt-get clean # 非特权用户 RUN groupadd -r appuser && useradd -r -g appuser appuser USER appuser WORKDIR /app COPY --chown=appuser:appuser app.jar . EXPOSE 8080 ENTRYPOINT ["java", "-jar", "app.jar"]
部署架构总结
通过本指南,您将掌握:
核心能力
-
环境标准化 - 一致的开发、测试、生产环境
-
自动化流程 - 完整的CI/CD流水线
-
生产就绪 - 监控、日志、安全加固
-
最佳实践 - 遵循Docker和SpringBoot规范
关键特性
-
✅ 持续集成自动化
-
✅ 多阶段构建优化
-
✅ 健康检查机制
-
✅ 资源限制配置
-
✅ 安全最佳实践
后续步骤
-
配置完整的CI/CD流水线
-
实施容器安全扫描
-
配置自动扩缩容
-
建立监控告警体系
现在您可以 confidently 将SpringBoot应用容器化,享受Docker带来的环境一致性和部署便利性!
更多推荐
所有评论(0)