본문 바로가기
CI&CD

Github actions를 이용한 CICD - 2

by e-pd 2021. 8. 10.

 

지난 깃헙액션 포스팅에서 깃헙액션을 이용해 빌드 자동화를 마쳤습니다.

이번 포스팅에서는 도커를 사용해서 배포 준비를 할 것입니다.

도커를 사용한다면 어디에서 동일한 환경의 배포를 할 수 있습니다.

 

도커에 익숙하지 않다면 아래 포스팅을 참고합니다.

https://aws.amazon.com/ko/docker/

 

Docker란 무엇입니까? | AWS

Q: Docker로 어떤 작업을 할 수 있습니까? Docker를 사용하면 환경에 구애받지 않고 애플리케이션을 신속하게 배포 및 확장할 수 있으며 코드가 문제없이 실행될 것임을 확신할 수 있습니다. 이는 Doc

aws.amazon.com

저는 springboot에서 docker 배포전에 몇가지 설정해주었습니다.

(이부분은 필수가 아니고 테스트를 쉽게하기 위해 설정을 변경했습니다)

 

build.gradle 부분에

jar {
    enabled = false
}

을 추가했습니다. 스프링부트 2.5.0이후 plain.jar가 만들어지기때문에 꺼두었습니다.

또한 jar 파일 생성 파일명을 수정했습니다. 프로젝트를 빌드하면 프로젝트명+버젼+jar로 생성되는데 아래와 같은 설정을

build.gradle에 추가했습니다.

bootJar{
    archivesBaseName = 'app'
    archiveFileName = 'app.jar'
    archiveVersion = "0.0.0"
}

이제 build시 app.jar 이름으로 생성됩니다. 테스트를 위함이니 따라하지 않아도 됩니다!

 

이제 도커 파일 프로젝트 루트에 Dockerfile이라는 이름으로 파일을 생성합니다.

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

내용은 openjdk를 이용하여 타겟 디렉터리의 jar를 컨테이너의 app.jar로 넣고 실행한다는 것입니다.

 

이제 할일은 workflow에 도커 빌드를 추가하면 됩니다.

- name: Docker build 항목이 추가 되었습니다.

name: Java CI with Gradle

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Set up JDK 11
      uses: actions/setup-java@v2
      with:
        java-version: '11'
        distribution: 'adopt'
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
    - name: Build with Gradle
      run: ./gradlew build
    - name: Docker build
      run: |
       docker build -t spring-cicd .

빌드후 spring-cicd라는 이름으로 도커 이미지를 만들게 되었습니다.

이제 해야 할 일은 만들어진 이미지를 dockerhub에 올려두고 그 이미지를 배포서버에서 가져와서 실행하면됩니다

 

도커허브에 가입합니다.

https://hub.docker.com/

 

Docker Hub Container Image Library | App Containerization

We and third parties use cookies or similar technologies ("Cookies") as described below to collect and process personal data, such as your IP address or browser information. You can learn more about how this site uses Cookies by reading our privacy policy

hub.docker.com

먼저 테스트를 위해 내 컴퓨터에서 테스트를 위해 도커가 설치되어있어야합니다.

현재 내 프로젝트 위치에서 터미널을 열고 도커를 빌드해봅니다. 

docker build -t spring-cicd .

빌드시 spring-cicd라는 별명을 주었습니다. 앞으로 도커 이미지 명으로 쓸 것입니다.

이제 이것을 dockerhub에 푸쉬를 해보겠습니다.

 

터미널에서 docker login 입력을 통해 도커허브에 로그인한뒤 아래 작업을 합니다.

docker tag spring-cicd [내계정]/spring-cicd
docker push [내계정]/spring-cicd

[내 계정]부분에는 dockerhub에 가입했을때 아이디를 적으면 됩니다.

그러면 dockerhub에 이미지가 올라간 것을 확인 할 수 있습니다. 버젼을 주지않았으므로 최신 버젼(latest)으로 표시됩니다

 

이제 할 작업은 

github에서 빌드 -> 도커 이미지 생성 -> 도커 허브 푸쉬 

입니다.

 

다시 깃헙 프로젝트 리파지토리로 들어와 제일 오른쪽 Settings 탭에 들어갑니다.

왼쪽 메뉴에 Secret이 있는데 New repository secret 을 누릅니다.

여기서 USERNAME에 도커허브 아이디

PASSWORD에서 도커허브 비밀번호를 입력합니다. 이것들은 환경변수로 사용할 예정입니다.

 

workflow에 배포내용을 추가합니다.

 

