Google Cloud Run + Nginx でティラノスクリプトのゲームをPWAでリリース

はじめに

そこそこ規模の大きいティラノスクリプトで作られたゲームをPWAでリリースしようとした際に起きた現象とその対策について書いた記事です。
内容としてはPWAでリリースすることを考えている人向けの記事になります。

またDockerなどを使っているので、どちらかといえばプログラマー向けの内容になっています。

起きたこと

とある大学から「学生の学習用にティラノスクリプトを使ったゲームを作りたい」と話がありました。
ちなみに、既にある程度の実装などは済んでいて、追加で実装してほしいとのこと。

逐一修正したものをZIP形式でやり取りするのも億劫なので、Netlifyなどのホスティングサービスを使うことにました。
Netilfyとか使えば、GitHubから自動的に最新のアプリをリリースできるので

ただ、実際に動作させると

  • 効果音がずれる
  • 処理がもっさりする

などの問題が発覚。

で、どうしたもんかなぁと考えてました。

原因

原因としては使用しているホスティングサービスのサーバーとの物理的距離の問題とサーバーのスペックの問題のようでした。
ちなみにリロードしてブラウザで表示されるまで15000msとかかかってた……

またブラウザへ表示するまでのレンダリング時間がかなりかかっていることからキャッシュか静的コンテンツを高速に配信することができれば大幅な改善が期待できそうでした。

対策検討

とりあえず処理が重いのはサーバーのスペックと物理的距離のようなので、それらをまず変更することを検討。
また、静的コンテンツを高速に配信してくれると評判のNginxを間にかますことで改善されると考えました。

できればリリースなどはコマンドでサクッとしたいですし、なおかつ使用するときだけ料金が発生するのがいいと考えました。
で、大阪リージョンがあるし、かつコマンドでリリースが楽にできるGoogle Cloud Run がよさそうと思い、そちらを使うことしました。

やったこと

まずは、ティラノスクリプトで作ったゲームのソースコードにDockerfileを以下のように追加します。

FROM nginx:alpine
COPY . /usr/share/nginx/html
COPY ./nginx/default.conf /etc/nginx/conf.d/default.conf

EXPOSE $PORT

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

COPY . /usr/share/nginx/htmlはティラノスクリプトの静的コンテンツをNginxで処理するディレクトリにコピーしています。

またGoogle Cloud Runで使用するポートが8888固定なのでEXPOSE $PORTで使用するポートをよしなにできるようにしています。
またNginxの設定ファイルもCOPY ./nginx/default.conf /etc/nginx/conf.d/default.confでコピーし、Google Cloud Runで動作するようにしています。

次に、nginxディレクトリをソースコード内に作成します。
nginxディレクトリにdefault.confを以下のように作成します。

server {
    listen       8080;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

使用しているポートを変更しているだけですね。

あとはGoogle Cloud Run で使用するコンテナをビルドしてデプロイすればOKです。

# コンテナのビルド
gcloud builds submit --tag gcr.io/<PROJECT-ID>/tyrano

# コンテナをデプロイ
gcloud run deploy --image gcr.io/<PROJECT-ID>/tyrano

これでリリースができました。

結果

Netlifyを使っていた時にリロードしてブラウザで表示されるまで15000msとかかかっていたのが、大体700msくらいまでに抑えることができました!

かなり快適になったので良い感じです。