대외활동/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가 됩니다.