[Docker] - SpringBoot + Redis λ„μš°κΈ°

πŸ› οΈ 개발 ν™˜κ²½

🎨 IDE : Intellij Ultimate

πŸƒ Spring : Spring Boot 3.1.3

πŸ› οΈ Java : Amazon corretto 17

🐳 Docker : 23.0.1

πŸ’» OS : M1 macOS Ventura 13.5.1

πŸ“” μ˜μ‘΄μ„±

SpringBoot λ‚΄λΆ€μ—μ„œ Redisλ₯Ό μ‚¬μš©ν•΄μ•Όν•˜κΈ° λ•Œλ¬Έμ— μ•„λž˜ 라이브러리λ₯Ό μΆ”κ°€ν•΄μ€€λ‹€.

implementation 'org.springframework.boot:spring-boot-starter-data-redis'

βš™οΈ μ„€μ •

둜컬 ν™˜κ²½μ—μ„œ Redisλ₯Ό μ‹€ν–‰ν•˜λ €λ©΄, hostλ₯Ό localhost둜 μ„€μ •ν•˜λ©΄ λœλ‹€.

단, jar 파일둜 λΉŒλ“œν•  λ•ŒλŠ” κΌ­ redis둜 λ³€κ²½ν•΄μ€˜μ•Ό ν•œλ‹€!

# application.yaml
spring:
  redis:
    data:
      host: redis
      port: 6379

μ•„λž˜ μ½”λ“œμ™€ 같이 Springμ—μ„œ μ‚¬μš©ν•  Redis 정보λ₯Ό μ„€μ •ν•΄μ€€λ‹€.

@Configuration
public class RedisConfig {
    @Value("${spring.redis.data.host}")
    private String host;

    @Value("${spring.redis.data.port}")
    private int port;

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(host, port);
    }

    @Bean
    public RedisTemplate<?, ?> redisTemplate() {
        RedisTemplate<?, ?> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }
}

λ§Œμ•½ Springμ—μ„œ JPA와 같은 λ¬Έλ²•μœΌλ‘œ Redis에 μ ‘κ·Όν•˜λ €λ©΄ μ•„λž˜μ™€ 같이 ꡬ성해주면 λœλ‹€.

@RedisHash의 속성을 μ΄μš©ν•˜λ©΄ κ΅¬λΆ„ν•˜κΈ°λ„ 쉽고, 생λͺ… 주기도 관리할 수 μžˆλ‹€.

...
@RedisHash(value = "area", timeToLive = 30)
public class Area {

    @Id
    private Location location;

    private final List<Festival> festivalList;

}

valueλ₯Ό μ§€μ •ν•˜λ©΄, Redis의 데이터가 λ“€μ–΄κ°ˆ λ•Œ, keyspace에 prefixλ₯Ό 지정할 수 있게 λœλ‹€. 즉, enum νƒ€μž…μ˜ location의 값이 OSAKA일 경우 area:OSAKAλΌλŠ” κ°’μœΌλ‘œ μ €μž₯λœλ‹€.

ν•΄λ‹Ή λ°μ΄ν„°μ˜ 생λͺ… μ£ΌκΈ°λ₯Ό μ§€μ •ν•˜λ €λ©΄ timeToLive 속성을 μΆ”κ°€λ‘œ μ£Όλ©΄ λœλ‹€.

λ˜ν•œ, μ•„λž˜μ™€ 같이 CrudRepositoryλ₯Ό 상속 λ°›μœΌλ©΄, Redisλ₯Ό JPA와 λ™μΌν•˜κ²Œ μ‚¬μš©ν•  수 μžˆλ‹€.

public interface AreaRepository extends CrudRepository<Area, Location> {

}

μ΄ν›„μ—λŠ” ν‰μ†Œ JPAλ₯Ό μ΄μš©ν•œ 개발과 λ™μΌν•˜κ²Œ ν•˜λ©΄ λœλ‹€.

🐳 도컀

Dockerfile

