3 minute read

일단 내가 만든 CI/CD 구조가 어떻게 실행되는지 설명을 하자면, 내 GitHub repository에서 코드가 commit 될 때 마다 docker hub에 push ➡ 이 이미지(latest)를 EC2의 docker-compose에서 사용해서 docker container를 띄우는 방식이다.

GitHub Actions 초기 세팅

일단 먼저 GitHub 의 CI/CD를 진행하고 싶은 프로젝트의 Actions 탭에서 Java CI with Gradle < 이것을 선택해주어야 하는데, 선택해주면 프로젝트 루트 경로 이하에 /.github/workflows/gradle폴더가 생성된다.

그리고 이 탭이 생겼는지 확인하면 된다.

Secret key 등록하기

사실 GitHub에 새 탭이 생겨서 여기서 반 이상 헤맸는데…… 공식 문서에도 업데이트가 안 되어있었다. 알고보니 오른쪽 위에 있었는데 거의 6시간을 이거 찾느라 헤맸다. Settings > Security > secrets and variables > Actions 탭에서 오른쪽 위의 New Repository Secret 을 눌러서 보안이 적용되어야 하는 환경 변수들(비밀번호, 키 값 등…)을 넣어주면 된다.

Dockerfile, docker-compose.yml 파일 작성

# Dockerfile

FROM openjdk:11-jdk  
ARG JAR_FILE=build/libs/*.jar  
COPY ${JAR_FILE} app.jar  
ENV JAVA_OPTS="-Dcom.amazonaws.sdk.disableEc2Metadata=true"  
EXPOSE 8080    
ENTRYPOINT ["java","-jar","/app.jar"]

Spring Boot 프로젝트의 루트 경로(server)에 Dockerfile을 넣어주었다. IDE의 터미널에서 docker build -t [username]/[repository name]:[tag] .를 실행해, 초기 이미지를 빌드하는 것이 가능한지 확인한다. (생략가능)

version: '3'  
  
services:  
  
  application:  
    container_name: spring  
    image: 21yrshin/seb44_main_017:latest  
    expose:  
      - 8080  
    ports:  
      - 8080:8080  
    tty: true  
    stdin_open: true  
    environment:  
      SPRING_DATASOURCE_URL:  
      SPRING_DATASOURCE_USERNAME:  
      MYSQL_PASSWORD:   
      ... 등등 Spring Boot 프로젝트 실행을 위한 환경변수들
    networks:  
      - test_network  
  
networks:  
  test_network:  
    driver: bridge

EC2에 docker-compose를 설치하고, home directory(~)에 docker-compose.yml 파일을 작성해 주었다. 환경 변수 파일을 따로 작성해도 되지만, 나의 경우 컨테이너 수가 적고 어차피 EC2 내에서만 사용하고 수정이 많지 않을 파일이기 때문에 그냥 파일에 바로 환경 변수들을 작성했다. 컨테이너가 더 많아지거나, GitHub로 해당 파일을 관리할 예정이라면 .env 파일을 따로 작성하는 것이 좋을 것이다.

Gradle.yml 파일 작성

name: Java CI with Gradle  
  
on:  
  push:  
    branches: [ "be-dev" ]  
  pull_request:  
    branches: [ "be-dev" ]  
  
permissions:  
  contents: read  
  
defaults:  
  run:  
    working-directory: server  

나는 루트 디렉토리가 아닌 루트 디렉토리 이하 server 폴더가 java spring boot 프로젝트의 루트 경로였기 때문에 working-directory를 별도로 지정해주었다.

그리고 main 이 아닌 별도 branch(be-dev)를 트리거로 하고 싶었기에 이를 명시해주었다.

  
jobs:  
  build:  
    runs-on: ubuntu-latest  
  
    steps:  
      ## JDK setting  
  
      - name: Checkout  
        uses: actions/checkout@v3  
        with:  
          ref: be-dev  
          repository: [username]/[repository name]:[tag]

ref 로 한번 더 어떤 브랜치를 선택할 건지 명명해주었다.

  
      - name: Set up JDK 11  
        uses: actions/setup-java@v3  
        with:  
          java-version: '11'  
          distribution: 'temurin'  
  
      - name: Set permission for gradlew  
        run: chmod +x ./gradlew  
  
      ## Gradle Build  
      - name: Build with Gradle  
        run: ./gradlew bootJar  

gradle build를 사용하기 위해 JDK 버전 설정, 실행 권한을 부여한 후 빌드를 실행해주면 프로젝트 .jar 파일이 생성된다.

  
      ## Docker with Docker Setup Buildx  
  
      - name: Set up Docker Buildx  
        uses: docker/setup-buildx-action@v1  
  
      - name: Login to DockerHub  
        uses: docker/login-action@v1  
        with:  
          username: $  
          password: $  

docker 이미지 빌드 및 push는 SSH에서 진행하지 않고, GitHub Actions의 docker setup buildxbuild-push-action을 사용했다.

      ## push to docker hub  
      - name: web docker build and push with docker action  
        uses: docker/build-push-action@v1  
        with:  
          dockerfile: ./server/Dockerfile  
          username:  
          password: 
          path: server  
          push: true  
          repository: [username]/[repository name]
          tags: latest  

working-directory를 build-push-action에서는 인식 못하는 문제가 있어서 path, repository, tag, dockerfile 위치를 직접 명시해주었다.

관련 issue를 참고해 작성하였다.

근데 작동에는 문제가 전혀 없으나 build-push-action이 지난 버전인데 최신 버전에서는 적용이 안된다… 최신 버전에서 적용하는 방법 아시는 분 계시면 알려주시면 감사하겠습니다.

  
      ## docker compose up  
      - name: executing remote ssh commands using password  
        uses: appleboy/ssh-action@v0.1.4  
        with:  
          host: $  
          username: ubuntu  
          key: $  
          script: |  
            sudo docker rm -f spring  
            sudo docker pull [username]/[repository name]:[tag]  
            sudo docker-compose up -d  
            docker image prune -f

AWS EC2에 SSH 연결하기 위한 값들을 동일하게 넣고 (환경 변수로 넣어야 한다) 실행해주면 된다.

  • HOST : SSH 로그인을 위한 IPv4 DNS 주소
  • KEY : KEY값 (vim이나 cat 명령어로 확인 가능)

이와 같은 과정을 마치면 GitHub Actions 가 정상수행되는 것을 확인할 수 있다.

EC2에서 실행된 컨테이너에 의해, Http request들도 정상작동한다.

참고한 글들

Leave a comment