🙆

ReflexをCloud Runにデプロイする

2024/08/24に公開

はじめに

ここ最近、Reflexという PythonのみでUI含めたWebアプリが作成できるライブラリ が使ってみていい感じなので、いろいろと触ってみてます。

https://zenn.dev/neka_nat/articles/f2f5b6ebeb049a
https://zenn.dev/neka_nat/articles/32824920cb6004
https://github.com/neka-nat/reflex-firebase

Reflexには専用のホスティングサービスがあるのですが、環境に入れられるものがpipでインストールできるものに限られてたり、ドメインを自由に変えられなかったり で、何らか他のパブリッククラウドを使用したいシーンも多いと思います。
今回はその中で比較的簡単にデプロイ可能な Cloud Runへのデプロイ方法 をまとめてみました。

Reflex専用ホスティングサービスへのデプロイ

Cloud Runへのデプロイの前に、専用ホスティングサービスへのデプロイについても触れておきたいと思います。
正直、ドメインにこだわりがなく、pipでパッケージをすべて揃えられるのであればこれで良いかなと思ってます。

Reflexコマンドでデプロイができるようにプロジェクト自体もReflexコマンドで作成します。

mkdir myproject
cd myproject
reflex init

reflex deployを実行するとインタラクティブに質問に答えながらデプロイを行えますが、一発コマンドで以下のようにデプロイすることができます。

# アカウント作成 or ログイン
reflex login
# デプロイ
reflex deploy --no-interactive -k myproject -r sin --env SAMPLE_ENV=<必要な環境変数の設定>

-rオプションはリージョン設定でsinはシンガポールです。
他に対応しているリージョンの一覧は以下にあります。
https://reflex.dev/docs/hosting/hosting-cli-commands/#reflex-deployments-regions
必要であれば--envで環境変数の設定を追加できます。

また現在デプロイしているアプリのリストの取得や削除もコマンドで可能です。

reflex deployments lists
reflex deployments delete <プロジェクト名>

Cloud Runへのデプロイ

次にCloud Runへのデプロイを方法についてです。
Cloud Runにデプロイする上で気を付けることとして、reflex runを普通に実行してしまうと、実行時にフロントエンド側のパッケージインストールやビルドが最初に実行されてしまうということです。
なので、Cloud Runでデプロイする際にはフロントエンドのビルドを予め行っておき、バックエンドとフロントエンドを分けてデプロイするということを行います。
https://github.com/orgs/reflex-dev/discussions/3164

バックエンド側のデプロイ

バックエンドは通常のスクリプトを reflex run --backend-only で実行することでバックエンドのみの実行になります。
poetryで作成したプロジェクトであれば、以下のような形でDockerfileを作成し、イメージをArtifact RegistoryにプッシュしてCloud Runにデプロイします。

ARG PYTHON_ENV=python:3.12-slim
ARG POETRY_VERSION=1.6.1

FROM $PYTHON_ENV as build
ENV PYTHONUNBUFFERED True

RUN apt-get update && \
    apt-get install --yes --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/*
RUN curl -sSL https://install.python-poetry.org | POETRY_VERSION=${POETRY_VERSION} python3 -

RUN mkdir -p /app
WORKDIR /app

COPY pyproject.toml poetry.lock ./

ENV PATH="/root/.local/bin:$PATH"
RUN poetry config virtualenvs.create false && \
    poetry install --no-interaction --no-root

FROM $PYTHON_ENV as prod
ENV PYTHONUNBUFFERED True
ENV APP_HOME /app
WORKDIR $APP_HOME
COPY . ./

COPY --from=build /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages
COPY --from=build /usr/local/bin/reflex /usr/local/bin/reflex

CMD ["reflex", "run", "--backend-only"]
docker build -t <Artifact Registoryのイメージパス> .
docker push <Artifact Registoryのイメージパス>
gcloud run deploy <バックエンドのプロジェクト名> \
    --image <Artifact Registoryのイメージパス> \
    --region <リージョン> \
    --project <Google cloudのプロジェクト名> \
    --service-account <サービスアカウント名> \
    --allow-unauthenticated

デプロイ後、バックエンドのURLをメモしておきます。

フロントエンド側のデプロイ

フロントエンドはビルド後のファイルをHttp serverを使ってデプロイします。
以下のコマンドでフロントエンドのビルドとエクスポートを行います。

API_URL="<デプロイしたバックエンドのURL>" reflex export --frontend-only
unzip frontend.zip -d frontend

frontend.zip が作成されるので、展開して以下のDockerfileでイメージを作成します。

FROM nginx:latest

RUN rm -f /etc/nginx/conf.d/*
COPY ./nginx.conf /etc/nginx/conf.d/
COPY frontend /etc/nginx/html

ENV HOST 0.0.0.0

CMD ["nginx", "-g", "daemon off;"]

上記Dockerfile内で読み込んでいるnginx.confでポートの設定を行っています。

server {
    listen 8080;
}

バックエンドと同様にCloud Runにデプロイし、フロントエンドのURLにアクセスすることでアプリの確認ができます。

まとめ

簡単ではありますが、ReflexをCloud Runでデプロイする方法についてまとめました。
ReflexはPythonのWebアプリ作る系のライブラリの中でかなり使い勝手が良いと思っているので、今後も実際にアプリ開発に使う上で必要そうな内容を記事にできればと思ってます。

Discussion