ν”„λ‘œμ νŠΈ μ΅œμƒμœ„μ— Dockerfile을 μƒμ„±ν•˜κ³ , μ•„λž˜μ™€ 같이 λ„£μ–΄μ€€λ‹€.

# μžλ°” 버전은 본인 ν”„λ‘œμ νŠΈ μžλ°” 버전과 λ§žμΆ°μ€€λ‹€.
FROM openjdk:17-oracle
COPY build/libs/{project-name}-0.0.1-SNAPSHOT.jar {build-name}.jar
EXPOSE 8080
ENTRYPOINT exec java -jar {build-name}.jar

{project-name} : build/libs/ κ²½λ‘œμ— μžˆλŠ” jar 파일 이름

{build-name} : docker에 배포할 μƒˆλ‘œμš΄ 파일 이름

# μ˜ˆμ‹œ
FROM openjdk:17-oracle
COPY build/libs/test-project-0.0.1-SNAPSHOT.jar test.jar
EXPOSE 8080
ENTRYPOINT exec java -jar test.jar

docker-compose.yml

Dockerfileκ³Ό λ™μΌν•˜κ²Œ ν”„λ‘œμ νŠΈ μ΅œμƒμœ„μ— docker-compose.yml을 μƒμ„±ν•˜κ³ , μ•„λž˜μ™€ 같이 λ„£μ–΄μ€€λ‹€.

version: '3.4'

services:
  redis:
    image: redis
    ports:
      - "6379:6379"
    container_name: redis

  festival-api:
    build:
      context: .
      dockerfile: ./Dockerfile
    ports:
      - "8080:8080"
    depends_on:
      - redis
    container_name: {build-name}

뭘 넣어도 상관은 μ—†μ§€λ§Œ, κ΅¬λΆ„ν•˜κΈ° μ‰½κ²Œ Dockerfileμ—μ„œ μž‘μ„±ν•œ build-name을 κ·ΈλŒ€λ‘œ λ„£μ–΄μ£Όλ©΄ λœλ‹€.

# μ˜ˆμ‹œ
...
container_name: test

🎁 λΉŒλ“œ

Spring λΉŒλ“œ

gradle이 μ„€μΉ˜λ˜μ–΄ μžˆλŠ” 경우 μ•„λž˜ λͺ…λ Ήμ–΄λ₯Ό ν†΅ν•΄μ„œ jar 파일둜 λΉŒλ“œν•΄μ€€λ‹€.

application.yaml에 hostλ₯Ό redis둜 μ„€μ • ν›„ 진행해야함

.\gradlew.bat build

λ§Œμ•½, μ„€μΉ˜κ°€ λ˜μ–΄ μžˆμ§€ μ•Šμ„ 경우 New UI κΈ°μ€€ IDE 우츑 gradle μ•„μ΄μ½˜μ„ 톡해 buildλ₯Ό 진행해쀀닀.

image

Docker λΉŒλ“œ

IntelliJ 터미널을 μ΄μš©ν•΄μ„œ μ•„λž˜ λͺ…λ Ήμ–΄λ₯Ό μž…λ ₯ν•΄μ€€λ‹€.

docker-compose -f "docker-compose.yml" up -d --build  

λΉŒλ“œμ— μ„±κ³΅ν–ˆλ‹€λ©΄ μ•„λž˜ λͺ…λ Ήμ–΄λ₯Ό 톡해 잘 싀행이 되고 μžˆλŠ”μ§€ 확인해보면 λœλ‹€.

docker ps

image

ν˜Ήμ€ Docker μ–΄ν”Œλ¦¬μΌ€μ΄μ…˜μ„ 톡해 확인해도 λœλ‹€.

image

🧩 ν…ŒμŠ€νŠΈ

Postman을 μ΄μš©ν•΄μ„œ λ‘œμ»¬μ— μš”μ²­μ„ λ³΄λ‚΄κ±°λ‚˜ localhost:8080에 μ ‘μ†ν•΄μ„œ μƒνƒœλ₯Ό ν™•μΈν•˜λ©΄ λœλ‹€.

λŒ“κΈ€λ‚¨κΈ°κΈ°