주의사항

Docker Hub의 최신버전 MySQL은 9.x 버전이다.

그런데 현재 24.8.25일 기준 최신 스프링부트 버전인 3.3.3은 MySQL 9.x 버전을 지원하지 않는다.

따라서 MySQL의 모든 버전은 8.0.32 버전으로 맞추었다.

 

스프링부트 설정

build.gradle

dependencies {
...
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation 'mysql:mysql-connector-java:8.0.32'
}

 

 

application.properties

spring.datasource.url=jdbc:mysql://my-db:3306/mydb
spring.datasource.username=root
spring.datasource.password=00000000
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

spring.data.redis.host=my-cache-server
spring.data.redis.port=6379

 

RedisConfig

@Configuration
public class RedisConfig {

  @Bean
  public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
    RedisTemplate<String, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(connectionFactory);
    template.setKeySerializer(new StringRedisSerializer());
    template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    return template;
  }
}

 

AppController

@RestController
public class AppController {

  @Autowired
  private RedisTemplate<String, Object> redisTemplate;

  @GetMapping("/")
  public String home() {
    redisTemplate.opsForValue().set("abc", "def");
    return "Hello, World!";
  }
}

 

 

Docker Compose 설정

Dockerfile

FROM openjdk:17-jdk

WORKDIR /spring-boot

COPY build/libs/*SNAPSHOT.jar app.jar

ENTRYPOINT ["java", "-jar", "/spring-boot/app.jar"]
  1. FROM openjdk:17-jdk
    -Docker 이미지를 생성할 때 기본으로 사용할 베이스 이미지를 설정하는 명령어이다.
    -이 경우, openjdk:17-jdk 이미지를 사용하여 JDK(Java Development Kit) 17이 설치된 환경에서 애플리케이션을 실행할 수 있도록 한다.
    -OpenJDK는 자바 애플리케이션을 실행하는 데 필요한 런타임 환경을 제공한다.
  2. WORKDIR /spring-boot
    -Docker 컨테이너 내에서 작업 디렉토리를 /spring-boot로 설정한다. 이후의 모든 명령어는 이 디렉토리 내에서 실행된다. 이 디렉토리가 존재하지 않으면 자동으로 생성된다.
  3. COPY build/libs/*SNAPSHOT.jar app.jar
    -호스트 시스템의 build/libs/ 경로에 있는 *SNAPSHOT.jar 파일을 Docker 컨테이너의 /spring-boot/ 디렉토리에 app.jar 파일로 복사한다.
    -build/libs/에 *SNAPSHOT.jar 파일이 존재해야 한다.
  4. ENTRYPOINT ["java", "-jar", "/spring-boot/app.jar"]:
    -Docker 컨테이너가 시작되면 java -jar /spring-boot/app.jar 명령어가 실행된다.
    -이 명령어는 Spring Boot 애플리케이션을 실행시킨다.

 

compose.yml

services:
  my-server:
    build: .
    ports:
      - 8080:8080
    depends_on:
      my-db:
        condition: service_healthy
      my-cache-server:
        condition: service_healthy
  my-db:
    image: mysql:8.0.32
    environment:
      MYSQL_ROOT_PASSWORD: 00000000
      MYSQL_DATABASE: mydb
    volumes:
      - /home/ubuntu/mysql_data:/var/lib/mysql
    ports:
      - 3306:3306
    healthcheck:
      test: [ "CMD", "mysqladmin", "ping" ]
      interval: 5s
      retries: 10
  my-cache-server:
    image: redis
    ports:
      - 6379:6379
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
      interval: 5s
      retries: 10
  1. my-server
    -Spring Boot 애플리케이션을 8080 포트에서 실행한다.
    -depends_on 옵션을 사용해 MySQL 데이터베이스와 Redis 캐시 서버가 먼저 준비된 후에 서버가 실행되도록 설정했다.
    -depends_on에서 condition: service_healthy를 사용해 각 서비스가 정상적으로 준비된 후에 서버가 실행될 수 있도록 보장한다.
  2. my-db (MySQL 데이터베이스)
    -image: mysql로 MySQL 컨테이너를 설정한다. MySQL의 기본 이미지가 사용된다.
    -환경 변수로 MYSQL_ROOT_PASSWORD와 MYSQL_DATABASE를 설정해 MySQL의 root 비밀번호와 데이터베이스 이름을 지정한다.
    -로컬의 ./mysql_data 디렉터리를 컨테이너 내부의 /var/lib/mysql에 마운트하여 데이터가 유지되도록 설정했다.
    -ports 옵션을 사용해 3306 포트를 노출시켜 외부에서 데이터베이스에 접근할 수 있다.
    -healthcheck를 설정해 MySQL 서버가 정상적으로 실행 중인지 확인한다. 5초마다 mysqladmin ping 명령어로 상태를 확인하고, 최대 10번의 시도를 한다.
  3. my-cache-server (Redis 캐시 서버):
    -image: redis로 Redis 캐시 서버를 설정한다.
    -ports 옵션을 통해 6379 포트를 노출시켜 외부에서 Redis에 접근할 수 있다.
    -healthcheck를 설정해 Redis 서버가 정상적으로 실행 중인지 확인한다. 5초마다 redis-cli ping 명령어로 상태를 확인하고, 최대 10번의 시도를 한다.

 

위 설정과 스프링부트의 application.properties 파일을 살펴보면 아래와 같은 그림이 이해가 될 것이다.

spring.datasource.url=jdbc:mysql://my-db:3306/mydb
spring.datasource.username=root
spring.datasource.password=00000000
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect

spring.data.redis.host=my-cache-server
spring.data.redis.port=6379

  • 호스트 컴퓨터: 사용자가 직접 접근하는 주체로, 포트를 통해 각각의 컨테이너와 연결된다.
  • 컨테이너들:
    -my-db: MySQL 데이터베이스 컨테이너로, 3306번 포트를 통해 외부(호스트 컴퓨터)와 연결된다. my-server 컨테이너는 내부적으로 이 데이터베이스와 통신한다.
    -my-server: Spring Boot 서버 애플리케이션이 동작하는 컨테이너로, 8080번 포트를 통해 외부와 통신하며, my-db와 my-cache-server와 내부적으로 연결되어 있다.
    -my-cache-server: Redis 캐시 서버가 동작하는 컨테이너로, 6379번 포트를 통해 호스트와 통신한다. my-server 컨테이너는 내부적으로 이 캐시 서버를 사용한다.

각 컨테이너는 외부로부터 특정 포트를 통해 접근할 수 있으며, 컨테이너들끼리는 내부적으로 연결되어 통신한다. my-server는 Spring Boot 기반 애플리케이션으로서 MySQL 데이터베이스(my-db)와 Redis 캐시 서버(my-cache-server)를 이용해 데이터 처리를 한다.

 

컨테이너 띄우기

  • ./gradlew clean build
  • docker compose up --build -d