Heroku의 Node.js 앱을 Cloud Run으로 마이그레이션


이 튜토리얼에서는 Heroku에서 실행 중인 Node.js 웹 앱을 Google Cloud의 Cloud Run으로 마이그레이션하는 방법을 설명합니다. 이 가이드는 Heroku의 앱을 Google Cloud의 관리형 서비스로 마이그레이션하려는 설계자와 제품 소유자를 대상으로 합니다.

Cloud Run은 HTTP 요청으로 호출 가능한 스테이트리스(Stateless) 컨테이너를 실행하는 관리형 컴퓨팅 플랫폼입니다. 이 플랫폼은 오픈소스 Knative를 기반으로 구축되므로, 플랫폼 간 이동이 가능하고 컨테이너 워크플로와 지속적 배포를 위한 표준을 지원합니다. Cloud Run 플랫폼은 Google Cloud 제품군과도 원활하게 통합되므로 이동성, 확장성, 복원력이 우수한 앱의 설계와 개발이 더 쉬워졌습니다.

이 튜토리얼에서는 Heroku에서 Node.js로 제작되고 Heroku Postgres를 백업 서비스로 사용하는 앱을 Google Cloud로 마이그레이션하는 방법을 알아봅니다. 웹 앱은 컨테이너화되어 Cloud Run에서 호스팅되며 PostgreSQL용 Cloud SQL을 영구 레이어로 사용합니다.

이 가이드에서는 태스크를 확인하고 만들 수 있는 간단한 앱인 Tasks를 사용합니다. 이러한 태스크는 현재 Heroku에서 실행 중인 앱의 배포에 있는 Heroku Postgres에 저장됩니다.

이 튜토리얼에서는 개발자가 Heroku의 기본 기능에 익숙하고 Heroku 계정을 보유하고 있거나 Heroku 계정에 대한 액세스 권한이 있다고 가정합니다. 또한 Cloud Run, Cloud SQL, Docker, Node.js에 익숙하다고 가정합니다.

목표

  • Docker 이미지를 빌드하여 Cloud Run에 앱을 배포합니다.
  • Google Cloud로 마이그레이션한 후 백엔드로 사용할 PostgreSQL용 Cloud SQL 인스턴스를 만듭니다.
  • Node.js 코드를 살펴보면서 Cloud Run이 Cloud SQL에 연결되는 방법을 이해하고 Heroku에서 Cloud Run으로 마이그레이션하는 데 코드 변경이 필요한지 확인합니다.
  • Heroku Postgres의 데이터를 PostgreSQL용 Cloud SQL로 마이그레이션합니다.
  • Cloud Run에 앱을 배포합니다.
  • 배포된 앱을 테스트합니다.

비용

이 문서에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

프로젝트 사용량을 기준으로 예상 비용을 산출하려면 가격 계산기를 사용하세요. Google Cloud를 처음 사용하는 사용자는 무료 체험판을 사용할 수 있습니다.

Heroku에 사용된 리소스에 대한 비용도 청구될 수 있습니다.

