Devops

GitHub를 이용한 CI (docker Hub)

댕발바닥 2024. 4. 11. 21:41

 

CI란?

CI는 Contious Integration으로 지속적인 통합이라 할 수 있다. 개발팀이 정기적으로 코드 변경사항을 구현하고 테스트 한 후, 공유 버전 관리 레포지토리에 병합하는 방식을 말한다. 자동화 된 빌드에 의해 이런 `체크인`이 인증되므로 코드와 관련된 모든 문제를 신속하게 파악하고 해결 할 수 있다. CI를 사용하면 개발자 팀 사이에 충돌 없이 동일한 앱을 동시에 작업 할 수있다.

 

 

사용 툴

  • Github
  • Docker
  • spring boot

 

차례

  1. spring boot 프로젝트 구조
  2. Github actions 스크립트 파일
  3. Dockerfile 파일
  4. Gitlab CI 확인

 

 

Spring Boot 프로젝트 구조

spring boot 구조

 

메이븐을 통한 멀티 모듈 구조로 프로젝트 구성을 만들었다. 

  • web-api: spring boot 메인 프로젝트로 MVC에서 컨트롤러, 서비스 로직을 담당하는 부분을 맡고 있는 모듈이다.
  • web-core: core 프로젝트로 독립적으로 사용가능하게 만든 모듈로 주로 jpa, entity, utils exception 정도를 넣어둔 모듈이다.
  • web-dao: MVC에 모델 파트를 맡은 부분으로 만든 모듈로 데이터베이스에 데이터를 가져오는 모듈로 사용하고있다.
  • web-middleware: 주로 필터, wrapper 등을 사용하는 모듈로 만들어 두었다.

위 처럼 만든 모듈을 통하여 web-api 밑에 jar파일을 통하여 프로젝트를 실행 할 수있게 구조를 만들었다.

 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <packaging>jar</packaging>

    <parent>
        <groupId>cm.kr.project</groupId>
        <artifactId>project-anme</artifactId>
        <version>0.0.1</version>
    </parent>

    <groupId>com.kr.project</groupId>
    <artifactId>web-api</artifactId>
    <version>0.0.1</version>

    <name>web-api</name>
    <description>web-api</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>com.kr.project</groupId>
            <artifactId>web-core</artifactId>
            <version>0.0.1</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>com.kr.project</groupId>
            <artifactId>web-dao</artifactId>
            <version>0.0.1</version>
        </dependency>

        <dependency>
            <groupId>com.kr.project</groupId>
            <artifactId>web-middleware</artifactId>
            <version>0.0.1</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

 

위 처럼 parent pom.xml에 묶어 다른 모듈들을 불러서 사용하고 있다.

 

 

Github actions 스크립트 파일

deploy.yml

 

Github배포 yml 파일을 작성했다.

 

name: CI-CD

