ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • API서버 배포하기(Docker + Aws + Github)
    graphst프로젝트 2023. 8. 11. 19:16

    ※ 리눅스 EC2 인스턴스가 준비되어 있다는 가정하에 작성되었습니다.

     

    이제 코드를 다 짰으니 접근할 수 있게 서버를 띄워야겠죠 AWS에서 제공하는 EC2 인스턴스를 사용할 겁니다.

    EC2 인스턴스 관련 포스팅은 워낙 양이 방대하니 제가 설명하는 것보단 월씬 양질의 정보를 얻을 수 있을 테니 따로 다루진 않겠습니다.

     

    일단 인스턴스를 연결하고 시작하겠습니다.

    aws에서 연결할 수 있게 친절하게 알려줄 겁니다.

    ssh -i "graphst.pem" <내 인스턴스>.amazonaws.com

     

    Docker Install

    인스턴스에 docker를 설치해 줄 겁니다.

    EC2에 docker를 설치하는 방법 또한 조금만 검색해 보면 많이 나오니 apt에 도커 레포지토리를 설정해서 docker를 설치하고 와주세요.

     

    Github Actions

    먼저 pipeline에서 돌릴 workflow를 작성할 겁니다.

    더 밑을 보면 사른사람들이 만들어놓은 워크플로도 있습니다.

    name: CICD
    
    on:
      // main에 푸시되면 실행하겠다는 뜻
      push:
        branches: [main]
    
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout
            uses: actions/checkout@v2
    
          - name: Set up Docker Buildx
            uses: docker/setup-buildx-action@v1
    
          - name: Login to DockerHub
            uses: docker/login-action@v1
            with:
              username: ${{ secrets.DOCKERHUB_USERNAME }}
              password: ${{ secrets.DOCKERHUB_TOKEN }}
    
          - name: Build and push
            id: docker_build
            uses: docker/build-push-action@v2
            with:
              builder: ${{ steps.buildx.outputs.name }}
              push: true
              tags: ${{ secrets.DOCKERHUB_USERNAME }}/my-web
    
      # 배포
      deploy:
        needs: build
        name: Deploy
        runs-on: [self-hosted, graphst] # AWS ./configure에서 사용할 label명
        steps:
          - name: Login to ghcr
            uses: docker/login-action@v1
            with:
              registry: ghcr.io
              username: ${{ github.actor }}
              password: ${{ secrets.GHCR_TOKEN }}
    
          - name: Login to DockerHub
            uses: docker/login-action@v1
            with:
              username: ${{ secrets.DOCKERHUB_USERNAME }}
              password: ${{ secrets.DOCKERHUB_TOKEN }}
    
          - name: Docker run
            run: |
              docker stop my-web && docker rm my-web && docker rmi ${{ secrets.DOCKERHUB_USERNAME }}/my-web:latest
    
              docker pull ${{ secrets.DOCKERHUB_USERNAME }}/my-web:latest
    
              docker run -d -p 80:4000 -e CLIENT_URL=${{ secrets.CLIENT_URL }} -e DB_PORT=${{ secrets.DB_PORT }} -e DB_DATABASE=${{ secrets.DB_DATABASE }} -e DB_USERNAME=${{ secrets.DB_USERNAME }} -e DB_PASSWORD=${{ secrets.DB_PASSWORD }} -e DB_HOST=${{ secrets.DB_HOST }} -e JWT_SECRET_KEY=${{ secrets.JWT_SECRET_KEY }} --name my-web ${{ secrets.DOCKERHUB_USERNAME }}/my-web:latest

    전 위처럼 작성해 주었습니다.

    • build: Docker hub에 로그인하고 이미지를 빌드해 푸시합니다. 여기서 빌드할 때 Dockerfile을 사용합니다.
    • deploy: container registry에 로그인 후 도커 허브에 로그인합니다. 도커 레포지토리가 공개돼있으면 허브 로그인은 안 해도 됩니다. docker hub에서 혹시 실행 중인 이미지를 닫고 마지막으로 푸시된 이미지를 당겨 실행시켜 줍니다.

    도커 이미지를 실행할 때 환경변수를 넣어줬습니다.

    제가 만든 API는 4000 포트에서 실행되게 만들었으니 포트는 80 -> 4000 포트로 맵핑시켰습니다.

     

    runs-on옵션에서 grapht라고 작성한 부분에는 원하시는 아무 라벨이나 작성하시면 됩니다. self-hosted runner가 딱 하나라면 아래처럼만 써도 충분합니다.

    runs-on: [self-hosted]

     

    label옵션은 계속해서 늘려서 작성할 수 있습니다.

    runs-on: [self-hosted, A, B, ...]

     

    jobs는 독립적으로 실행됩니다.

    builddeploy는 적절히 잘라서 작성해 주세요. 저 같은 경우 코드는 변하는 게 없고 환경변수만 수정했다 싶으면 deploy만 돌리기 위해 로그인을 포함해 잘라주었습니다.

     

     

    Runner

    Settings에 있는 Runners를 등록해 줄 겁니다. 리눅스 인스턴스니까 리눅스를 선택해 줍니다.

     

    Optional을 제외하고 터미널에 복사해서 실행해 주세요.

    중간에 이름 뭐로 할 건지 등등 질문 나오는데 만약 위에 워크 플로 작성했을 때 label이름 작성하셨다면 Enter any additional label 에서 해당 label을 일치시켜 주세요

    ./run.shnohup ./run.sh &로 실행해 줍시다 nohup <쉘 스크립트> &는 백그라운드로 실행하겠다는 의미입니다.

    nohup를 사용해 쉘 스크립트를 데몬으로 실행시켜 현재 인스턴스가 연결된 터미널세션이 꺼져도 남아있게 될 겁니다.

     

    DockerFile

    이제 마지막으로 도커 이미지 빌드 시에 사용할 dockerfile을 작성하면 됩니다.

    FROM node:16.20.0
    
    RUN mkdir /app
    WORKDIR /app
    COPY . .
    RUN npm ci
    RUN npm install -g pm2
    RUN npm run build
    
    CMD [ "pm2-runtime", "start", "node dist/entry.js" ]

    node이미지는 해당 패키지에서 사용 중인 의존성을 잘 확인하고 사용하시면 됩니다.

    app디렉토리를 작업 디렉토리로 지정합니다. 이 이후부턴 명령이 해당 디렉토리 경로에서 실행됩니다.

    COPY를 사용해 모든 파일을 현 디렉토리로 복사해올 겁니다. (뒤쪽점이 복사될 위치입니다.)

     

    그리고 모듈 설치하고 pm2 설치하고 빌드해서 적절한 엔트리파일을 pm2로 실행시켜 주면 됩니다. pm2는 데몬으로 실행시켜 백그라운드에서 돌리기 위해 사용했습니다.

     

    별거 없죠?? 마지막으로 잘 실행됐는지 확인해 볼게요.

    인스턴스가 연결된 터미널로 가겠습니다. 아래 명령어로 돌고 있는 pm2를 확인해주세요

    docker exec -it <도커 id> pm2 list
    
    // id는 docker ps로 확인

     

     

    도커를 실행했을 때 추가해 준 환경변수가 잘 들어갔나 확인하고 싶다면 아래 명령어로 확인할 수 있습니다.

    docker exec -it <도커 id> env

     

    그냥 도커 컨테이너 bash에 접근해서 dockerfile대로 잘 들어갔는지 확인해 봅시다. 잘 있군요 빌드도 잘 되었고요

    docker exec -it <도커 id> /bin/bash
    
    ls -al
    
    .
    ..
    dist
    기타등등

     

    마치며...

    이제 main으로 푸시하면 자동으로 배포될 겁니다.

    지금은 docker build시점에 dist를 만들고 있는데 나중엔 워크 플로에서 빌드를 끝내고 docker에 dist만 올릴 생각이에요 지금은 쓸대 없는것도 다 들어가 있죠

     

    제가 처음 기획했던 graphst프로젝트 포스팅은 여기까지입니다.

    당분간 graphst관련 포스팅은 거의 없겠지만 아직 많이 부족한 필요한 프레임워크다 보니 열심히 확장해나갈 생각입니다.

    마이너 버전은 아직도 0이고 패치 버전만 엄청나게 올라가고 있죠...

     

    마지막으로 두서없는 긴 글 읽어 주셔서 너무 감사합니다!

     

     

     

     

     

    ...

    혹시라도 관심 있으시면 깃헙 와서 ⭐️를 눌러주심.. 매우 감사..

Designed by Tistory.