Spring Boot/Testing & Deploy/Deploy Spring Boot Application
2/2
~18 phútTesting & Deploy

Deploy Spring Boot Application

Đóng gói JAR, Docker hóa, deploy lên server. Hiểu profiles, externalized configuration và health check.

Từ code đến production

Spring Boot application có thể deploy bằng nhiều cách. Bài này đi từ đơn giản nhất đến production-ready.

Build JAR file

Spring Boot tạo fat JAR (executable JAR) chứa tất cả dependencies:

# Maven
./mvnw clean package -DskipTests

# Gradle
./gradlew bootJar

# Chạy JAR
java -jar target/myapp-0.0.1-SNAPSHOT.jar

ℹ️ Fat JAR vs Thin JAR

Fat JAR chứa tất cả dependencies (~50-100MB). Ưu điểm: deploy đơn giản, chỉ cần JRE. Nhược điểm: file lớn, build chậm.

Spring Profiles

Tách config theo môi trường:

# application.yml — config chung
spring:
  application:
    name: myapp

# application-dev.yml — chỉ cho development
server:
  port: 8080
spring:
  datasource:
    url: jdbc:h2:mem:devdb

# application-prod.yml — chỉ cho production
server:
  port: 80
spring:
  datasource:
    url: jdbc:postgresql://db:5432/myapp

Kích hoạt profile:

# Qua command line
java -jar myapp.jar --spring.profiles.active=prod

# Qua biến môi trường
SPRING_PROFILES_ACTIVE=prod java -jar myapp.jar

Docker hóa Spring Boot

# Multi-stage build
FROM eclipse-temurin:21-jdk-alpine AS build
WORKDIR /app
COPY . .
RUN ./mvnw clean package -DskipTests

FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar

# Non-root user
RUN addgroup -S spring && adduser -S spring -G spring
USER spring

EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
docker build -t myapp .
docker run -p 8080:8080 -e SPRING_PROFILES_ACTIVE=prod myapp

Health Check với Actuator

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
# application.yml
management:
  endpoints:
    web:
      exposure:
        include: health,info,metrics
  endpoint:
    health:
      show-details: when_authorized

Truy cập http://localhost:8080/actuator/health:

{
  "status": "UP",
  "components": {
    "db": { "status": "UP" },
    "diskSpace": { "status": "UP" }
  }
}

Externalized Configuration

Thứ tự ưu tiên config (cao → thấp):

  1. Command line arguments (--server.port=9090)
  2. Environment variables (SERVER_PORT=9090)
  3. application-{profile}.yml
  4. application.yml
  5. Default values trong code
@Configuration
public class AppConfig {
    @Value("${app.upload.max-size:10MB}")  // default 10MB
    private String maxUploadSize;

    @Value("${app.feature.ai-explain:false}")
    private boolean aiExplainEnabled;
}

⚠️ Không hardcode secrets!

Database password, API key KHÔNG BAO GIỜ đặt trong application.yml. Dùng environment variables hoặc secret manager (Vault, AWS Secrets Manager).

Checklist deploy production

  • Build JAR/Docker image thành công
  • Profile prod đã cấu hình đúng
  • Health check endpoint hoạt động
  • Secrets được inject qua env vars
  • Logging level phù hợp (INFO cho prod)
  • CORS, Security headers đã cấu hình
  • Database migration đã chạy