시작하기 전에

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  4. Enable the Cloud SQL, Cloud Build, Cloud Run, Container Registry, Service Networking, Serverless VPC Access APIs.

    Enable the APIs

  5. 프로젝트에 다음 역할이 있는지 확인합니다. Cloud Run > Cloud Run Admin, Cloud Storage > Storage Admin, Cloud SQL > Cloud SQL Admin, Compute Engine > Compute Network Admin, Resource Manager > Project IAM Admin, Cloud Build > Cloud Build Editor, Serverless VPC Access > Serverless VPC Access Admin, Logging > Logs Viewer, Service Accounts > Service Account Admin, Service Accounts > Service Account User, and Service Usage > Service Usage Consumer

    역할 확인

    1. Google Cloud 콘솔에서 IAM 페이지로 이동합니다.

      IAM으로 이동
    2. 프로젝트를 선택합니다.
    3. 주 구성원 열에서 이메일 주소가 있는 행을 찾습니다.

      이메일 주소가 열에 없으면 역할이 없는 것입니다.

    4. 이메일 주소가 있는 행에 대해 역할 열에서 역할 목록에 필요한 역할이 있는지 확인합니다.

    역할 부여

    1. Google Cloud 콘솔에서 IAM 페이지로 이동합니다.

      IAM으로 이동
    2. 프로젝트를 선택합니다.
    3. 액세스 권한 부여를 클릭합니다.
    4. 새 주 구성원 필드에 이메일 주소를 입력합니다.
    5. 역할 선택 목록에서 역할을 선택합니다.
    6. 역할을 추가로 부여하려면 다른 역할 추가를 클릭하고 각 역할을 추가합니다.
    7. 저장을 클릭합니다.
  6. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  7. Google Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다.

  8. Enable the Cloud SQL, Cloud Build, Cloud Run, Container Registry, Service Networking, Serverless VPC Access APIs.

    Enable the APIs

  9. 프로젝트에 다음 역할이 있는지 확인합니다. Cloud Run > Cloud Run Admin, Cloud Storage > Storage Admin, Cloud SQL > Cloud SQL Admin, Compute Engine > Compute Network Admin, Resource Manager > Project IAM Admin, Cloud Build > Cloud Build Editor, Serverless VPC Access > Serverless VPC Access Admin, Logging > Logs Viewer, Service Accounts > Service Account Admin, Service Accounts > Service Account User, and Service Usage > Service Usage Consumer

    역할 확인

    1. Google Cloud 콘솔에서 IAM 페이지로 이동합니다.

      IAM으로 이동
    2. 프로젝트를 선택합니다.
    3. 주 구성원 열에서 이메일 주소가 있는 행을 찾습니다.

      이메일 주소가 열에 없으면 역할이 없는 것입니다.

    4. 이메일 주소가 있는 행에 대해 역할 열에서 역할 목록에 필요한 역할이 있는지 확인합니다.

    역할 부여

    1. Google Cloud 콘솔에서 IAM 페이지로 이동합니다.

      IAM으로 이동
    2. 프로젝트를 선택합니다.
    3. 액세스 권한 부여를 클릭합니다.
    4. 새 주 구성원 필드에 이메일 주소를 입력합니다.
    5. 역할 선택 목록에서 역할을 선택합니다.
    6. 역할을 추가로 부여하려면 다른 역할 추가를 클릭하고 각 역할을 추가합니다.
    7. 저장을 클릭합니다.

환경 설정

  1. Cloud Shell을 엽니다.

    Cloud Shell 열기

  2. Cloud Shell에서 이 튜토리얼에 사용된 Google Cloud CLI의 환경 변수 및 기본값을 설정합니다.

    gcloud config set project PROJECT_ID
    gcloud config set run/region us-central1
    

    PROJECT_ID를 프로젝트 ID로 바꿉니다.

아키텍처

다음 그림 두 개는 Heroku의 웹 앱 아키텍처(현재 상태)와 Google Cloud의 아키텍처 레이아웃(빌드할)을 간략하게 보여줍니다.

현재 Heroku의 아키텍처
그림 1. 현재 Heroku의 아키텍처

현재 Heroku에 배포된 Tasks 앱은 1개 이상의 웹 dyno로 구성되어 있습니다. 백그라운드 작업 및 예약된 태스크에 더 적합한 작업자 dyno와 달리, 웹 dyno는 HTTP 트래픽을 수신하고 응답할 수 있습니다. 이 앱은 Node.js용 Mustache 템플릿 라이브러리를 사용하여 Postgres 데이터베이스에 저장된 태스크를 표시하는 색인 페이지를 제공합니다.

개발자는 HTTPS URL을 통해 앱에 액세스할 수 있습니다. 해당 URL에 /tasks 경로를 사용하면 새 태스크를 만들 수 있습니다.

현재 Heroku의 아키텍처
그림 2. Google Cloud에 빌드된 아키텍처

Google Cloud에서 Cloud Run은 Tasks 앱을 배포하는 서버리스 플랫폼으로 사용됩니다. Cloud Run은 요청에 따라 스테이트리스(Stateless) 컨테이너를 실행하도록 설계되었습니다. 또한 자동 확장되거나 트래픽을 제공하지 않을 때는 0으로 축소되는 컨테이너화된 앱을 지원하기 위해 관리형 서비스를 사용해야 하는 경우에 적합합니다.

Heroku에서 사용되는 구성요소와 Google Cloud 간 연결 관계

