Docker Compose 部署 Spring Boot 项目
Docker Compose 是部署 Spring Boot 项目的理想工具,它可以通过一个简单的 YAML 文件定义和运行多容器应用。下面我将详细介绍如何使用 Docker Compose 部署 Spring Boot 项目,包括基础配置、开发与生产环境优化以及常见问题解决方案。
1. 项目准备与基础配置
1.1 项目打包
首先确保你的 Spring Boot 项目已经正确打包成可执行的 JAR 文件。可以使用 Maven 命令:
bash
mvn clean package -DskipTests
这将在target
目录下生成一个your-project-0.0.1-SNAPSHOT.jar
文件。
1.2 创建 Dockerfile
在项目根目录创建Dockerfile
,建议使用多阶段构建优化镜像大小:
dockerfile
# 构建阶段
FROM maven:3.8.6-jdk-11 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src /app/src
RUN mvn package -DskipTests
# 生产阶段
FROM openjdk:11-jre-slim
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
# 解决时区问题
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
这个 Dockerfile 使用了多阶段构建,第一阶段用 Maven 环境构建项目,第二阶段用轻量级的 JRE 运行环境。
2. Docker Compose 配置
2.1 基础 docker-compose.yml
在项目根目录创建docker-compose.yml
文件:
yaml
version: "3.8"
services:
app:
build: .
container_name: spring-boot-app
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- TZ=Asia/Shanghai
restart: unless-stopped
networks:
- app-network
networks:
app-network:
driver: bridge
这个配置定义了一个服务app
,它会构建当前目录下的 Dockerfile,将容器的 8080 端口映射到主机的 8080 端口。
2.2 启动项目
运行以下命令构建并启动容器:
bash
docker-compose up --build -d
--build
参数确保每次都会重新构建镜像,-d
参数让容器在后台运行。
3. 高级配置选项
3.1 添加数据库服务
在docker-compose.yml
中添加 MySQL 数据库服务:
yaml
services:
app:
# ...原有配置
depends_on:
- db
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/mydb?useSSL=false&serverTimezone=Asia/Shanghai
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root123
db:
image: mysql:8.0
container_name: mysql-db
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: mydb
TZ: Asia/Shanghai
ports:
- "3306:3306"
volumes:
- db-data:/var/lib/mysql
networks:
- app-network
volumes:
db-data:
这样 Spring Boot 应用可以通过服务名db
访问 MySQL 数据库。
3.2 添加 Redis 缓存服务
yaml
services:
app:
# ...原有配置
depends_on:
- db
- redis
environment:
SPRING_REDIS_HOST: redis
SPRING_REDIS_PORT: 6379
redis:
image: redis:alpine
container_name: redis-cache
ports:
- "6379:6379"
volumes:
- redis-data:/data
networks:
- app-network
volumes:
redis-data:
3.3 开发环境配置
对于开发环境,可以配置热部署:
yaml
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "8080:8080"
- "5005:5005" # 远程调试端口
volumes:
- ./src:/app/src
environment:
- SPRING_PROFILES_ACTIVE=dev
- SPRING_DEVTOOLS_RESTART_ENABLED=true
对应的Dockerfile.dev
:
dockerfile
FROM maven:3.8.6-jdk-11
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src /app/src
CMD ["mvn", "spring-boot:run"]
4. 生产环境优化
4.1 使用更小的基础镜像
dockerfile
FROM eclipse-temurin:11-jre-alpine
4.2 添加健康检查
yaml
services:
app:
# ...其他配置
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
4.3 资源限制
yaml
services:
app:
# ...其他配置
deploy:
resources:
limits:
cpus: "0.5"
memory: 512M
5. 常见问题与解决方案
时区问题:
- 在 Dockerfile 中添加时区设置:
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
- 在 Dockerfile 中添加时区设置:
数据库连接失败:
- 确保
depends_on
配置正确,并且应用有重连机制 - 检查数据库 URL 中的服务名称是否与 docker-compose 中一致
- 确保
端口冲突:
- 修改
docker-compose.yml
中的端口映射:"8081:8080"
- 修改
构建速度慢:
- 使用
.dockerignore
文件排除不必要的文件 - 分阶段复制文件,先复制
pom.xml
安装依赖
- 使用
6. 完整生产环境示例
docker-compose.prod.yml:
yaml
version: "3.8"
services:
app:
build:
context: .
dockerfile: Dockerfile.prod
image: my-spring-app:latest
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
- SPRING_DATASOURCE_URL=jdbc:mysql://db:3306/mydb
- SPRING_DATASOURCE_USERNAME=root
- SPRING_DATASOURCE_PASSWORD=root123
- SPRING_REDIS_HOST=redis
depends_on:
- db
- redis
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
timeout: 10s
retries: 3
deploy:
resources:
limits:
cpus: "0.5"
memory: 512M
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: mydb
TZ: Asia/Shanghai
volumes:
- db-data:/var/lib/mysql
command: --default-authentication-plugin=mysql_native_password
redis:
image: redis:alpine
volumes:
- redis-data:/data
volumes:
db-data:
redis-data:
Dockerfile.prod:
dockerfile
# 构建阶段
FROM maven:3.8.6-jdk-11 AS builder
WORKDIR /app
COPY pom.xml .
RUN mvn dependency:go-offline
COPY src /app/src
RUN mvn package -DskipTests
# 生产阶段
FROM eclipse-temurin:11-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
通过以上配置,你可以轻松地使用 Docker Compose 部署 Spring Boot 项目到生产环境。根据你的具体需求,可以调整配置中的参数和选项。