WordPressのGCEからCloudRunへ移行の検討

# はじめに
[株式会社Retail AI X AdventCalender2022](https://qiita.com/advent-calendar/2022/retail-ai-x)の 12 日目の記事です。
昨日は@broccolibroccolibroccoli さんの『デザインチームを立ち上げた話』でした。

# 自己紹介
Retail AI XのSREチームに所属しています。
直近の仕事内容はFlutter、Android Java、Objective-C、GCPのインフラです。
IoT、金融、基幹システム、WEB・・・色々幅広くやっている会社です。

詳細を聞きたい方や興味がある方は、以下を参照下さい。
会社HP：[https://www.retail-ai.jp/](https://www.retail-ai.jp/)
採用ページ：[https://recruit.jobcan.jp/retail-ai/](https://recruit.jobcan.jp/retail-ai/)


# 目的
会社のメディアをWordPressで運営しています。
その新着記事をメールマガジンやLINE、アプリなどの媒体で告知を行うのですが、登録メディア数を合わせると数十万になります。
メール配信やLINE通知後、すぐにアクセスする人が0.1%だとしても数百〜数千の同時接続のアクセスを捌く必要があります。
このパルス([バルス](https://dic.pixiv.net/a/%E3%83%90%E3%83%AB%E3%82%B9))的なアクセスを現状捌き切れずに503エラーが出てしまう状況です。
CloudCDNを前段に置いてGCE(GoogleComputeEngine)１台にて動かしているのですが、静的ファイルのキャッシュのみで動的ページはキャッシュされずにサーバーに負荷をかけています。

# 構成
GCE：CentOS7、PHP8.0
CloudSQL：MySQL8
GCS、CloudCDN
GCEにはgcsfuseを使用してGCSディレクトリをマウントし、メディア系ファイルをアップロードしています。

データベースは現在接続中のCloudSQLをそのまま使用し、[Cloud SQL Auth Proxy](https://cloud.google.com/sql/docs/mysql/sql-proxy)を使用してCloud Runを接続します。

以下に今回作成したWordPressのDockerfile（一部抜粋したもの）です。
```
FROM centos:centos7.9.2009

EXPOSE 8080

RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 && \
    yum -y update && \
    yum clean all && \
    localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 && \
    ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
ENV LANG="ja_JP UTF-8" \
    LANGUAGE="ja_JP:ja" \
    LC_ALL="ja_JP.UTF-8" \
    TZ="Asia/Tokyo"
RUN yum -y install epel-release; yum clean all

# install php8
RUN yum install -y https://rpms.remirepo.net/enterprise/remi-release-7.rpm; yum clean all
RUN yum install -y yum-utils centos-release-scl
RUN yum-config-manager --disable 'remi-php*'
RUN yum-config-manager --enable remi-php80
RUN yum -y install php php-xml php-xmlrpc php-pecl-apcu php-mbstring php-gd php-json \
    php-pdo php-mysqlnd php-soap php-intl php-pear 

# install mysql client
RUN yum remove mariadb-libs
RUN rpm -ivh https://dev.mysql.com/get/mysql80-community-release-el7-2.noarch.rpm
RUN rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
RUN yum install -y mysql-community-client

# install python3.8
RUN yum install -y rh-python38 rh-python38-python-devel rh-python38-python-config
RUN cat /opt/rh/rh-python38/enable >> /root/.bashrc
# default python3
ENV PATH /opt/rh/rh-python38/root/bin:$PATH

# supervisord
RUN pip install Flask==2.0.2 gunicorn==20.1.0 supervisor
ADD (後述するsupervisord.conf) /etc/supervisord.conf

CMD ["/opt/rh/rh-python38/root/usr/local/bin/supervisord","-n","-c","/etc/supervisord.conf"]
```
CloudRunでは「1つのイメージに対し、1つのポートを設定する」ことしかできません。
[https://cloud.google.com/run/docs/container-contract#port](https://cloud.google.com/run/docs/container-contract#port)

しかしWordPressを起動させるには最低WEBサーバーのポート(80 or 443)とMySQLのポート(3306)が必要になってきます。

# supervisord
[http://supervisord.org/](http://supervisord.org/)
子プロセスをメモリ上に作成して、常駐・監視等行い、要求に応じて処理を行います。

supervisord.confの中身は以下のようになりました(一部抜粋)。
```
[unix_http_server]
file=/tmp/supervisor.sock
chmod=0700

[supervisord]
pidfile=/tmp/supervisord.pid
nodaemon=true              
user=root

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock

[program:httpd]
command=/usr/sbin/httpd -DFOREGROUND

[program:cloudsqlproxy]
command=/usr/local/bin/cloud_sql_proxy -instances=(MySQLインスタンス)

[program:gcsfuse]
command=/usr/bin/gcsfuse --debug_gcs --debug_fuse --foreground --implicit-dirs -o rw,allow_other (GCSバケット) (WordPressアップロードディレクトリ)
user=root
startretries=1

```
httpd、gcsfuse、cloudsqlproxy、それぞれを子プロセスで動作させることになります。
これによりWordPressをCloud Run上で実行することができます。

# 課題
WordPressの管理画面上でデザインやプラグインの修正を行うと、コンテナイメージが複数存在する場合は1台しか書き換えられず、ユーザーや権限を設定して変更できないようにする必要があります。
それらが変更されたら他のコンテナと同期を取るなど、の手段も考えられます。
変更を加える際はGitにpushしてもらい新しいイメージを作るのが良いのですが、エンジニアはそれで対応していますが、メディア対応する方々は現状そのようにはなっていません。
また管理画面のログインのcookieも共有する必要があります。

Google CDNがキャッシュが弱い為に、AWSのCloud FrontやCloudFlareなど試す必要があります。
他の会社などでWordPress + CloudRunの実績が見当たらない（知らないだけ？）ので、引き続き調査・検討を進めていきたいと思います。

# 次
[株式会社Retail AI X AdventCalender2022](https://qiita.com/advent-calendar/2022/retail-ai-x)の1３日目
社内イベント企画が得意な @esoul さんによる「Reactでよく使われるpropsについて知ろう」になります。


# 参考
[https://github.com/google-github-actions/deploy-cloudrun](https://github.com/google-github-actions/deploy-cloudrun)
[https://ondwn.com/github-action-cloudrun-wp/](https://ondwn.com/github-action-cloudrun-wp/)