FireDrago
[GithubActions] GithubActions로 Docker CI 구성하기 본문
CI (Continuous Integration) : 지속적인 통합
CI 과정은 여러 개발자가 작업한 코드를 중앙 저장소에 정기적으로 통합하는 과정을 말한다.
새로운 코드가 추가될 때마다 자동으로 테스트와 빌드를 거쳐, 기존 코드와 충돌 없이 잘 통합되는지 검증한다.
CI와 Docker
Docker를 사용하면 CI 과정을 어디서나 동일한 환경에서 수행할 수 있다. (개발자 컴퓨터, 개발 서버, 운영 서버 등등)
코드 테스트와 빌드 과정이 끝나면 최종 산출물과 실행 환경등을 담은 도커 이미지로 만든다.
GithubActions


CI/CD를 위한 대표적인 도구로 Jenkins와 GithubActions가 있다.
Actions는 jenkins에 비해 CI/CD구성이 간편하다.
프로젝트 .github/workflow 에 yml 파일로 작업을 정의해 줄 수 있다.
반면 Jenkins는 직접 서버에 설치해야 하고 학습 곡선이 더 높은 대신, Actions 보다 다양한 작업을 가능하게 해준다.
(여러 서버를 한번에 관리 해야 한다거나, 애플리케이션 서버 private Ip 설정등)
현재 프로젝트 단계에서는 쉽게 적용할 수 있는 GithubActions를 도입하기로 팀원들과 합의했다.
코드로 보기
name: Dev Server CI
on:
pull_request:
types: [opened, synchronize, reopened]
branches: [develop]
paths: ['server/**']
jobs:
# 작업을 하나로 통합하여 테스트, 빌드, 이미지 생성을 순차적으로 진행
build-and-push:
name: Test, Build and Push Docker Image
runs-on: ubuntu-latest
permissions:
contents: read
steps:
# 1. 레포지토리 코드 체크아웃
- name: Checkout
uses: actions/checkout@v4
# 2. JDK 21 (Temurin) 환경 설정
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: '21'
distribution: 'temurin'
# 3. Gradle 캐시 설정 (빌드 속도 향상)
- name: Cache Gradle dependencies
uses: actions/cache@v3
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('server/**/*.gradle*', 'server/**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
# 4. ✨ 중요: Gradle을 사용해 테스트와 .jar 파일 빌드를 한 번에 실행
- name: Build with Gradle
run: ./gradlew build
working-directory: ./server
# 5. Docker Buildx 환경 설정
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# 6. Docker Hub 로그인
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# 7. ✨ 중요: Docker 이미지를 빌드하고 푸시 (단순화된 Dockerfile 사용)
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./server
file: ./server/Dockerfile
push: true
platforms: linux/arm64,linux/amd64
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/moment:latest
${{ secrets.DOCKERHUB_USERNAME }}/moment:${{ github.sha }}
cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/moment:buildcache
cache-to: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/moment:buildcache,mode=max
위 파일은 yml 파일을 통해 ci 과정을 정의해놓은 것이다.
on:
pull_request:
types: [opened, synchronize, reopened]
branches: [develop]
paths: ['server/**']
먼저 트리거 (발동 조건)을 설정해준다.
pr 제출, 커밋 푸쉬, 다시 열린 경우에 실행된다.
paths: 설정을 통해 소스코드의 server 디렉토리 이하의 변경에 해당될때만 작동하도록 설정했다.
build-and-push:
name: Test, Build and Push Docker Image
runs-on: ubuntu-latest
permissions:
contents: read
GithubActions는 해당 작업을 실행할때 새로운 가상 공간을 만든다.
runs-on: ubuntu-latest 가상공간의 환경을 우분투 최신 버전으로 설정한다.
permissions: contents: read 해당 가상 공간이 소스코드를 읽을 수 있는 권한을 부여한다.
소스코드를 테스트 하고 .jar 파일로 변환하기 위해 jdk21 설치하고 gradle을 통해 빌드를 실행한다.
이 과정은 이해하기 어렵지 않다.
# 7. ✨ 중요: Docker 이미지를 빌드하고 푸시 (단순화된 Dockerfile 사용)
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: ./server
file: ./server/Dockerfile
push: true
platforms: linux/arm64,linux/amd64
tags: |
${{ secrets.DOCKERHUB_USERNAME }}/moment:latest
${{ secrets.DOCKERHUB_USERNAME }}/moment:${{ github.sha }}
cache-from: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/moment:buildcache
cache-to: type=registry,ref=${{ secrets.DOCKERHUB_USERNAME }}/moment:buildcache,mode=max
빌드된 jar 파일을 DockerHub에 push 하는 과정이다.
file: ./server/Dockerfile 경로를 통해 Dockerfile을 읽고 설정대로 이미지를 생성한다.
context: ./server 를 설정해주어서 Dockerfile에서 ./server 내부에서 작업을 진행 할 수 있게된다.
Dockerfile을 살펴보자
# 1. 실행에 필요한 최소한의 JRE(Java Runtime Environment) 이미지를 사용
FROM eclipse-temurin:21-jre-jammy
# 2. 컨테이너 내부의 작업 디렉토리 설정
WORKDIR /app
# 3. CI에서 이미 빌드된 .jar 파일을 컨테이너 안으로 복사
COPY build/libs/*.jar app.jar
# 4. 컨테이너 시작 시 애플리케이션 실행
ENTRYPOINT ["java", "-jar", "app.jar"]
GithubActions는 이 Dockerfile대로 이미지를 생성한다.
CI 과정에서는 소스 코드를 컴파일하기 위해 javac를 포함한 JDK가 필요하지만,
최종 이미지에는 이미 빌드된 .jar 파일을 실행하기 위한 JRE만 포함시켜 이미지 크기를 최소화하고 보안을 강화한다.
COPY 명령어에서 앞서 CI 과정에서 context 명령어에 정의한 ./server 디렉토리 내부에서 jar 파일을 찾는다.
빌드된 이미지가 DockerHub에 업로드 되면 CI 과정이 마무리된다.
'프로그래밍 > 배포' 카테고리의 다른 글
| [GithubActions] GithubActions로 Docker CD 구성하기 (0) | 2025.07.29 |
|---|---|
| [배포] jenkins 사용하여 배포 자동화 하기 (0) | 2024.07.27 |
| [vultr] DB를 사용하는 프로젝트 배포하기 (0) | 2024.07.23 |
| pscp명령어로 원격서버 <-> 로컬 파일전송하기 (0) | 2024.07.22 |
| [배포] Vultr 이용하여 간단한 프로젝트 배포해보기 (0) | 2024.07.18 |