다음은 Heroku 플랫폼의 구성요소와 Google Cloud 간 연결 관계를 보여주는 표입니다. 이 연결 관계를 사용하면 이 가이드에 설명된 아키텍처를 Heroku에서 Google Cloud로 변환할 수 있습니다.

구성요소 Heroku 플랫폼 Google Cloud
컨테이너 Dynos: Heroku는 Heroku앱을 빌드하고 확장할 때 컨테이너 모델을 사용합니다. dyno라고 하는 이 Linux 컨테이너는 Heroku 앱의 리소스 요구를 지원하기 위해 지정된 수까지 확장할 수 있습니다. 앱의 메모리 및 CPU 요구사항을 기준으로 다양한 dyno 유형 중에서 선택할 수 있습니다. Cloud Run 컨테이너: Google Cloud는 완전 관리형 환경 또는 Google Kubernetes Engine(GKE) 클러스터에서 실행할 수 있는 스테이트리스(Stateless) 컨테이너에서 컨테이너식 워크로드 실행을 지원합니다.
웹 앱 Heroku 앱: Dyno는 Heroku 앱의 구성 요소입니다. 일반적으로 앱은 웹 dyno와 작업자 dyno를 조합한 1개 이상의 dyno 유형으로 구성됩니다. Cloud Run 서비스: 웹 앱은 Cloud Run 서비스로 모델링할 수 있습니다. 각 서비스는 자체 HTTPS 엔드포인트를 가져와 서비스 엔드포인트에서 발생하는 트래픽에 따라 0에서 N까지 자동으로 확장 또는 축소할 수 있습니다.
데이터베이스 Heroku Postgres: PostgreSQL을 기반으로 하는 Heroku의 DaaS(서비스로서의 데이터베이스)입니다. Cloud SQL: Google Cloud의 관계형 데이터베이스용 관리형 데이터베이스 서비스로,

Tasks 웹 앱 샘플을 Heroku에 배포

다음 섹션에서는 Heroku에서 사용할 명령줄 인터페이스(CLI)를 설정하고, GitHub 소스 저장소를 클론하고, 앱을 Heroku에 배포하는 방법을 보여줍니다.

Heroku용 명령줄 인터페이스 설정

이 튜토리얼에서는 Cloud Shell에서 Heroku CLI를 실행하며 Heroku API 키를 사용하여 인증해야 합니다. Cloud Shell에서 실행하는 경우 Heroku CLI는 비밀번호 또는 웹 기반 인증을 사용하여 인증할 수 없습니다.

또는 로컬 터미널에서 샘플을 실행하는 경우 Heroku CLI 인증 방법을 사용할 수 있습니다. 로컬 터미널에서 튜토리얼을 실행하는 경우 Google Cloud CLI, git, Docker도 설치해야 합니다.

  1. Heroku용 웹 콘솔에 로그인합니다. 그 후 계정 설정 페이지에서 API 키 값을 복사합니다.

  2. Cloud Shell에서 Heroku CLI를 설치합니다.

  3. Cloud Shell에서 Heroku CLI를 설치합니다. 비밀번호를 입력하라는 메시지가 표시되면 콘솔에 로그인할 때 사용한 비밀번호가 아닌 Heroku 콘솔에서 복사한 API 키 값을 입력합니다.

    heroku login --interactive
    

소스 저장소 클론

  1. Cloud Shell에서 Tasks 앱 GitHub 저장소 샘플을 클론합니다.

    git clone https://github.com/GoogleCloudPlatform/migrate-webapp-heroku-to-cloudrun-node.git
    
  2. 디렉터리를 저장소를 클론하여 만든 디렉터리로 변경합니다.

    cd migrate-webapp-heroku-to-cloudrun-node
    

    디렉터리에는 다음과 같은 파일이 포함됩니다.

    • 웹 앱에서 제공하는 경로의 코드가 포함된 index.js라는 Node.js 스크립트
    • 웹 앱의 종속 항목이 표시된 package.jsonpackage-lock.json 파일. 앱을 실행하려면 이러한 종속 항목을 설치해야 합니다.
    • 앱 시작 시 실행할 명령어를 지정하는 Procfile 파일. 앱을 Heroku에 배포하려면 Procfile 파일을 만들어야 합니다.
    • '/' 경로의 웹 앱에서 제공하는 HTML 콘텐츠가 포함된 views 디렉터리
    • .gitignore 파일

