GCP 이용 배포(artifact Registy +cloud run)

Featured image

이번 데브캠프에 참여하면서 배포하기가 있었는데 그동안 해온 aws가 아닌 gcp를 사용해 배포해보았다 한 15번 정도 실패했지만 성공함ㅎ

GCP란

Google Cloud Platform의 약자로, 구글에서 제공하는 클라우드 컴퓨팅 서비스로 aws 처럼 클라우드 기반의 컴퓨팅, 데이터베이스등의 서비스를 제공한다

aws가 아마존의 인프라를 사용해 애플리케이션을 개발, 배포, 관리할 수 있는것처럼 GCp는 구글의 인프라를 통해 애플리케이션을 개발, 배포, 관리 할 수 있다

도커 이미지 관리

aws에서는 도커 이미지 관리를 aws ECR을 사용해 했지만 GCP에서는 이와 비슷한 서비스로 Artifact Registry가 있다

둘 모두 컨테이너 이미지를 저장 및 관리 하는데 사용 되며, IAM을 사용해 접근 제어가 가능하다

둘의 차이점은 ECR은 컨테이너 이미지 관리가 중심이지만 Artifact Registry는 컨테이너 이미지 말고도 pip등 소프트웨어 패키지도 관리 할 수 있다

Compute Engine

GCp의 Compute Engine은 aws의 ec2와 다를 것이 없다고 생각해 aws의 Lambda 처럼 서버리스 아키텍쳐를 찾아봤다

GCP에서는 cloud run이 서버리스 컨테이너이다

서버리스로 운영되며 컨테이너 이미지를 실행한다 또한 클라우드 런은 트래픽에 따라 자동으로 확장되며 요청이 줄어들게 되면 자동으로 축소된다

사전 설정

  1. 구글 콘솔(https://cloud.google.com)에 접속해 계정 생성
  2. 프로젝트 생성 후 프로젝트의 아이디를 깃 시크릿에 GCP_PROJECT_ID로 저장
  3. gcp의 iam및 사용자 카테고리에 들어가 서비스 계정 들어가기(카테코리 없어도 눌러도 iam 안나오면 맨 아래의 모든제품보기 들어가 찾기)
  4. 서비스계층 만들기 눌러 만들기 이름 쓰고 계속하기 누르기만 하면 됨 역할에 Artifact Registry 관리자 container Registry 서비스 에이전트 cloud run 관리자 권한 부여 만일 vm엔진 쓰면 Compute 관리자도 권한 부여 iam 탭에 들어가 잘 들어있는지 확인

  5. 다시 서비스계정 탭에 들어가 만든 서비스계정 누르면 키라고 뜨는데 들어가서 json키 만들기
  6. 만든후 처음부터 끝까지를 GCP_SA_KEY라는 이름으로 깃 시크릿에 저장

  7. Artifact Registry탭에 들어가 활성화 (아티펙트 관리하는 Artifact Registry, Container Registry 둘의 차이는 Artifact Registry이 더 확장한 서비스다 ) 애의 기본 포트는 8080

8.cloud run 활성화 하기 (이거 깃액션 파일에 넣어도 되는데 혹시 모르니까)

vm 쓸시 기본 설정

vm 인스턴스 생성 그 탭에 들어가 ssh누르고 구글 아이디로 인증 누르면 커맨드가 나옴

# Update package index
sudo apt-get update

# Install Docker
sudo apt-get install -y docker.io

# Start Docker service
sudo systemctl start docker

# Enable Docker to start at boot
sudo systemctl enable docker

# GCP에 인증
gcloud auth configure-docker

# SSH 키 생성
ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa

# SSH 공개 키를 VM 인스턴스에 추가
gcloud compute instances add-metadata YOUR_INSTANCE_NAME \
    --metadata ssh-keys="YOUR_USERNAME:$(cat ~/.ssh/id_rsa.pub)"

도커 및 깃 액션 파일

도커 파일은 노드 이미지를 사용해 만들고 ARG로 변수를 선언하고 ENV로 사용한다 workdir로 설정하고 카피해온다 그 후 npm install과 npm run build를 한다

FROM node:alpine

#ARG로 변수 선언
ARG TYPEORM_HOST
ARG TYPEORM_PORT
ARG TYPEORM_USERNAME
ARG TYPEORM_PASSWORD
ARG TYPEORM_DATABASE
ARG TYPEORM_SYNCHRONIZE
ARG TYPEORM_LOGGING
ARG JWT_SECRET

ENV TYPEORM_HOST=$TYPEORM_HOST \
TYPEORM_PORT=$TYPEORM_PORT \
TYPEORM_USERNAME=$TYPEORM_USERNAME \
TYPEORM_PASSWORD=$TYPEORM_PASSWORD \
TYPEORM_DATABASE=$TYPEORM_DATABASE \
TYPEORM_SYNCHRONIZE=$TYPEORM_SYNCHRONIZE \
TYPEORM_LOGGING=$TYPEORM_LOGGING \
JWT_SECRET=$JWT_SECRET \
PORT=3000

LABEL creator="soi@dev_camp"
WORKDIR /app 
COPY . .
COPY package.json .
COPY package-lock.json .
RUN npm install
RUN npm run build
# 컨테이너 포트 노출
EXPOSE 3000
CMD ["node", "dist/main"]

포트 내보내기를 했지만 보니까 8080으로 되어있더라

깃액션 파일의 흐름은 브런치가 메인에 올라가면 구글 클라우드에 로그인하한다 프로젝트를 설정한 후 cloud run을 활성화 시켜준다(혹시 모르니까) 그후 도커를 쓴다고 설정하고 이미지를 만들고 artifact Registy에 올린다 그 후 클라우드 런에 들어가 풀받고 실행한다

name: Deploy to GCP

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Authenticate to Google Cloud
        uses: google-github-actions/auth@v1
        with:
          credentials_json: $

      - name: Set up Cloud SDK
        uses: google-github-actions/setup-gcloud@v1
        with:
          project_id: $

      - name: Enable APIs
        run: |
          gcloud services enable run.googleapis.com \
            artifactregistry.googleapis.com \
            --project=$

      - name: Configure Docker
        run: gcloud auth configure-docker

      - name: Build Docker image
        run: |
          docker build -t gcr.io/$/nestjs-app:$GITHUB_SHA \
            --build-arg TYPEORM_HOST=$ \
            --build-arg TYPEORM_PORT=$ \
            --build-arg TYPEORM_USERNAME=$ \
            --build-arg TYPEORM_PASSWORD=$ \
            --build-arg TYPEORM_DATABASE=$ \
            --build-arg TYPEORM_SYNCHRONIZE=$ \
            --build-arg TYPEORM_LOGGING=$ \
            --build-arg JWT_SECRET=$ \
            .

      - name: Push Docker image
        run: docker push gcr.io/$/nestjs-app:$GITHUB_SHA

      - name: Deploy to Cloud Run
        run: |
          gcloud run deploy nestjs-app \
            --image gcr.io/$/nestjs-app:$GITHUB_SHA \
            --platform managed \
            --region $ \
            --allow-unauthenticated \

vm 사용시 마지막 부분만 바꾸면 된다

 # Docker 이미지 가져오기 및 실행
            docker pull gcr.io/$/nestjs-app:$GITHUB_SHA
            docker stop nestjs-app || true
            docker rm nestjs-app || true
            docker run -d -p 3000:3000 --name nestjs-app gcr.io/$/nestjs-app:$GITHUB_SHA

클라우드런과 vm의 차이

모두 클라우드 환경에서 애플리케이션을 실행하기 위한 플랫폼