Docker와 GitHub Actions

이지훈·2023년 2월 11일

Docker

목록 보기
2/2

1. GitHub Actions?

GitHub Actions는 GitHub에서 제공하는 CI/CD를 위한 서비스입니다.

GitHub Actions를 사용하면 자동으로 코드 저장소에서 어떤 이벤트(event)가 발생했을 때 특정 작업이 일어나게 하거나 주기적으로 어떤 작업들을 반복해서 실행시킬 수도 있습니다.

사람이 매번 직접 하기에는 비효율적인데다가 실수할 위험도 있기 때문에 GitHub Actions와 같은 자동화시키는 것이 유리합니다.

타 CI/CD 도구와 비교하여 설치가 필요없어 접근성이 높고 설정이 간편하다는 특징이 있습니다.

2. 무엇을 하고자 하는가?

어떤 새로운 코드가 main 브랜치에 push되면 GitHub Actions를 통해 소프트웨어를 build하고 서버에 deploy 하고자 합니다.

🔔 주의사항
메인에 푸쉬할 때, yml 또는 properties 파일을 .gitignore 에 등록해 보안성도 고려해야 합니다

3. 어떻게 설정 하는가?

우선 깃허브 설정이 필요하다

클릭 후


다음 파일이 보이는데 이곳에 아래 코드를 넣으면 된다.

name: Backend CD
on:
  push:
    branches: [ main ]        # 메인브랜치에 푸쉬가 되면

jobs:
  deploy:                     # deploy라는 작업을 할것이고
    runs-on: ubuntu-latest    # 우분투 최신버전으로 진행 할게요
    steps:                    # 순서대로 실행하겠습니다
    
      - name: 저장소 Checkout        
        uses: actions/checkout@v3   # 레포지토리 한번 체크할게요
        
        
      - name: yml 생성
        run: touch application.yml  # 비어있는 yml 파일 하나 만들게요    
        
        
        
      - name: secrets에 있는 APPLICATION 내용을 yml 파일에 덮어쓰기
        run: echo "${{secrets.APPLICATION}}" > ./src/main/resources/application.yml   # APPLICATION에 있는 내용 저 경로에 복붙좀 할게요

      
      - name: yml 파일 다운받을 수 있게 업로드
        uses: actions/upload-artifact@v3.1.2   
        with:
          name: application.yml
          path: ./src/main/resources/
          
          
          
      - name: gradlew 실행권한 주기
        run: chmod +x gradlew
      
      
      - name: 스프링부트 애플리케이션 빌드 
        run: ./gradlew clean build 

      - name: 도커 이미지 빌드 
        run: docker build -t ${{ secrets.DOCKER_HUB_REPO }} .

      - name: Docker Hub 로그인 
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Docker Hub 퍼블리시 
        run: docker push ${{ secrets.DOCKER_HUB_REPO }}

      - name: WAS 인스턴스 접속 및 애플리케이션 실행 
        uses: appleboy/ssh-action@v0.1.6
        with:
          host: ${{ secrets.EC2_SERVER_HOST }}
          username: ${{ secrets.SERVER_USERNAME }}
          key: ${{ secrets.PRIVATE_KEY }}
          script: |
            docker stop ${{ secrets.CONTAINER_NAME }}
            docker rm ${{ secrets.CONTAINER_NAME }}
            docker image rm $(docker images -q)
            docker pull ${{ secrets.DOCKER_HUB_REPO }}
            docker run -d --name ${{ secrets.CONTAINER_NAME }} -p 8080:8080 ${{ secrets.DOCKER_HUB_REPO }}

${{ secrets.~~}} 이런 값들이 보이는데 이건 깃허브 안에서 설정이 가능하다
Settings -> Secrets and variables -> Actions -> New repository secret
그러면 다음의 화면이 보인다

이곳에 값들을 작성해주면 된다. 작성하게 되면 아래처럼 생기게 된다

그렇다면 각 이름의 값들은 어떤게 들어가는지 써놓는게 개발자의 도리겠쥬?

· APPLICATION: application.yml에 들어가는 값

· CONTAINER_NAME: 설정하고 싶은 컨테이너 이름 (아무거나 써도 ok)

· DOCKER_HUB_REPO: 도커허브에서 레포지토리를 만들었다면 사진을참고

· DOCKER_PASSWORD: 도커허브 로그인 패스워드

· DOCKER_USERNAME: 도커허브 로그인 유저이름 (소문자로)

· EC2_SERVER_HOST: ec2의 탄력적 ip ex) 111.111.111.111

· PRIVATE_KEY: ec2 생성시 받은 pem키를 BEGIN END 라인 포함해서 넣기

· SERVER_USERNAME: 우분투는 ubuntu, centos는 centos
다른 서버를 쓴다면 아래 링크 참조
https://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/managing-users.html

4. 결과 확인은 어떻게?

메인 브랜치로 푸시가 되면 사진과 같이 스크립트가 실행되고


완료가 되면 yml 파일 업로드, 이미지 생성 및 도커허브 업로드, 서버에서 실행이 된다


5. 어떤 에러를 마주했는가?

1. ssh.ParsePrivateKey: ssh: no key found
✔️ 해결
https://github.com/appleboy/ssh-action/issues/6
https://github.com/appleboy/ssh-action#setting-up-ssh-key

2. .gitignore 작동하지 않는 경우
✔️ 해결
https://growingarchive.tistory.com/244

3. dial tcp ~:22 i/o timeout
✔️ 해결
https://dev.to/tarohida/error-on-appleboyssh-action-dial-tcp-lookup-exampleexample-on-19202153-io-timeout-6ng

4. 실행하자마자 exit 될 경우
✔️ 해결
https://velog.io/@swhybein/Docker-%EC%8B%A4%ED%96%89%ED%95%98%EC%9E%90%EB%A7%88%EC%9E%90-exit-%EB%90%A0-%EA%B2%BD%EC%9A%B0

6. 느낀점

항상 느끼지만 배우는건 어렵고 적용하는건 더 어렵다....
공식문서도 뒤져보고 미쿸인들의 코멘트도 하나하나 까보고 이런저런 삽질들은 힘들다 ㅠㅠ
그럼에도 하고자 했던 일에 마침표가 찍힐 때 이 기분... 구글 사랑해요

📚 참고
GitHub Actions 워크플로우 관련1
GitHub Actions 워크플로우 관련2
GitHub Actions 워크플로우 관련3
ubuntu에서 docker 설치 하는 방법
도커 명령어 정리
Docker 사용시 sudo 없이 사용하기

0개의 댓글