Github Action + Docker

이 분 블로그 많이 참고했습니다 ㅎㅎ

지금 내가 하고 있는 플젝에 Docker를 이용한 Github Action을 적용해보고자 한다.
Github Action은 대표적인 CI/CD 툴 중에 하나로 코드 병합 및 배포를 자동화해줘서 배포가 매우 편리해진다는 장점이 있다. 젠킨스를 써볼까 했는데 젠킨스를 쓰려면 젠킨스를 위한 인스턴스가 또 있어야 되는 불편함이 있고 Github Action은 경험도 있으니 겸사겸사~(그 땐 Docker 안 쓰고 S3 사용했었음)
그럼 렉츠꼬~🏃‍♀️🏃‍♀️🏃‍♀️

flow 정리

  1. main 브랜치에 푸시
  2. Github Action에서 빌드 후 docker hub에 push
  3. 인스턴스에서 docker hub에 올린 이미지 pull 하고 run

Github Action 사용하기 위한 파일 만들기

repository에서 Actions를 누르면 다양한 템플릿을 선택할 수 있다. 그 중에서 Gradle 템플릿 선택!
그러면 루트 디렉토리에서 /.github/workflow/gradle.yml 파일을 생성할 수 있다.

# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle

name: Java CI with Gradle

# main 브랜치에 푸시하거나 pr 하면 이 플로우 실행
on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    # jdk 11 set up
    - uses: actions/checkout@v2
    - name: Set up JDK 11
      uses: actions/setup-java@v2
      with:
        java-version: '11'
        distribution: 'temurin'
    # gradle 로 src build
    - name: Build with Gradle
      uses: gradle/gradle-build-action@937999e9cc2425eddc7fd62d1053baf041147db7
      with:
        arguments: build
    # Docker에 빌드 된 이미지 push
    - name: Docker build
      run: |
        docker login -u ${{ secrets.USERNAME }} -p ${{ secrets.PASSWORD }}
        docker build -t spring-cicd .
        docker tag spring-cicd s2moon98/spring-cicd:${GITHUB_SHA::7}
        docker push s2moon98/spring-cicd:${GITHUB_SHA::7}
    # instance에 배포
    - name: Deploy
      uses: appleboy/ssh-action@master
      with:
        host: 146.56.130.233
        username: ubuntu
        key: ${{ secrets.PRIVATE_KEY }}
        envs: GITHUB_SHA
        script: |
          docker pull s2moon98/spring-cicd:${GITHUB_SHA::7}
          docker tag s2moon98/spring-cicd:${GITHUB_SHA::7} spring-cicd
          docker stop server
          docker run -d --rm --name server -p 8080:8080 spring-cicd

Port 관련 에러 해결기
처음에 docker run -d --rm --name server -p 80:8080 spring-cicd로 되어 있었고 docker ps를 해보면 도커는 띄워져 있지만 외부에서 접속이 안되는 문제가 생겼다. 구글링해도 나같은 경우는 나오지 않았다. 그런데 인스턴스에서 curl localhost:80은 접속이 되는 상태.
그래서 생각을 해보니 내가 이미 해당 서버에 포트 포워딩으로 80 -> 8080이 되도록 설정해놓았는데 그래서 외부 접속이 무조건 8080으로 들어오고 있었고 서버 안에서도 도커 명령어에 의해서 80 포트만 열어놓은 상태였기 때문에 접속이 거부되었던 것! docker 명령어에서 8080을 열어주도록 설정하자 해결되었다~🌻

server instance에서 작업할 것

instance에 docker를 설치한다. 나는 ubuntu 환경이라 apt-get 이용함
docker --version으로 설치 잘 됐는지 확인해준 다음에
배포를 하기 위한 키 생성!
이 키도 인스턴스 접속할 때 처럼 ssh 키 페어를 이용한다.
ssh-action을 이용해서 Github action 배포용 키 생성

여기 readme 문서에 나온대로 rsa 방식으로 키 페어 만들어주고 public key는 인스턴스에서 .ssh/authorized_keys2에 복붙해준다. 그리고 하라는대로 chmod 이용해서 권한 설정해주기

공개키 관련 에러 해결기 - 2
난 처음에 이미 인스턴스 접속용 공개키가 인스턴스의 .ssh/authorized_keys에 저장된 상태였기 때문에 당연히 해당 파일이 공개키를 저장하는 파일인줄 알고 여기에 추가해서 저장해줬었다. 그런데 계속 public key를 찾을 수 없다고 에러가 났고 readme 문서를 보니 authorized_keys2 문서였다는 사실~ 공식 문서를 열심히 보자~!
구글링해보니 원래는 authorized_keys에 저장해도 되는 것 같은데 내 경우에는 서버에 저장해야 할 공개키가 여러개인 특이 케이스라서 그런듯하다.

그리고 Docker hub에 이미지를 푸시하기 위해서 Dockerfile을 생성해준다.

FROM openjdk:11.0.10-jre-slim-buster
ARG JAR_FILE=build/libs/picture-diary-0.0.1-SNAPSHOT.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]

빌드된 jar 파일을 복사해서 실행하는 꽤나 간단한 Dockerfile

완성된 코드를 main에 push해보면?!

오랜 실패 끝에 성공한 모습을 볼 수 있다😭

좋은 웹페이지 즐겨찾기