name: Java CI with Gradle

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2
    - name: Set up JDK 11
      uses: actions/setup-java@v2
      with:
        java-version: '11'
        distribution: 'adopt'
    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
    - name: Build with Gradle
      run: ./gradlew build
    - name: Docker build
      run: |
       docker login -u ${{ secrets.USERNAME }} -p ${{ secrets.PASSWORD }}
       docker build -t spring-cicd .
       docker tag spring-cicd [계정명]/spring-cicd:${GITHUB_SHA::7}
       docker push [계정명]/spring-cicd:${GITHUB_SHA::7}

이제 내가 커밋을 하면 커밋 해쉬값이 도커의 버젼으로 들어갑니다. 이것을 이용하면 커밋과 버젼별 관리가 가능하게됩니다.

빌드후 자동으로 도커허브에 이미지를 업로드를 하도록 만들었습니다.

 

이제 할일은 도커허브에 올린 이미지를 가져와서 배포만 하면됩니다. 배포는 aws ec2를 이용하기로했습니다.

ec2 서버를 만드는 내용은 생략하겠습니다. 포트는 80번을 열어두었습니다.

아마존 Linux를 이미지를 이용했고 리눅스 서버에 도커를 설치합니다.

sudo yum update -y
sudo yum install -y docker
sudo service docker start
sudo systemctl enable docker
sudo usermod -a -G docker ec2-user

 

docker도 설정까지 되면  이제 다 끝났습니다. docker hub에 이미지를 가져와서 실행하기만 하면됩니다.

sudo docker pull [계정명]/spring-cicd
혹은
sudo docker pull [계정명]/spring-cicd:[최신버젼]

도커 실행

docker run -d -p 80:8080 [계정명]/spring-cicd:[버젼]

톰캣의 8080포트를 맵핑해서 80에 띄워줍니다.

 

이제 외부아이피로 접근해보면

 

배포 완료.

 

한가지 더 고민할 점이 있습니다.

배포를 하다보면, 배포할때마다 이미지를 받아오고 실행하는 것도 자동화 할 수 없을까 고민하게됩니다.

이 부분은 회사의 정책에 따라 다르긴합니다만 테스트이기때문에 이 부분도 자동화해보겠습니다.

 

이번에 사용할것은 ssh-action입니다. 터미널에서 작업을 자동화 할수 있습니다.

ssh 키를 우선 세팅합니다. 내 컴퓨터에서 키를 만들기 위해 CMD 터미널을 띄웁니다.

배포할 서버에 public 키를 넣어두고 private 키로 접근할 예정입니다.

https://github.com/appleboy/ssh-action

 

GitHub - appleboy/ssh-action: GitHub Actions for executing remote ssh commands.

GitHub Actions for executing remote ssh commands. Contribute to appleboy/ssh-action development by creating an account on GitHub.

github.com

 

 

ssh-keygen -t rsa -b 4096 -C "[내메일]" -f spring-cicd

저는 이런식으로 키를 생성했습니다. 생성하게되면 spring-cicd, spring-cicd.pub 파일이 생깁니다.

 

공개키는 AWS 서버의 ~/.ssh 경로의 authorized_keys에다가 붙여넣었습니다.

이제 spring-cicd 라는 파일에 담긴 개인키인데 이것을 복사하여

GITHUB SECRET의 PRIVATE_KEY로 등록합니다.

 

이제 워크플로우를 조금만 고쳐주면됩니다.

 

name: Java CI with Gradle

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  build:

    runs-on: ubuntu-20.04

    steps:
      - uses: actions/checkout@v2
      - name: Set up JDK 11
        uses: actions/setup-java@v2
        with:
          java-version: '11'
          distribution: 'adopt'
      - name: Grant execute permission for gradlew
        run: chmod +x gradlew
      - name: Build with Gradle
        run: ./gradlew build
      - name: Docker build
        run: |
          docker login -u ${{ secrets.USERNAME }} -p ${{ secrets.PASSWORD }}
          docker build -t spring-cicd .
          docker tag spring-cicd [계정명]/spring-cicd:${GITHUB_SHA::7}
          docker push [계정명]/spring-cicd:${GITHUB_SHA::7}
      - name: Deploy
        uses: appleboy/ssh-action@master
        with:
          host: 서버명[~~ap-northeast-2.compute.amazonaws.com로 시작하는 서버명을 적음]
          username: ec2-user
          key: ${{ secrets.PRIVATE_KEY }}
          envs: GITHUB_SHA
          script: |
            docker pull [계정명]/spring-cicd:${GITHUB_SHA::7}
            docker tag [계정명]/spring-cicd:${GITHUB_SHA::7} spring-cicd
            docker stop server
            docker run -d --rm --name server -p 80:8080 spring-cicd

이제 이렇게하면 직접 도커허브에 접속해서 이미지를 가져올 필요없이 자동으로 

이미지를 가져와 띄워주게됩니다 😆

 

https://github.com/etff/github-actions

 

GitHub - etff/github-actions

Contribute to etff/github-actions development by creating an account on GitHub.

github.com