Heroku에 앱 배포

  1. Cloud Shell에서 Heroku 앱을 만듭니다.

    heroku create
    

    앱을 위해 만든 이름을 기록해 둡니다. 다음 단계에서 이 값이 필요합니다.

  2. Heroku 앱 이름의 환경 변수를 만듭니다.

    export APP_NAME=APP_NAME
    

    APP_NAMEheroku create 명령어가 반환한 앱 이름으로 바꿉니다.

  3. Heroku Postgres 부가기능을 추가하여 PostgreSQL 데이터베이스를 프로비저닝합니다.

    heroku addons:create heroku-postgresql:mini
    
  4. 부가기능이 제대로 추가되었는지 확인합니다.

    heroku addons
    

    Postgres 부가기능이 성공적으로 추가되면 다음과 비슷한 메시지가 표시됩니다.

    Add-on               Plan     Price       State
    -----------------    -----    --------    -----
    heroku-postgresql    mini     5$/month    created
    
  5. 앱을 Heroku에 배포합니다.

    git push heroku master
    
  6. 다음 명령어를 실행하여 DATABASE_URL의 값을 확인합니다.

    heroku config
    

    DATABASE_URL에 대해 검색된 값을 기록해 둡니다. 다음 단계에서 이 값이 필요합니다.

  7. Docker 컨테이너 실행

    docker run -it --rm postgres psql "DATABASE_URL"
    

    DATABASE_URL을 이전 단계에서 기록한 Heroku Postgres URL로 바꿉니다.

  8. Docker 컨테이너에서 다음 명령어를 사용하여 TASKS 테이블을 만듭니다.

    CREATE TABLE TASKS
    (DESCRIPTION TEXT NOT NULL);
    
  9. 컨테이너를 종료합니다.

    exit
    
  10. Cloud Shell에서 다음 명령어를 실행하여 Heroku 앱의 웹 URL을 가져옵니다.

    heroku info
    
  11. 브라우저 창에서 웹 URL을 엽니다. 앱은 다음 스크린샷과 같이 표시됩니다. 단, 사용 중인 버전에 아래 나열된 태스크가 없을 수도 있습니다.

    웹브라우저의 할 일 앱

  12. 브라우저에서 앱의 샘플 태스크를 만듭니다. 데이터베이스에서 검색된 태스크가 UI에 표시되는지 확인합니다.

Cloud Run으로 마이그레이션할 웹 앱 코드 준비

이 섹션에서는 Cloud Run에 배포할 웹 앱을 준비하기 위해 완료해야 할 단계를 자세히 설명합니다.

Docker 컨테이너를 빌드하여 Container Registry에 게시

Docker 이미지는 Cloud Run에서 실행할 앱 컨테이너를 빌드하는 데 필요합니다. 컨테이너는 수동으로 또는 빌드팩을 사용하여 빌드할 수 있습니다.

컨테이너 수동 빌드

  1. Cloud Shell에서 이 튜토리얼 용으로 제공된 저장소를 클론하여 만든 디렉터리에 Dockerfile을 만듭니다.

    cat <<"EOF" > Dockerfile
    # Use the official Node image.
    # https://hub.docker.com/_/node
    FROM node:10-alpine
    
    # Create and change to the app directory.
    WORKDIR /app
    
    # Copying this separately prevents re-running npm install on every code change.
    COPY package*.json ./
    RUN npm install
    
    # Copy local code to the container image.
    COPY . /app
    
    # Configure and document the service HTTP port.
    ENV PORT 8080
    EXPOSE $PORT
    
    # Run the web service on container startup.
    CMD ["npm", "start"]
    EOF
    
  2. Cloud Build로 컨테이너를 빌드하고 해당 이미지를 Container Registry에 게시합니다.

    gcloud builds submit --tag gcr.io/PROJECT_ID/APP_NAME:1 \
      --gcs-log-dir=gs://PROJECT_ID_cloudbuild
    
  3. 생성된 Docker 이미지의 이름을 저장할 환경 변수를 만듭니다.

    export IMAGE_NAME="gcr.io/PROJECT_ID/APP_NAME:1"
    

