diff --git a/.github/workflows/be-cd_dev-docker.yml b/.github/workflows/be-cd_dev-docker.yml index c691ce643..8de997a71 100644 --- a/.github/workflows/be-cd_dev-docker.yml +++ b/.github/workflows/be-cd_dev-docker.yml @@ -130,6 +130,11 @@ jobs: COOKIE_PATH=${{ secrets.COOKIE_PATH }} COOKIE_SAME_SITE=${{ secrets.COOKIE_SAME_SITE }} COOKIE_MAX_AGE=${{ secrets.COOKIE_MAX_AGE }} + + # Redis + REDIS_PORT=${{ secrets.REDIS_PORT }} + REDIS_HOST=${{ secrets.REDIS_HOST }} + REDIS_PASSWORD=${{ secrets.REDIS_PASSWORD }} EOF # - name: Check if MySQL container is running diff --git a/.github/workflows/be-cd_prod-docker.yml b/.github/workflows/be-cd_prod-docker.yml index 3fd4b6bb9..8ccb2b276 100644 --- a/.github/workflows/be-cd_prod-docker.yml +++ b/.github/workflows/be-cd_prod-docker.yml @@ -131,7 +131,12 @@ jobs: COOKIE_DOMAIN=${{ secrets.COOKIE_DOMAIN }} COOKIE_PATH=${{ secrets.COOKIE_PATH }} COOKIE_SAME_SITE=${{ secrets.COOKIE_SAME_SITE }} - COOKIE_MAX_AGE=${{ secrets.COOKIE_MAX_AGE }} + COOKIE_MAX_AGE=${{ secrets.COOKIE_MAX_AGE }} + + # Redis + REDIS_PORT=${{ secrets.REDIS_PORT }} + REDIS_HOST=${{ secrets.REDIS_HOST }} + REDIS_PASSWORD=${{ secrets.REDIS_PASSWORD }} EOF - name: Stop and remove existing containers diff --git a/.github/workflows/be-cd_test-docker.yml b/.github/workflows/be-cd_test-docker.yml index 96baabe2d..6eaa811a3 100644 --- a/.github/workflows/be-cd_test-docker.yml +++ b/.github/workflows/be-cd_test-docker.yml @@ -124,7 +124,12 @@ jobs: COOKIE_DOMAIN=${{ secrets.COOKIE_DOMAIN }} COOKIE_PATH=${{ secrets.COOKIE_PATH }} COOKIE_SAME_SITE=${{ secrets.COOKIE_SAME_SITE }} - COOKIE_MAX_AGE=${{ secrets.COOKIE_MAX_AGE }} + COOKIE_MAX_AGE=${{ secrets.COOKIE_MAX_AGE }} + + # Redis + REDIS_PORT=${{ secrets.REDIS_PORT }} + REDIS_HOST=${{ secrets.REDIS_HOST }} + REDIS_PASSWORD=${{ secrets.REDIS_PASSWORD }} EOF - name: Stop and remove existing containers diff --git a/backend/build.gradle b/backend/build.gradle index 5a9b4a0fe..c5a1b2bb3 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -41,6 +41,9 @@ dependencies { implementation 'org.flywaydb:flyway-core:9.22.3' implementation 'org.flywaydb:flyway-mysql' + // Redis + implementation 'org.springframework.boot:spring-boot-starter-data-redis' + // Lombok compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' diff --git a/backend/docker-compose.local.yml b/backend/docker-compose.local.yml new file mode 100644 index 000000000..7c907fcc6 --- /dev/null +++ b/backend/docker-compose.local.yml @@ -0,0 +1,17 @@ +version: '3.8' + +services: + redis: + image: redis:latest + container_name: redis-local + env_file: + - .env + command: "redis-server --requirepass ${LOCAL_REDIS_PASSWORD}" + ports: + - "${LOCAL_REDIS_PORT}" + networks: + - redis_network + +networks: + redis_network: + driver: bridge diff --git a/backend/src/main/java/com/cruru/config/RedisConfig.java b/backend/src/main/java/com/cruru/config/RedisConfig.java new file mode 100644 index 000000000..88265f5ff --- /dev/null +++ b/backend/src/main/java/com/cruru/config/RedisConfig.java @@ -0,0 +1,43 @@ +package com.cruru.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.RedisPassword; +import org.springframework.data.redis.connection.RedisStandaloneConfiguration; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +@Configuration +public class RedisConfig { + + @Value("${spring.data.redis.host}") + private String host; + + @Value("${spring.data.redis.port}") + private int port; + + @Value("${spring.data.redis.password}") + private String password; + + @Bean + public RedisConnectionFactory redisConnectionFactory() { + RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration(); + redisConfig.setHostName(host); + redisConfig.setPort(port); + redisConfig.setPassword(RedisPassword.of(password)); + return new LettuceConnectionFactory(redisConfig); + } + + @Bean + public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) { + RedisTemplate redisTemplate = new RedisTemplate<>(); + redisTemplate.setConnectionFactory(connectionFactory); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new StringRedisSerializer()); + redisTemplate.afterPropertiesSet(); + return redisTemplate; + } +} diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 652ddb743..20919a2dc 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -45,6 +45,11 @@ spring: file-size-threshold: 2KB max-file-size: 25MB max-request-size: 50MB + data: + redis: + port: ${REDIS_PORT} + host: ${REDIS_HOST} + password: ${REDIS_PASSWORD} security: jwt: @@ -116,6 +121,11 @@ spring: file-size-threshold: 2KB max-file-size: 25MB max-request-size: 50MB + data: + redis: + port: ${REDIS_PORT} + host: ${REDIS_HOST} + password: ${REDIS_PASSWORD} security: jwt: @@ -207,7 +217,11 @@ spring: file-size-threshold: 2KB max-file-size: 25MB max-request-size: 50MB - + data: + redis: + port: ${REDIS_PORT} + host: ${REDIS_HOST} + password: ${REDIS_PASSWORD} security: jwt: token: @@ -297,7 +311,11 @@ spring: file-size-threshold: 2KB max-file-size: 25MB max-request-size: 50MB - + data: + redis: + port: ${REDIS_PORT} + host: ${REDIS_HOST} + password: ${REDIS_PASSWORD} security: jwt: token: diff --git a/backend/src/test/resources/application.yml b/backend/src/test/resources/application.yml index 09f1cb581..2201cc1d8 100644 --- a/backend/src/test/resources/application.yml +++ b/backend/src/test/resources/application.yml @@ -25,6 +25,11 @@ spring: open-in-view: false mail: host: smtp.gmail.com + data: + redis: + port: 6379 + host: localhost + password: password dataloader: enable: false