Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: AWS 배포 파이프라인 설정 #8

Merged
merged 8 commits into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions .github/workflows/release-cd.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
name: AWS EC2 Deploy

on:
push:
branches:
- main

jobs:
build:
# ubuntu 버전 지정
runs-on: ubuntu-22.04
steps:
# Checkout 진행
- uses: actions/checkout@v3

# JDK 17 설치
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'corretto'

# Gradle 캐싱
- name: Gradle Caching
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-

# Gradle 권한 부여
- name: Grant execute permission for gradlew
run: chmod +x gradlew

# secret.yml 반영
- name: Make application-secret.yml
run: |
cd ./src/main/resources
touch ./application.yml
echo "${{ secrets.APPLICATION_SECRET}}" > ./application-secret.yml
shell: bash

# release.yml 반영
- name: Make application-release.yml
run: |
cd ./src/main
mkdir resources
cd ./resources
touch touch ./application.yml
echo "${{ secrets.GCP_APPLICATION_RELEASE}}" > ./application.yml
shell: bash

# Gradle BootJar
- name: BootJar with Gradle
run: ./gradlew clean bootJar -Dspring.profiles.active=release

# Docker Image Push
- name: Docker Image push
run: |
docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_PASSWORD }}
docker build -t ${{ secrets.DOCKERHUB_USERNAME}}/${{ secrets.DOCKERHUB_REPOSITORY}} ./
docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPOSITORY}}

# Docker Compose
- name: Docker Compose
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.EC2-SERVER-IP }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
sudo docker login -u ${{ secrets.DOCKERHUB_USERNAME }} -p ${{ secrets.DOCKERHUB_PASSWORD }}
sudo docker-compose stop ${{ secrets.DOCKER_SERVICE_NAME }}
sudo docker-compose rm -f ${{ secrets.DOCKER_SERVICE_NAME }}
sudo docker pull ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPOSITORY}}
sudo docker tag ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_REPOSITORY}} ${{ secrets.DOCKER_IMAGE_NAME }}
sudo docker-compose up -d
52 changes: 52 additions & 0 deletions .github/workflows/release-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: CI with Gradle

on:
pull_request:
branches:
- main

permissions: write-all

jobs:
build:
# ubuntu 버전 지정
runs-on: ubuntu-22.04
steps:
# Checkout 진행
- uses: actions/checkout@v3

# JDK 17 설치
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'corretto'

# Gradle 캐싱
- name: Gradle Caching
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-

# Gradle 권한 부여
- name: Grant execute permission for gradlew
run: chmod +x gradlew

# yml 반영
- name: Make application-secret.yml
run: |
cd ./src/main
mkdir resources
cd ./resources
touch touch ./application.yml
echo "${{ secrets.GCP_APPLICATION_RELEASE}}" > ./application.yml
shell: bash

# Gradle clean bootJar
- name: Build with Gradle
run: ./gradlew clean bootJar
4 changes: 4 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
FROM openjdk:17-alpine
ARG JAR_FILE=./build/libs/gwalit-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["sh", "-c", "java -Duser.timezone=Asia/Seoul -jar /app.jar"]
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ dependencies {
// MySQL
runtimeOnly 'com.mysql:mysql-connector-j'

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

// Swagger UI - spring doc
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.0.2'

Expand Down
36 changes: 36 additions & 0 deletions src/main/java/com/gongjakso/server/global/config/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.gongjakso.server.global.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.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@EnableRedisRepositories
public class RedisConfig {

@Value("${spring.redis.host}")
private String host;

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

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

@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());

return redisTemplate;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.gongjakso.server.global.util.redis;

import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.Objects;

@Component
@RequiredArgsConstructor
public class RedisClient {

private final RedisTemplate<String, Object> redisTemplate;

/**
* Redis에 값 삽입하는 메소드
* @param key - 삽입하고자 하는 데이터의 key
* @param value - 삽입하고자 하는 데이터의 value
* @param timeout - 삽입하고자 하는 데이터의 유효 시간
*/
public void setValue(String key, String value, Long timeout) {
ValueOperations<String, Object> values = redisTemplate.opsForValue();
values.set(key, value, Duration.ofMinutes(timeout));
}

/**
* Redis에서 key값을 기반으로 value를 찾아서 반환하는 메소드
* @param key - value를 찾을 데이터의 key 값
* @return - 해당 데이터의 value 반환
*/
public String getValue(String key) {
ValueOperations<String, Object> values = redisTemplate.opsForValue();
return Objects.requireNonNull(values.get(key)).toString();
}

/**
* Redis에서 key에 해당하는 데이터를 삭제하는 메소드
* @param key - 삭제할 데이터의 key를 의미
*/
public void deleteValue(String key) {
redisTemplate.delete(key);
}
}