빌드팩으로 컨테이너 빌드

  1. Cloud Shell에서 pack CLI를 설치합니다.

  2. 기본적으로 Heroku 빌더를 사용하도록 pack CLI를 설정합니다.

    pack config default-builder heroku/buildpacks:22
    
  3. Docker 이미지 이름을 저장할 환경 변수를 만듭니다.

    export IMAGE_NAME=gcr.io/PROJECT_ID/APP_NAME:1
    
  4. pack 명령어를 사용하여 이미지를 빌드한 후 Container Registry에 이 이미지를 내보내거나 게시합니다.

    pack build --publish $IMAGE_NAME
    

PostgreSQL용 Cloud SQL 인스턴스 만들기

웹 앱의 백엔드 역할을 하는 PostgreSQL용 Cloud SQL 인스턴스를 만듭니다. 이 가이드에서는 PostgreSQL이 Heroku에 배포된 샘플 앱으로 가장 적합하며 이 앱은 Postgres 데이터베이스를 백엔드로 사용합니다. 이 앱의 용도에 맞춰 관리형 Postgres 서비스에서 PostgreSQL용 Cloud SQL로 마이그레이션할 때는 스키마를 변경할 필요가 없습니다.

  1. 비공개 IP 주소를 사용하여 Cloud SQL용 네트워크를 준비합니다.

    gcloud compute addresses create google-managed-services-default \
      --global \
      --purpose=VPC_PEERING \
      --prefix-length=16 \
      --description="peering range for CloudSQL Private Service Access" \
      --network=default
    
    gcloud services vpc-peerings connect \
      --service=servicenetworking.googleapis.com \
      --ranges=google-managed-services-default \
      --network=default \
      --project=PROJECT_ID
    
  2. 다음 단계에서 만들 데이터베이스 인스턴스의 이름을 저장할 CLOUDSQL_DB_NAME이라는 환경 변수를 만듭니다.

    export CLOUDSQL_DB_NAME=tasks-db
    
  3. 데이터베이스를 만듭니다.

    gcloud sql instances create $CLOUDSQL_DB_NAME \
    --cpu=1 \
    --memory=4352Mib \
    --database-version=POSTGRES_15 \
    --region=us-central1 \
    --network default \
    --no-assign-ip
    

    인스턴스를 초기화하는 데 몇 분 정도 걸릴 수 있습니다.

  4. Postgres 사용자의 비밀번호를 설정합니다.

    gcloud sql users set-password postgres \
        --instance=$CLOUDSQL_DB_NAME  \
        --password=POSTGRES_PASSWORD
    

    POSTGRES_PASSWORD를 Postgres 데이터베이스에 사용하려는 비밀번호로 바꿉니다.

Heroku Postgres에서 Cloud SQL로 데이터 가져오기

Cloud SQL로 데이터를 마이그레이션하는 데 사용할 수 있는 마이그레이션 패턴에는 여러 가지가 있습니다. 일반적으로 다운타임이 최소화되거나 발생하지 않는 방법이 최고의 방법으로 여겨지며, 이를 위해서는 마이그레이션할 데이터베이스의 복제본으로 Cloud SQL을 구성한 후 Cloud SQL을 마이그레이션 이후의 기본 인스턴스로 설정하는 것이 좋습니다. Heroku Postgres는 외부 복제본(팔로어)을 지원하지 않으므로, 이 튜토리얼에서는 오픈소스 도구를 사용하여 앱의 스키마를 마이그레이션해야 합니다.

