데브옵스

삽질기록 - NCP 에 프론트 서버 올리기 (with Docker, Github Actions)

ZestLee 2023. 5. 29. 01:57

개요

  • 비사이드에서 NCP 크레딧을 지원해 준다고 한다
  • 따라서 NCP 를 이용하여 프론트 서버를 올리려고 한다

목표

  • 특정 브랜치에 푸시하면 자동 배포가 되는 그런 CI/CD 구성을 만들고 싶었다
  • 도커를 이용하여 서버 위에 도커를 띄우고 그 안에서 Next.js 를 실행시켜서 도커는 3000번을 바라보게끔.. 그런 구성을 만들고 싶었다

필요하면 가장 아래 소스 코드부터 보시길... 깃헙 링크 걸어놓겠습니다

서버 생성 및 셋팅

  • 저렴이 서버인 Compact 로 만들기 위해서 VPC 가 아닌 Classic 버전을 사용했다 (NCP 너무 비쌈 인간적으로)
  • Compact Ubuntu 를 사용했다
  • Pubilc IP 를 할당 받고
  • ACG 를 0.0.0.0/0 , 포트는 80 을 열어줬다

NCR 생성

  • Container Registry 를 생성해 주었다
  • 그리고 이거 생성하기 전에 Object Registry 였나... 그거 먼저 생성하라 하는데 그것도 생성해 준다
  • Access key 랑 Secret key 는 NCP 홈페이지에서 마이페이지 > 계정관리 쪽 가면 인증키 보는 것이 있다. 거기에 써있는 것 가져다 쓰면 된다

아래는 workflow.yml 파일이다...

1. 첫번째 시도 - tar 파일로 도커를 올려 보자

  • 왜 다들 ECR NCR 을 사용하는지 몰랐다. 굳이 도커 허브를 만들지 않더라도 tar 파일로 압축하여 서버에 올리면 되는데, 왜 굳이 왜??

    - name: Build Docker image
      run: docker-compose build
    
    - name: Save Docker image as TAR
      run: docker save -o my-image.tar my-image:latest
    
    - name: Transfer TAR file to NCP server
      uses: appleboy/scp-action@master
      with:
        host: ${{ secrets.NCP_SERVER_IP }}
        username: ${{ secrets.NCP_SERVER_USERNAME }}
        password: ${{ secrets.NCP_SERVER_PASSWORD }}
        port: ${{ secrets.NCP_SERVER_PORT }}
        source: my-image.tar
        target: /path/to    
    
    - name: SSH into NCP server
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.NCP_SERVER_IP }}
        username: ${{ secrets.NCP_SERVER_USERNAME }}
        password: ${{ secrets.NCP_SERVER_PASSWORD }}
        port: ${{ secrets.NCP_SERVER_PORT }}
        script: |
          docker load -i /path/to/my-image.tar
          docker run -d --name my-container my-image:latest    
  • 이런 식으로 하면 NCP 서버에 tar 파일이 올라갔고, 그 하단에서 tar 파일을 load 해서 run 하면 됐다.

  • 하지만... 파일 저장을 할 때 tar 파일이 얼마나 될지 모르기 때문에... 그 저장 비용도 있고, 해당 파일을 왔다갔다 하면서 발생하는 요청 비용도 있을 거라고 한다

  • 또한 docker load 를 할 때 발생하는 비용도 있겠지...? 아무래도 압축 파일이다 보니

  • 또한 개발자가 테스트 할 때 도커 허브를 통해서 바로 받아 볼 수 있고, 동일한 도커 환경에서 실행도 가능하기 때문에... NCR 을 사용하는 쪽이 편리하다고 한다.

2. 바로 Back 해서 NCR 을 사용하는 쪽으로 하자

  • 말만 바로 Back 이지 사실 위와 같은 삽질을 2시간은 한 것 같다 ㅎㅎ;; 이게 다 성장의 고통인 것일까

    - name: Build Docker image
      run: docker-compose build
    
    - name: Login to NCP Container Registry
      uses: docker/login-action@v2
      with:
        registry: ${{ secrets.NCP_NCR }}
        username: ${{ secrets.NCP_NCR_ACCESS_KEY }}
        password: ${{ secrets.NCP_NCR_SECRET_KEY }}
    
    - name: Push Docker image
      run: docker push ${{ secrets.NCP_NCR }}/nextjs-docker:latest
  • 위처럼 하면 NCP_NCR~블라블라/nextjs-docker:latest 로 된 도커가 없다고 한다

  • 빌드는 docker compose 에서 설정한대로 되어있을 테니... 태그 이름을 바꿔주는 것을 추가해 주었다

  • 그런데 글을 쓰면서 생각해 보니... 요것도 docker-compose 에서 어떻게 해 주면 수정이 가능할 것 같기도 한다. (나중에 하자 너무 피곤)

  • 그리고 태그 네임은 내가 설정해 주기 나름인데... 요 생각을 왜 못했지

      - name: Build Docker image
        run: docker-compose build

      - name: Login to NCP Container Registry
        uses: docker/login-action@v2
        with:
          registry: ${{ secrets.NCP_NCR }}
          username: ${{ secrets.NCP_NCR_ACCESS_KEY }}
          password: ${{ secrets.NCP_NCR_SECRET_KEY }}

      - name: Set Tag Name
        run: docker image tag bside-test_front-service ${{ secrets.NCP_NCR }}/nextjs-docker:latest

      - name: Push Docker image
        run: docker push ${{ secrets.NCP_NCR }}/nextjs-docker:latest
  • 위처럼 설정된 tag 이름을 오른쪽처럼 바꿔주는 것이다
  • 그리고 그것을 push 시킨다

서버에서 pull 받기

      - name: Connect ssh
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.NCP_SERVER_IP }}
          username: ${{ secrets.NCP_SERVER_USERNAME }}
          password: ${{ secrets.NCP_SERVER_PASSWORD }}
          port: ${{ secrets.NCP_SERVER_PORT }}
          script: |
            echo ${{ secrets.NCP_NCR_SECRET_KEY }} | docker login -u ${{ secrets.NCP_NCR_ACCESS_KEY }} --password-stdin ${{ secrets.NCP_NCR }}
            docker pull ${{ secrets.NCP_NCR }}/nextjs-docker:latest
            if [[ $(docker ps -q) ]]; then
              docker stop $(docker ps -q)
              docker rm $(docker ps -aq)
            else
              echo "No running containers found."
            fi
            docker run -d -p 80:3000 --name nextjs-docker ${{ secrets.NCP_NCR }}/nextjs-docker:latest
            docker image prune -f
            docker logout
  • docker login 을 한다
  • docker 에서 아까 올렸던 태그 네임의 이미지를 pull 받는다
  • 만약에 도커 올려져있는 무언가가 있다면 stop 시키고 삭제한다 (띄워진 게 있거나 이미 만들어진게 있으면 다시 안 만들어진다.) >> 요것은 나중에 해시값 붙여서 하는 게 나을지도
  • 80 포트에서 도커 내부 3000 포트로 띄워진 next 앱에 포트포워딩 하도록 한다

푸시 테스트를 해 보자

  • 잘 된다. ㅎ
  • 혹시 모르니 다 열어뒀던 ACG 를 다시 다 닫아두도록 하자

느낀점

  • 서버를 잘 몰라서 거의 20시간은 쓴 듯하다
  • 또 까먹지 않기 위해서 글을 적는데.. 사실 이거 말고도 했던 삽질이 너무 많은데 까먹을듯하다.. 까먹으면 또 찾아보면 되지 뭐 ^_ㅠ.....

소스 참고::: https://github.com/zestlee1106/bside-test