대외활동/DRACONIST-백엔드

08. docker와 github action으로 CI/CD하기

피스타0204 2025. 3. 16. 19:08

1. .github/workflows/gradle.yml을 프로젝트의 루트 폴더에 만듭니다.

name: goodluckynews  #프로젝트 이름
on:
  push:
    branches: [ "develop" ]
  pull_request:
    branches: [ "develop" ]
  workflow_dispatch:

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'

      - 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-

      - name: make application.properties
        run: |
          mkdir -p src/main/resources
          echo "$APPLICATION" > src/main/resources/application.properties
        env:
          APPLICATION: ${{ secrets.APPLICATION }}

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew build -x test

      - name: Docker build
        run: |
          docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
          docker build -t app .
          docker tag app ${{ secrets.DOCKER_USERNAME }}/`docker_username`:latest
          docker push ${{ secrets.DOCKER_USERNAME }}/`docker_username`:latest

      - name: Deploy to dev
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ubuntu
          key: ${{ secrets.PRIVATE_KEY }}
          script: |
            sudo docker login -u ${{ secrets.DOCKER_USERNAME }} -p ${{ secrets.DOCKER_PASSWORD }}
            sudo docker pull ${{ secrets.DOCKER_USERNAME }}/`docker_username`:latest
            sudo docker stop $(sudo docker ps -a -q)
            sudo docker run -d --log-driver=syslog -p 8080:8080 -e TZ=Asia/Seoul -e SPRING_PROFILES_ACTIVE= ${{ secrets.DOCKER_USERNAME }}/`docker_username`:latest
            sudo docker rm $(sudo docker ps --filter 'status=exited' -a -q)
            sudo docker image prune -a -f

      - name: Check logs
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.HOST }}
          username: ubuntu
          key: ${{ secrets.PRIVATE_KEY }}
          script: |
            sudo docker logs $(sudo docker ps -l -q)

 

2. github에서 비밀키들을 설정해줍니다.

1) github repository의 setting에 들어가서 secrets and variables의 action을 누릅니다.

 

2) github action에 application.properties에서 관리하는 비밀키들을 한번에 집어 넣습니다. (APPLICATION)

spring.application.name=goodluckynews
# spring.h2.console.enabled=true

# JPA 초기화 설정
spring.jpa.deferdatasource-initialization=true

# Hibernate SQL 로그 설정
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE

# JPA 설정
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
logging.level.org.springframework.security=DEBUG

# MariaDB RDS 설정
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver

# JPA 데이터베이스 설정
spring.jpa.database-platform=org.hibernate.dialect.MariaDBDialect

# 파일 업로드 제한 설정
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=10MB

# JWT 설정
spring.jwt.secret=
spring.jwt.expiration_time=86400000 

# AWS S3 설정
cloud.aws.credentials.access-key=
cloud.aws.credentials.secret-key=
cloud.aws.region.static=
cloud.aws.s3.bucket=

# MariaDB RDS 설정
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=

#테이블 자동생성
spring.jpa.hibernate.ddl-auto=update

#크롤링 키
naver.client-id=
naver.client-secret=

 

 

3) build.gradle(참고)

plugins {
	id 'java'
	id 'org.springframework.boot' version '3.4.2'
	id 'io.spring.dependency-management' version '1.1.7'
}

group = 'com.draconist'
version = '0.0.1-SNAPSHOT'

java {
	toolchain {
		languageVersion = JavaLanguageVersion.of(17)
	}
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	runtimeOnly 'com.h2database:h2'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.security:spring-security-test'
	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

	// JJWT (JSON Web Token)
	implementation 'io.jsonwebtoken:jjwt-api:0.12.3'
	implementation 'io.jsonwebtoken:jjwt-impl:0.12.3'
	implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3' // JSON 처리

	// ✅ Jakarta Validation 추가
	implementation 'org.springframework.boot:spring-boot-starter-validation'

	//s3 설정
	implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'

}


tasks.named('test') {
	useJUnitPlatform()
}

 

3. 프로젝트 루트에 Dockerfile을 만듭니다.

FROM openjdk:17
COPY ./build/libs/goodluckynews-0.0.1-SNAPSHOT.jar goodluckynews.jar
ENTRYPOINT ["java", "-jar", "goodluckynews.jar"] #프로겢트 이름이 들어 갑니다

 

4. 이제 ec2에서 docker를 설치하고 실행을 확인합니다.

1)우분투 시스템 패키지 업데이트

sudo apt-get update

2) 필요한 패키지 설치

sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

3) Docker의 공식 GPG키를 추가

curl -fsSL <https://download.docker.com/linux/ubuntu/gpg> | sudo apt-key add -

4) Docker의 공식 apt 저장소를 추가

sudo add-apt-repository "deb [arch=amd64] <https://download.docker.com/linux/ubuntu> $(lsb_release -cs) stable"

5) 시스템 패키지 업데이트

sudo apt-get update

6) Docker 설치

sudo apt-get install docker-ce docker-ce-cli containerd.io

7) 도커 실행상태 확인

sudo systemctl status docker

8) 도커 실행

sudo docker run hello-world

동작중인 도커 컨테이너 확인

sudo docker ps

컨테이너 로그 확인

sudo docker logs <container_id>

 

5. 완료

이제 github repository에 action 탭에서 pull request가 발생하거나, push가 발생했을때 자동으로 build가 됩니다.