이 튜토리얼에서 사용하는 Tasks 앱의 경우 pg_dump 유틸리티를 사용하여 Heroku Postgres의 데이터를 Cloud Storage 버킷으로 내보낸 다음 Cloud SQL로 가져옵니다. 이 유틸리티는 동종 버전 간에 또는 대상 데이터베이스의 버전이 소스 데이터베이스보다 최신일 경우에 데이터를 전송할 수 있습니다.

  1. Cloud Shell에서 샘플 앱에 연결된 Heroku Postgres 데이터베이스의 데이터베이스 사용자 인증 정보를 가져옵니다. 이 사용자 인증 정보는 다음 단계에서 필요합니다.

    heroku pg:credentials:url
    

    이 명령어는 애플리케이션의 연결 정보 문자열과 연결 URL을 반환합니다. 연결 정보 문자열의 형식은 다음과 같습니다.

    "dbname=DATABASE_NAME host=FQDN port=5432 user=USER_NAME password=PASSWORD_STRING sslmode=require"
    

    다음 단계에서 연결 문자열에 표시된 값이 필요합니다.

    연결 정보 문자열의 FQDN(정규화 된 도메인 이름) 값의 예는 Heroku 문서를 참조하세요.

  2. 후속 단계에서 사용할 Heroku 값을 저장할 환경 변수를 설정합니다.

    export HEROKU_PG_DBNAME=DATABASE_NAME
    export HEROKU_PG_HOST=FQDN
    export HEROKU_PG_USER=USER_NAME
    export HEROKU_PG_PASSWORD=PASSWORD_STRING
    

    다음을 바꿉니다.

    • DATABASE_NAME: 정보 문자열에 표시되는 데이터베이스 이름입니다.
    • FQDN: 정보 문자열에 표시되는 FQDN입니다.
    • USER_NAME: 정보 문자열에 표시되는 사용자 이름입니다.
    • PASSWORD_STRING: 정보 문자열에 표시되는 비밀번호 문자열입니다.
  3. Heroku Postgres 데이터베이스의 백업을 SQL 형식으로 만듭니다.

    docker run \
      -it --rm \
      -e PGPASSWORD=$HEROKU_PG_PASSWORD \
      -v $(pwd):/tmp \
      --entrypoint "pg_dump" \
      postgres \
      -Fp \
      --no-acl \
      --no-owner \
      -h $HEROKU_PG_HOST \
      -U $HEROKU_PG_USER \
      $HEROKU_PG_DBNAME > herokudump.sql
    
  4. Cloud Storage 버킷의 이름을 저장할 환경 변수를 만듭니다.

    export PG_BACKUP_BUCKET=gs://PROJECT_ID-pg-backup-bucket
    
  5. Cloud Storage 버킷을 만듭니다.

    gcloud storage buckets create $PG_BACKUP_BUCKET \
      --location=us-central1 \
      --public-access-prevention \
      --uniform-bucket-level-access
    
  6. SQL 파일을 이 버킷에 업로드합니다.

    gcloud storage cp herokudump.sql $PG_BACKUP_BUCKET/herokudump.sql
    
  7. Cloud Storage 버킷에서 SQL 파일을 가져오는 데 필요한 역할로 Cloud SQL 인스턴스를 승인합니다.

    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=serviceAccount:$(gcloud sql instances describe $CLOUDSQL_DB_NAME --format='get("serviceAccountEmailAddress")') \
      --role=roles/storage.objectAdmin
    
    gcloud projects add-iam-policy-binding PROJECT_ID \
      --member=serviceAccount:$(gcloud sql instances describe $CLOUDSQL_DB_NAME --format='get("serviceAccountEmailAddress")') \
      --role=roles/cloudsql.editor
    
  8. SQL 파일을 Cloud SQL 인스턴스로 가져오기합니다.

    gcloud sql import sql $CLOUDSQL_DB_NAME $PG_BACKUP_BUCKET/herokudump.sql \
      --database=postgres \
      --user=postgres
    

    do you want to continue (y/n) 메시지가 표시되면 'y'를 입력합니다.

Cloud Run이 Cloud SQL 데이터베이스에 액세스하는 방법

Heroku에 배포된 웹 앱이 Heroku Postgres의 관리형 인스턴스에 연결되어야 하는 것처럼 Cloud Run에서 데이터를 읽고 쓰려면 Cloud SQL에 액세스해야 합니다.

Cloud Run은 Cloud Run에 컨테이너를 배포할 때 자동으로 활성화 및 구성되는 Cloud SQL 프록시를 사용하여 Cloud SQL과 통신합니다. 수신하는 모든 통신이 보안 TCP를 사용하여 프록시에서 수신되기 때문에 데이터베이스에서 외부 IP 주소를 승인할 필요가 없습니다.

코드는 UNIX 소켓을 통해 프록시를 호출하여 데이터베이스 작업(예: 데이터베이스에서 데이터 가져오기 또는 쓰기)을 호출해야 합니다.

