glasses.dev
#GCP#Cloud Run#Cloud SQL#Deployment#FastAPI

GCP Cloud Run & Cloud SQL 배포 가이드

2025-11-22
5 min read

FastAPI & PostgreSQL: GCP 도입기록.log

앞선 글에서 Docker 도입 시 겪었던 문제들을 해결했다면, 이제 실제로 Google Cloud Platform(GCP)에 서비스를 띄울 차례입니다. 서버리스 컨테이너 서비스인 Cloud Run과 관리형 데이터베이스인 Cloud SQL을 연동하는 과정을 다룹니다.


아키텍처 개요

  • Compute: Google Cloud Run (Serverless, Auto-scaling)
  • Database: Google Cloud SQL (PostgreSQL 16)
  • Registry: Google Container Registry (GCR)
  • Connection: Unix Socket을 통한 보안 연결 (Public IP 노출 최소화)

1. Dockerfile 최적화 (Multi-stage Build)

배포 속도와 비용 절감을 위해 이미지 크기를 줄이는 것이 중요합니다. Multi-stage 빌드를 사용하여 실행에 불필요한 빌드 도구들을 제거합니다.

# Build Stage
FROM python:3.11-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt
 
# Runtime Stage
FROM python:3.11-slim
WORKDIR /app
# 런타임에 필요한 최소한의 시스템 패키지만 설치 (예: libpq5)
RUN apt-get update && apt-get install -y --no-install-recommends libpq5 && rm -rf /var/lib/apt/lists/*
 
# 빌드 스테이지에서 설치한 패키지 복사
COPY --from=builder /root/.local /root/.local
COPY . .
 
ENV PATH=/root/.local/bin:$PATH
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8080"]

2. Cloud SQL 인스턴스 설정

  1. 인스턴스 생성: GCP 콘솔에서 PostgreSQL 16 버전을 선택하여 인스턴스를 생성합니다.
  2. 데이터베이스 생성: swifty_app (또는 원하는 이름) DB를 생성합니다.
  3. 사용자 생성: 애플리케이션에서 사용할 유저를 생성합니다.
  4. 연결 이름 확인: 개요 페이지에서 프로젝트ID:리전:인스턴스이름 형태의 Connection Name을 복사해둡니다.

3. 배포 스크립트 작성 (deploy-cloud-run.sh)

매번 긴 gcloud 명령어를 칠 수 없으므로, 배포 스크립트를 작성하여 자동화합니다.

주요 포인트

  • --add-cloudsql-instances: Cloud Run이 Cloud SQL에 접근할 수 있도록 권한을 부여합니다.
  • --env-vars-file: 환경 변수를 YAML 파일로 주입합니다.
#!/bin/bash
SERVICE_NAME="swifty-backend-api"
IMAGE_NAME="gcr.io/app-swifty-healthy/swifty-backend-api"
REGION="asia-northeast3"
DB_INSTANCE="app-swifty-healthy:asia-northeast3:psql-swifty-free"
 
# 1. Docker 이미지 빌드 및 푸시
echo "🐳 Building & Pushing Docker image..."
gcloud builds submit --tag ${IMAGE_NAME}
 
# 2. Cloud Run 배포
echo "🚀 Deploying to Cloud Run..."
gcloud run deploy ${SERVICE_NAME} \
  --image ${IMAGE_NAME} \
  --platform managed \
  --region ${REGION} \
  --allow-unauthenticated \
  --env-vars-file .env.yaml \
  --add-cloudsql-instances ${DB_INSTANCE} \
  --memory 512Mi \
  --cpu 1

4. DB 연결 설정 (Unix Socket)

Cloud Run에서 Cloud SQL로 연결할 때는 TCP(IP) 방식보다 Unix Socket 방식이 권장됩니다. 별도의 인증 프록시 설정 없이 안전하게 연결할 수 있기 때문입니다.

database.py 혹은 설정 파일에서 DB Host를 다음과 같이 설정해야 합니다.

# .env.yaml 예시
# DB_HOST: "/cloudsql/프로젝트ID:리전:인스턴스이름"
 
# Python 코드 (SQLAlchemy/AsyncPG)
# 호스트가 '/'로 시작하면 자동으로 Unix Socket으로 인식하거나,
# 드라이버에 따라 별도 설정이 필요할 수 있습니다.
DATABASE_URL = f"postgresql+asyncpg://{user}:{pw}@/{db_name}?host={db_host_socket_path}"

5. 배포 및 확인

스크립트를 실행하여 배포를 진행합니다.

chmod +x deploy-cloud-run.sh
./deploy-cloud-run.sh

배포가 성공하면 Service URL이 출력됩니다. 해당 URL의 /docs 엔드포인트(FastAPI Swagger UI)에 접속하여 정상 동작을 확인합니다.

트러블슈팅 팁

  • 502 Bad Gateway: 주로 컨테이너가 시작되지 못하고 죽었을 때 발생합니다. gcloud run logs read 명령어로 애플리케이션 로그를 확인하세요. (대부분 DB 연결 실패나 환경 변수 누락입니다.)
  • DB 연결 실패: Cloud Run 서비스 계정(Service Account)이 Cloud SQL Client 권한을 가지고 있는지 IAM에서 확인해야 합니다.

마무리

이제 로컬에서 개발한 FastAPI 서비스가 전 세계 어디서든 접근 가능한 클라우드 환경에 배포되었습니다. Cloud Run은 트래픽이 없을 때 인스턴스를 0개로 줄여 비용을 절감해주고(Scale to Zero), 트래픽이 몰리면 자동으로 확장해주는 강력한 기능을 제공합니다.

댓글이나 피드백을 남겨주세요

(Giscus 또는 Utterances 댓글 컴포넌트가 들어갈 자리)