🌊

Cloud RunからCloud SQLに接続する

2023/05/30に公開

この記事について

この記事ではCloud Run上の簡易APIをCloud SQLに接続する方法を解説していきます。
Cloud SQLはGCPで使用できるリレーショナルデータベースサービスです。

前提

  • Docker Desktopがインストール済み。
  • Cloud SQLのMySQLを使用する。
  • モジュール管理はpoetryを使用。

目次

  • プロジェクト、ファイル構成
  • イメージのビルド、プッシュ
  • Cloud Run上のAPIからCLOUD SQLに接続

プロジェクト・ファイル構成

以下、プロジェクト構成です。

.
├── Dockerfile
├── app
│   │
│   └── main.py
│   └── database.py
│   └── models.py
├── poetry.lock
└── pyproject.toml

以下、Dockerfileのコード例です。
設定値の詳細な解説はローカルのアプリをCloud Runにデプロイする方法を参考にしてください。

#dockerイメージを指定。
FROM python:3.8-slim
#パッケージのアップデート&curlをダウンロード
RUN apt-get update && apt-get -y install curl
#環境変数を設定。
ENV PATH /root/.local/bin/:$PATH
#poetry(pythonのパッケージ管理ツール)をダウンロード。
RUN curl -sSL https://install.python-poetry.org | python3 -
#コンテナ内での作業ディレクトリを指定。
WORKDIR root

#コンテナ内にディレクトリを作成。
RUN mkdir app
#ロ-カルファイルをコンテナ内のroot配下にコピー。
COPY pyproject.toml poetry.lock ./
COPY app/main.py app/

#poetryの仮想化を無効か。
RUN poetry config virtualenvs.create false
#pyproject.tomlで設定されているパッケージをインストール。
RUN poetry install --only main
#コンテナ起動時に実行するコマンドを指定。
ENTRYPOINT ["uvicorn", "app.main:app", "--reload", "--host", "0.0.0.0", "--port", "8080"]

main.py

from fastapi import FastAPI
from sqlalchemy.orm import Session
from models import User  # Userモデルを定義したファイルをimportします
import os
from database import get_db  # DBセッションを取得するためのヘルパー関数をimportします

app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

@app.get("/users")
def get_users(db: Session = Depends(get_db)):
    users = db.query(User).all()
    return {"users": [user.dict() for user in users]}

@app.post("/users/create")
def create_users(db: Session = Depends(get_db)):
    for age in range(20, 25):
        user = User(name='山田太郎', age=age, gender='男')
        db.add(user)
    db.commit()
    return "Created 5 users."

@app.delete("/users/delete")
def delete_users(db: Session = Depends(get_db)):
    db.query(User).delete()
    db.commit()
    return "Deleted all users."

以下、Cloud SQLと接続するコード例です。
Cloud SQLとの接続にはConnectorを使うことが推奨されています。

database.py

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from google.cloud.sql.connector import Connector
import os

# 環境変数から接続情報を取得

#DB接続ユーザ名。
db_user = os.environ["DB_USER"]
#DB接続パスワード
db_pass = os.environ["DB_PASS"]
#DB名
db_name = os.environ["DB_NAME"]
#接続するCloud SQLインスタンスを指定
db_instance_connection_name = os.environ["INSTANCE_CONNECTION_NAME"]

connector = Connector()

# Cloud SQL接続用インスタンスを取得。
def getconn():
    conn = connector.connect(
        db_instance_connection_name,
        "pymysql",
        user=db_user,
        password=db_pass,
        db=db_name
    )
    return conn

# SQLAlchemyのエンジンを作成
engine = create_engine(
    "mysql+pymysql://",
    creator=getconn,
)

# SessionLocalという名前のデータベースセッションクラスを作成
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# SQLAlchemyベースモデルを作成
Base = declarative_base()

# データベースセッションを取得するためのヘルパー関数を定義
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

環境変数INSTANCE_CONNECTION_NAMEには以下書式の値を設定します。

プロジェクトID:リージョン:Cloud SQLインスタンス

Cloud SQLインスタンス詳細画面の[接続名]からでも確認できます。

models.py

from sqlalchemy import Column, Integer, String, CHAR
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(255), nullable=False)
    age = Column(Integer, nullable=False)
    gender = Column(CHAR(1), nullable=True)

イメージのビルド、プッシュ

上記のプロジェクトをコンテナ化してContainer Registoryにpushします。
以下のコマンドを実行します。

#dockerコンテナを構築。
docker build . -t 任意のイメージ名

#Container Registoryにpushするためにタグ付け。
docker tag app gcr.io/[GCPプロジェクト名]/[GCP内でのイメージ名]

#Container Registoryにpush。
docker push gcr.io/[GCPプロジェクト名]/[GCP内でのイメージ名]

Cloud Run上のアプリからCloud SQLに接続

Cloud RunからCloud SQLに接続します。
Cloud Runの管理画面から[サービスの作成]をクリック。

まず、Cloud Runの基本的な設定をしていきます。

  • [コンテナイメージのURL]
    • Container Registoryにpushしたdockerイメージを選択。
  • [サービス名]
    • 任意のサービス名を選択。
  • [リージョン]
    • 特別な理由がなければ近いリージョンを選択
  • [認証]
    • 用途に応じて選択。

ここまで完了したらDB接続の部分を実施します。

  1. [コンテナ、ネットワーキング、セキュリティ]をクリック。
  2. [環境変数]の[+変数]を追加をクリック。以下の変数を作成。
    • DB_USER
    • DB_PASS
    • DB_NAME
    • INSTANCE_CONNECTION_NAME
  3. [Cloud SQL接続]から接続したいCloud SQLインスタンスを選択。
  4. [作成]をクリック。

以上でCloud SQLに接続したCloud Runの設定が完了しました。
画面上部にURLが発行されたら構築完了です。

Discussion