🐏

Docker×Cloud Runでコンテナデプロイする方法

2024/04/05に公開

こんにちは、学生エンジニアのMasamichiです!久々にインターン先のオフィスに遊びにいく途中でとても綺麗な富士山が見れたのでいい気分でこの記事を書いてます。

さて、作成したサービスをデプロイする上で、サーバーレス環境だと注意するべきことがあります。それはサーバーレスプラットフォームに依存してしまうということです。最近そのデメリットを痛感した出来事があり、Renderというホスティングサービスを使用したところ、MongoDBのSSL証明書が期限切れになってデプロイしても使えないということがありました。このことから既存のプロジェクトをDockderを使ってコンテナ化する方向に切り替えました。

そこで今回は、プロジェクトをGCPを使用してコンテナデプロイする方法を解説します。

全体像

デプロイするために行う処理は下画像のようなイメージです。

Dockerfileを使って(Artifact Registry)GCRにイメージをpush→Cloud Buildを使ってイメージをビルド→Cloud Runにデプロイするという流れになります。

実装手順

実装は以下の手順で進めていきます。

  1. APIを作成する
  2. Dockerコンテナ化する
  3. DockerイメージをGCRにPushする
  4. Cloud Runでデプロイする

1. APIを作成する

まず簡単なAPIを作成します。既にプロジェクトが完成しているという方はこの章を飛ばしてください。今回は例としてPythonのWebフレームワークであるFastAPIを使ってミニマムのAPIをデプロイしてみます。細かい手順は省略するので、必要に応じて公式ドキュメントやQiitaなどの記事を活用してください。

ディレクトリ構成は以下ように設定します。

ディレクトリ構成
root_dir
 |--app/
     |--main.py
 |--tests/
 |--requirements.txt
 |--.env
 |--Dockerfile
 |--cloudbuild.yml
 ---.gitignore

今回は、このようなシンプルなGETとDBへのPOSTを行うAPIを作成してみます(以下コードはサンプル)。

main.py
import os
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pymongo import MongoClient
from dotenv import load_dotenv

load_dotenv()

app = FastAPI()

@app.get("/")
async def root():
    return {"message": "Hello World"}

@app.post("/add")
async def add_item(item: str):
    client = MongoClient(os.getenv("MONGO_URI"))
    db = client.test
    collection = db.test
    collection.insert_one({"item": item})
    return {"message": "Item added successfully"}

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

これでコアとなるAPIが完成しました。ここまででセーブしたい人はGithubなりを使用してください。

2. Dockerコンテナの導入

次に作成したAPIをDockerコンテナ化します。ここも詳しいdockerfileの説明は省略するのでDockerの記事や本を参照してください。

ルートディレクトリ直下にdockerfileを作成し、イメージを作成します。

FastAPIのDockerfile例:

dockerfile
# Pythonのベースイメージを作成
FROM python:3.11.3
# 作業ディレクトリを指定
WORKDIR /app
# 依存関係ファイルをコピー
COPY requirements.txt .
# 依存関係をインストール
RUN pip install --no-cache-dir -r requirements.txt
# アプリケーションファイルのコピー
COPY . .
# Uvicornを使用してアプリケーションを実行
CMD sh -c "uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-8080}"

Dockerfile作成後、ターミナルで以下のコマンドを入力しDockerイメージを作成します。

docker
docker build -t my-project-name . 
docker
docker run -d -p 8080:8080 --name my-fastapi-app(コンテナ名) my-project-name(イメージ名)

以上のコマンドを実行後、ローカル環境でDockerコンテナが起動したらひとまず完了です。

3. DockerイメージをGCRにPushする

次にDockerイメージをGCP Artifact Registry(GCR)にPushします。手順は以下のようにします。

DockerイメージをGCRにビルド

まずDockerイメージをGCR上でビルドします。以下のdockerコマンドをターミナルで実行します

docker
docker build -t gcr.io/project-id/my-image:my-tag .

DockerイメージをGCRにPush

ビルドが完了したら、GCRに対してDockerイメージをPushします。

docker
docker push gcr.io/project-id/my-image:my-tag

手順が完了したら、実際にGCRにイメージがあるか確認しましょう。自身のコンソールに行き、画像のようにイメージが確認できたらOKです。

4. Cloud Runでデプロイする

最後の手順です。実際にCloud Runを使ってデプロイをしてみましょう。具体的には以下のコマンドを実行するだけです。

gcloud
gcloud run deploy <server名> --image <your-gcr-image> --region asia-northeast1 --platform managed --allow-unauthenticated 

他にもcpu(CPU割り当て)やmemory(メモリ割り当て)など様々なargsを指定できます。ご自身でカスタマイズしたいように引数を選択してください。

無事にデプロイできていたら以下の画像のように確認できます。

補足

デプロイを行う上で、環境変数が入力されていないとデプロイに失敗します。GUIで簡単に環境変数を設定できるので、必ず確認しましょう!

[新しいリビジョンの編集とデプロイ > 変数とシークレット]へいき設定できます。

終わりに

今回はGCP Cloud RunとDockerを使ってコンテナデプロイをする方法を紹介しました。前述した通り、コンテナデプロイのメリットは環境依存しづらくなることにあります。またCloud Runは強力なホスティングサービスの一つであり、多くの企業で採用されているため、使えるようになって損はないです。ぜひ個人開発などでお役立てください!

Discussion