이 웹 앱은 Node.js로 제작되므로 pg-connection-string 라이브러리를 사용하여 데이터베이스 URL을 파싱하고 config 객체를 만듭니다. 이 방법을 사용할 때의 장점은 Heroku 및 Cloud Run에서 백엔드 데이터베이스에 원활하게 연결된다는 점입니다.

다음 단계에서는 웹 앱을 배포할 때 데이터베이스 URL을 환경 변수로 전달합니다.

Cloud Run에 샘플 앱 배포

  1. Cloud Shell에서 Cloud Run에서 Cloud SQL로의 비공개 트래픽을 허용하도록 서버리스 VPC 액세스를 구성합니다.

    gcloud compute networks subnets create serverless-connector-subnet \
    --network=default \
    --range=10.0.0.0/28 \
    --region=us-central1
    
    gcloud compute networks vpc-access connectors create serverless-connector \
    --region=us-central1 \
    --subnet=serverless-connector-subnet
    
  2. Cloud Shell에서 생성된 Cloud SQL 인스턴스의 연결 이름을 저장할 환경 변수를 만듭니다.

    export DB_CONN_NAME=$(gcloud sql instances describe $CLOUDSQL_DB_NAME --format='value(connectionName)')
    
  3. UNIX 포트를 통해 Cloud SQL 프록시에 연결하는 데 필요한 연결 문자열을 저장하기 위해 DATABASE_URL이라는 환경 변수를 만듭니다.

    export DATABASE_URL="socket:/cloudsql/${DB_CONN_NAME}?db=postgres&user=postgres&password=POSTGRES_PASSWORD"
    
  4. IAM 역할로 Cloud Run용 서비스 계정을 만들어 데이터베이스에 연결합니다.

    gcloud iam service-accounts create sa-run-db-client
    
    gcloud projects add-iam-policy-binding PROJECT_ID \
        --member=serviceAccount:sa-run-db-client@PROJECT_ID.iam.gserviceaccount.com \
        --role=roles/cloudsql.client
    
  5. Cloud Run에 웹 앱을 배포합니다.

    gcloud run deploy tasksapp-PROJECT_ID \
        --image=$IMAGE_NAME \
        --service-account=sa-run-db-client@PROJECT_ID.iam.gserviceaccount.com \
        --set-env-vars=DATABASE_URL=$DATABASE_URL \
        --add-cloudsql-instances $DB_CONN_NAME \
        --vpc-connector serverless-connector \
        --allow-unauthenticated
    
    

    위의 명령어를 실행하면 Cloud Run 컨테이너가 생성된 Cloud SQL 데이터베이스 인스턴스에도 연결됩니다. 이 명령어는 Cloud Run용 환경 변수가 이전 단계에서 생성된 DATABASE_URL 문자열을 가리키도록 설정합니다.

애플리케이션 테스트

  1. Cloud Shell에서 Cloud Run이 트래픽을 제공하는 URL을 가져옵니다.

    gcloud run services list
    

    Google Cloud Console에서 Cloud Run 서비스를 검토할 수도 있습니다.

  2. Cloud Run 서비스 URL로 이동하여 웹 앱이 HTTP 요청을 허용하는지 확인합니다.

Cloud Run은 HTTP 요청이 제공 엔드포인트로 전송될 때와 컨테이너가 아직 실행 중이 아닌 경우 새 컨테이너를 만들거나 가동합니다. 따라서 새 컨테이너의 가동 요청을 처리하는 데 시간이 좀 더 오래 걸릴 수 있습니다. 추가 시간을 고려하는 경우 앱에서 지원할 수 있는 동시 요청 수와 특정 메모리 요구사항을 고려하세요.

이 앱에서 기본 동시 실행 설정을 사용하면 Cloud Run 서비스가 단일 컨테이너에서 80개의 요청을 동시에 처리하도록 할 수 있습니다.

삭제

이 가이드에서 사용한 리소스 비용이 Google Cloud 계정에 청구되지 않도록 하려면 다음 안내를 따르세요. 이 가이드용으로 Heroku에서 만든 리소스를 삭제하는 것이 좋습니다.

Google Cloud 프로젝트 삭제

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Heroku 앱 삭제

Heroku에 배포된 샘플 앱과 관련 PostgreSQL 부가기능을 삭제하려면 다음 명령어를 실행합니다.

heroku apps:destroy -a APP_NAME

다음 단계