on:
  push:
    branches:
      - master
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      DATASOURCE_KEY: ${{ secrets.DATASOURCE_KEY }}
      DATASOURCE_URL: ${{ secrets.DATASOURCE_URL }}
      DATASOURCE_USERNAME: ${{ secrets.DATASOURCE_USERNAME }}
      DATASOURCE_PASSWORD: ${{ secrets.DATASOURCE_PASSWORD }}
      DOCKER_HUB_REPO: ${{ secrets.DOCKER_HUB_REPO }}
      DOCKER_HUB_NAME: ${{ secrets.DOCKER_HUB_NAME }}
      DOCKER_HUB_USER: ${{ secrets.DOCKER_HUB_USER }}
      DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }}

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      # Cache Maven
      - name: Cache Maven packages
        uses: actions/cache@v2
        with:
          path: ~/.m2
          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
          restore-keys: ${{ runner.os }}-m2

      # Maven Package
      - name: Build with Maven
        run: mvn -Dmaven.test.skip=true -B package --file ./pom.xml

      # Docker Image Build
      - name: Docker Build Image
        run: | 
          docker build -t ${{ env.DOCKER_HUB_REPO }} \
          --build-arg DATASOURCE_KEY="${{ env.DATASOURCE_KEY }}" \
          --build-arg DATASOURCE_URL="${{ env.DATASOURCE_URL }}" \
          --build-arg DATASOURCE_USERNAME="${{ env.DATASOURCE_USERNAME }}" \
          --build-arg DATASOURCE_PASSWORD="${{ env.DATASOURCE_PASSWORD }}" .

      # Docker Hub Login
      - name: Login to DockerHub
        uses: docker/login-action@v1
        with:
          username: ${{ env.DOCKER_HUB_USER }}
          password: ${{ env.DOCKER_HUB_PASSWORD }}

      # Docker Hub 이미지 push
      - name: Build and Release to DockerHub
        env:
          NAME: ${{ env.DOCKER_HUB_NAME }}
          REPO: ${{ env.DOCKER_HUB_REPO }}
        run : |
          docker tag $REPO:latest $NAME/$REPO:latest
          docker push $NAME/$REPO:latest

 

  1. 도커, DB의 정보는 Github secert으로 env처리후 불러왔다. ( db정보 경우 이전 포스팅했던 jasypt 해시 처리도 진행했다)
  2. maven 빌드 경우 동일할 경우 캐시처리로 빌드 속도를 향상시켰다.
  3. maven 패키징을 진행했고 테스트는 스킵처리로 진행했다.
  4. Dockerfile 이미지를 빌드했고 db정보를 argumenet로 전달을 진했다.
  5. Docker Hub에 로그인 했다.
  6. 4단계에서 만들어진 이미지 파일을 Docker Hub로 push를 진행했다.

 

내가 만든 CI 스크립트로 멀티 모듈을 하나의 jar로 패키징한 후 Docker 이미지화 시킨후 허브에 올려두었다.

다양한 방식이 있겠지만 필자는 이후에 도커 허브의 이미지로 CD를 구축하는 법을 찾아볼 예정이다.

 

Dockerfile 파일

FROM openjdk:8-alpine

WORKDIR /app

ARG JAR_FILE_PATH=/web-api/target/*.jar
ARG DATASOURCE_KEY
ARG DATASOURCE_URL
ARG DATASOURCE_USERNAME
ARG DATASOURCE_PASSWORD

ENV ACTIVE_PROFILE="local" \
    DATASOURCE_KEY=${DATASOURCE_KEY} \
    DATASOURCE_URL=${DATASOURCE_URL} \
    DATASOURCE_USERNAME=${DATASOURCE_USERNAME} \
    DATASOURCE_PASSWORD=${DATASOURCE_PASSWORD}

COPY /${JAR_FILE_PATH} ROOT.jar

EXPOSE 12001

ENTRYPOINT ["java", "-jar", "-Xincgc", "-Xmx1024m", "-Dspring.profiles.active=${ACTIVE_PROFILE}", "-Dencryptor.key=${DATASOURCE_KEY}", "-Dspring.datasource.url=${DATASOURCE_URL}", "-Dspring.datasource.username=${DATASOURCE_USERNAME}", "-Dspring.datasource.password=${DATASOURCE_PASSWORD}", "-Duser.timezone=Asia/Seoul", "ROOT.jar"]

 

도커 파일을 만들어주었고 디스크 공간 소모를 아끼기위해 openjdk 경량화를 사용하였다. (web-api/target 밑에 생긴 jar를 사용하게 만들었다)

이후 여러 argument를 세팅한 후 기본 포트를 설정하고 jar를 실행시키는 명령어를 넣어준 도커 파일을 만들었다.

 

 

Gitlab CI 확인

github ci

 

github action을 살펴보면 정상적으로 구동되는것을 확인 할 수있다.

 

위 이미지 처럼 도커 허브에 내가 올린 이미지가 정상적으로 올라가는것을 볼 수있다. 이 이미지를 이용해서 이제 배포를 진행 할 거다

 

아직은 CD에 대해서 정확히 공부를 하지 않은 상태로 배포 스크립트를 작성해서 배포해보는 연습을 진행할 예정이다.