지금 내가 하고 있는 플젝에 Docker를 이용한 Github Action을 적용해보고자 한다.
Github Action은 대표적인 CI/CD 툴 중에 하나로 코드 병합 및 배포를 자동화해줘서 배포가 매우 편리해진다는 장점이 있다. 젠킨스를 써볼까 했는데 젠킨스를 쓰려면 젠킨스를 위한 인스턴스가 또 있어야 되는 불편함이 있고 Github Action은 경험도 있으니 겸사겸사~(그 땐 Docker 안 쓰고 S3 사용했었음)
그럼 렉츠꼬~🏃♀️🏃♀️🏃♀️
- main 브랜치에 푸시
- Github Action에서 빌드 후 docker hub에 push
- 인스턴스에서 docker hub에 올린 이미지 pull 하고 run
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을 열어주도록 설정하자 해결되었다~🌻
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해보면?!
오랜 실패 끝에 성공한 모습을 볼 수 있다😭