Google Cloud Platform (GCP) の Cloud Run を使って、Webアプリケーションを無料でデプロイする方法を紹介します。
未経験からエンジニアにキャリアチェンジを目指す方のポートフォリオ公開や、
小規模な個人開発のプロジェクトに最適な方法です。
今回はRuby on Railsのアプリケーションを例に解説しますが、
Dockerコンテナ化されたアプリケーションであれば、言語やフレームワーク問わずにデプロイできます。
背景
2022年8月25日にHerokuが無料プランを廃止をアナウンス、2022年11月28日に無料プランが終了しました。
https://www.heroku.com/blog/next-chapter/
ポートフォリオの公開や小規模な個人開発のプロジェクトを無料でホスティングする方法のファーストチョイスはHerokuでしたが、
Herokuの無料プランがなくなったことで、代替手段を探す必要があります。
そこでRenderなどのPaaS(Platform as a Service)を利用してみましたが、
無料で使えるものの次のような課題がありました。
- コールドスタートで起動が遅い
- スリープ時はRenderの画面が表示される
- データベースが3か月で削除される
- 管理画面に一人しかアクセスできないので、デバッグが難しい
- 管理画面が使いづらい
Renderのメリットはアプリケーションサーバー、データベースをすべて無料で使えることです。
しかし、上記の課題があるため、無料で使えるものの使いづらさは否めません。
なるべく無料もしくは低コストで、かつ使いやすい環境を探していたところ、GCPのCloud Runにたどり着きました。
構成
GCPのCloud Runを使ったWebアプリケーションの構成は以下の通りです。
Cloud Run
Cloud Runは完全にマネージドなコンテナ実行環境です。
Cloud RunでアプリケーションのDockerコンテナを実行します。
今回はRuby on Railsを例にしますが、他の言語やフレームワークでも同様に動作します。
Cloud Runは無料枠があり、月間200万リクエストまで無料で利用できます。
ポートフォリオや小規模な個人開発のプロジェクトであれば、無料枠内で十分に運用可能です。
Cloud Run上でデータベースはSQLite3を使用します。
Cloud Runはステートレスなサービスであるため、Cloud Runのインスタンスが停止すると、データは失われます。
そこでSQLite3のデータベースファイルをCloud Storageと連携してマウントすることで、データを永続化します。
Ruby on Railsのデフォルトの設定ではSQLiteはstorage以下にSQLite3のデータベースファイルを作成します。
そのためstorage以下をCloud Storageにマウントします。
コンテナレジストリ
Cloud Runでアプリケーションを実行するには、Dockerコンテナイメージを保存しておくレジストリが必要です。
GCPではArtifact Registryを使用します。
ただし、Artifact Registryは500MBまでのイメージを無料で保存できますが、
それ以上のサイズになると課金されます。
Railsだと500MBを超えてしまうことが多いので、Artifact Registryを使用した場合、
0.1円/日、1か月だと3円程度の課金が発生します。
次の場合は素直にArtifact Registryを使うことをおすすめします。
- GCPで完結したい
- 安く済ませたいが、無料にこだわる必要はない
- Dockerイメージは非公開にしたい
もしGCPで完結する必要がなく、ポートフォリオなどの公開でソースコードやDockerイメージを公開しても問題ない場合は、
Docker Hubを利用することでArtifact Registryの課金を回避できます。
Cloud Storage
Cloud Runで動作させているSQLite3のデータベースファイルを永続化するために、Cloud Storageを使用します。
5GBまでのストレージ、5,000回のクラスAオペレーション、50,000回のクラスBオペレーションが無料で利用できます。
SQLite3のデータベースファイルは数MB程度、ポートフォリオや小規模な個人開発のプロジェクトであれば、無料枠内で十分に運用可能です。
https://cloud.google.com/free/docs/free-cloud-features?hl=ja#storage
Secret Manager
Cloud Runでアプリケーションを実行する際に、環境変数やシークレット情報を管理するために、Secret Managerを使用します。
今回はRuby on Railsで秘匿情報を管理するキーである、RAILS_MASTER_KEYをSecret Managerに保存します。
なおCloud RunでSecret Managerではなく、環境変数を直接設定することもできるため、利用は必須ではありませんが、推奨事項になります。
注意点
今回の構成は多くの場合、Artifact Registryを除き無料枠内で運用可能ですが、
利用状況によっては課金が発生する可能性があります。
またDocker Hubを利用する場合はイメージを公開する必要があるため、
ソースコードやDockerイメージを公開しても問題ない場合に限ります。
心配な方は課金については予算アラートを設定する、Docker HubではなくArtifact Registryを利用するなどの対策を検討してください。
予算アラートの設定については後述します。
「Artifact RegistryとDocker Hubのどっちを使ったらよいかわからない」という場合は、
3円/月ほど課金されますが、Artifact Registryを利用することをおすすめします。
全体像
では、実際にCloud RunでWebアプリケーションをデプロイする手順を説明しますが、
その前に全体の流れを把握しておきましょう。
- Googleアカウントの作成
- Google Cloudのアカウントを作成
- Dockerイメージの作成
- CloudStorageのバケットを作成
- Secret Managerの設定
- Artifact Registryの設定
- Cloud Runの設定
Docker Desktopのインストール
もし、まだDockerをインストールしていなければ、はじめにパソコンにDockerをインストールしましょう。
Docker Desktopをインストールすると、開発に必要なDocker Engine、Docker CLI、Docker Composeなどが一式インストールされます。
次のリンクから、使用しているパソコンに合わせてDocker Desktopをダウンロードしてインストールしてください。
https://www.docker.com/ja-jp/products/docker-desktop/
私の場合はWindowsを使用しているので、Windows版のDocker Desktopをインストールしました。
アプリケーションを起動して、左下のステータスがEngine running
になっていれば、Docker Desktopのインストールは成功です。
VSCoceのインストール
今回はVSCodeのDev Containerを使って開発を行います。
VSCodeをまだインストールしていない場合は、次のリンクからダウンロードしてインストールしてください。
https://code.visualstudio.com/
Dev Containerの拡張機能のインストール
VSCodeのDev Containerを使うために、次の拡張機能をインストールします。
Dev Containerを使うことで、Dockerさえあれば、Rubyなどをホストにインストールする必要がなく、コンテナ内で開発環境を構築できます。
VSCodeの拡張機能のマーケットプレイスから、次の拡張機能をインストールしてください。
https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers
rails-newコマンドのインストール
Railsの新しいプロジェクトを作成するために、rails-new
コマンドをインストールします。
次のリリースページから、最新のrails-new
コマンドをダウンロードしてインストールしてください。
https://github.com/rails/rails-new/releases
Macの場合は、rails-new-aarch64-apple-darwin.tar.gz
をダウンロードします。
WindowsのWSL2の場合は、rails-new-x86_64-unknown-linux-gnu.tar.gz
をダウンロードします。
ダウンロードしたファイルを解凍して、rails-new
コマンドをパスの通ったディレクトリに移動します。
tar -xzf rails-new-aarch64-apple-darwin.tar.gz
解凍したらrails-new
コマンドをパスの通ったディレクトリに移動します。
mv rails-new /usr/local/bin/
コマンドが実行できるか確認します。
rails-new --version
次のようにバージョンが表示されれば、rails-new
コマンドのインストールは成功です。
rails-new 0.4.1
Ruby on Railsのプロジェクトを作成
次に、Ruby on Railsのプロジェクトを作成します。
先ほどインストールしたrails-new
コマンドを使って、プロジェクトを作成します。
ターミナルを開いて、次のコマンドを実行してください。
-r
オプションでRailsのバージョンを指定できます。
今回はRails 8.0.2を使用します。
sample_app
はプロジェクト名です。
--devcontainer
オプションをつけると、VSCodeのDev Containerで開発できるように設定されます。
rails-new -r 8.0.2 sample_app --devcontainer
プロジェクトはカレントディレクトリにsample_app
というディレクトリが作成されます。
VSCodeでプロジェクトを開く
プロジェクトが作成できたら、VSCodeでプロジェクトを開きます。
VSCodeを起動して、先ほど作成したsample_app
ディレクトリを開いてください。
VSCodeを開くと、右下に「コンテナで開く」というボタンが表示されるので、クリックします。
もしくは、コマンドパレット(Ctrl + Shift + P
)を開いて、「Dev Containers: Reopen in Container」を選択します。
これでVSCodeのDev Containerが起動し、コンテナ内で開発環境が構築されます。
簡単なTODOアプリケーションを作成
Railsのプロジェクトが作成出来たら、簡単なTODOアプリケーションを作成します。
データベースのCRUD操作を確認するためです。
次のコマンドを実行して、Railsのジェネレータを使って、Task
モデルを作成します。
rails generate scaffold Task title:string description:text completed:boolean
データベースにテーブルを作成するmigrationファイルなど、CRUD操作に必要なファイルが生成されます。
次に、データベースをマイグレーションします。
rails db:migrate
Routeの設定
次に、ルーティングを設定します。
config/routes.rb
ファイルを開いて、次のように設定します。
http://localhost:3000 にアクセスしてTaskの一覧が表示されるようにします。
Rails.application.routes.draw do resources :tasks root "tasks#index"end
Railsの起動
次に、Railsを起動します。
ターミナルで次のコマンドを実行してください。
rails server
これで、Railsの開発サーバーが起動します。
http://localhost:3000 にアクセスすると、先ほど作成したTODOアプリケーションの一覧が表示されるはずです。
Dockerfileの確認
RailsはデフォルトでDockerfileが含まれています。
念のためsample_app
以下のDockerfile
を確認しておきましょう。
こちらのDockerfileでイメージを作成します。
Googleアカウントの作成
Google Cloud Platformを利用するには、Googleアカウントが必要です。
もしまだGoogleアカウントをお持ちでない場合は、次のリンクからアカウントを作成してください。
https://www.google.com/intl/ja/account/about/
すでにGoogleアカウントをお持ちの場合は、Google Cloud Platform用に新しいアカウントを作成する必要はありません。
既存のGoogleアカウントをそのまま利用できます。
Google Cloudのアカウントを作成する
Googleアカウントを作成したら、次のリンクからGoogle Cloud Platformのアカウントを作成してください。
右上の「無料で利用開始」ボタンをクリックして、アカウントを作成します。
プロジェクトの作成
Google Cloudのアカウントを作成出来たら、プロジェクトを作成します。
画面上部のプロジェクトタブをクリックすると、プロジェクトの一覧が表示されます。
プロジェクトを選択するか、「新しいプロジェクト」ボタンをクリックして新しいプロジェクトを作成します。
Cloud Storageのバケットを作成
次にSQLite3のデータベースファイルを永続化するために、Cloud Storageのバケットを作成します。
画面上部の検索バーに「storage」と入力して、Cloud Storageのページを開きます。
バケットを作成
ボタンをクリックして、バケットを作成します。
バケットの名前を入力します。
わかりやすい名前をつけてください。
sample-app-sqlite
のように、プロジェクト名やアプリケーション名を含めると良いでしょう。
データの保存場所
は、今回は費用を抑えるためにロケーションタイプをRegion
(単一リージョン)に設定します。
リージョンは、アプリケーションのユーザーが多い地域を選ぶと、パフォーマンスが向上します。
例えば、日本のユーザーが多い場合は、asia-northeast1
(東京リージョン)を選択します。
他の設定はデフォルトのままで問題ありません。
設定が完了したら画面最下部の作成
ボタンをクリックして、バケットを作成します。
パブリックアクセスの防止
のポップアップが表示されたら、
このバケットに対するパブリックアクセス禁止を適用する
を選択して、確認
ボタンをクリックします。
今回はCloud Runのアプリケーションからのみアクセスするため、パブリックアクセスは不要です。
バケットが作成されると、Cloud Storageのバケット一覧に表示されます。
後ほどCloud Runのアプリケーションからこのバケットをマウントして、SQLite3のデータベースファイルを永続化します。
Secret Managerの設定
次に、Cloud Runでアプリケーションを実行する際に必要な秘匿情報を管理するために、Secret Managerを設定します。
今回はRailsの秘匿情報を一元管理できるキーである、RAILS_MASTER_KEY
をSecret Managerに保存します。
他のアプリケーションの場合は、必要な秘匿情報を同様にSecret Managerに保存してください。
画面上部の検索バーに「Secret Manager」と入力して、Secret Managerのページを開きます。
シークレットを作成
ボタンをクリックして、シークレットを作成します。
シークレットの作成画面になります。
名前はrails_master_key
など、わかりやすい名前をつけてください。
値にはsample_app
のconfig/master.key
の内容を入力します。
改行が入らないように注意してください。
それ以外はデフォルトのままで問題ありません。
名前と値を入力したら、画面最下部のシークレットを作成
ボタンをクリックします。
他にも必要な秘匿情報があれば、同様にSecret Managerに保存してください。
サービスアカウントの設定
Cloud RunからSecret Managerにアクセスするためには、サービスアカウントに適切な権限を付与する必要があります。
画面上部の検索バーに「IAM」と入力して、IAMのページを開きます。
デフォルトのサービスアカウント(@development.gserviceaccount.com)の鉛筆アイコンをクリックして、編集画面を開きます。
ロールのフィルタでsecret
と入力すると、Secret Managerのシークレットアクセサー
が表示されるので、これを選択します。
設定が完了したら、画面最下部の保存
ボタンをクリックします。
これでCloud RunからSecret Managerにアクセスできるようになりました。
Artifact Registryの設定
次に、Cloud Runでアプリケーションを実行するためのDockerコンテナイメージを保存するために、Artifact Registryを設定します。
画面上部の検索バーに「Artifact Registry」と入力して、Artifact Registryのページを開きます。
Artifact Registry API
を有効にしていない場合は、画面上部のAPIを有効にする
ボタンをクリックして、APIを有効にします。
次に、リポジトリを作成
ボタンをクリックして、リポジトリを作成します。
リポジトリの作成画面になります。
リポジトリの名前を入力します。
わかりやすい名前をつけてください。
sample-app
のように、プロジェクト名やアプリケーション名を含めると良いでしょう。
形式はDocker
を選択します。
モードは標準
を選択します。
ロケーションタイプは今回は費用を抑えるためにRegion
(単一リージョン)に設定します。
リージョンはasia-northeast1
(東京リージョン)を選択します。
他の設定はデフォルトのままで問題ありません。
設定が完了したら画面最下部の作成
ボタンをクリックして、リポジトリを作成します。
Dockerコンテナイメージの作成
次に、Dockerコンテナイメージを作成します。
ターミナルで次のコマンドを実行してください。
こちらのコマンドはsample_app
ディレクトリで実行する必要があります。
また、Dev Containerを使用しているときは、VSCodeのターミナルではなく、
ホストのターミナルで実行するように注意してください。
docker build -t sample_app .
Dockerコンテナイメージのタグ付け
次に、作成したDockerコンテナイメージにタグを付けます
タグはArtifact Registryのリポジトリ名と同じ名前を付けます。
Artifact Registryに作成したリポジトリの詳細画面でパスをコピー
ボタンをクリックして、パスをクリップボードにコピーします。
次のコマンドを実行して、Dockerコンテナイメージにタグを付けます。
<パス>
の部分には、先ほどコピーしたパスを貼り付けてください。
Railsアプリケーションはappという名前でタグ付けします。
Artifact Registryにapp
という名前でDockerイメージをプッシュすることになります。
docker tag sample_app <パス>/app
Gcloud CLIのインストール
次に、Gcloud CLIをインストールします。
このCLIでDockerイメージのpushやCloud Runのデプロイを行います。
docker run -ti --name gcloud-config \ -v gcloud-config:/root/.docker \ gcr.io/google.com/cloudsdktool/google-cloud-cli:stable \ gcloud auth login
アカウントの選択画面が表示されたら、先ほど作成したGoogleアカウントを選択します。
Google Cloud SDKへのアクセスを許可する画面が表示されたら、許可
ボタンをクリックします。
クレデンシャルが表示されるので、Copy
ボタンをクリックして、クリップボードにコピーします。
ターミナルに戻って、コピーしたクレデンシャルを貼り付けてEnterキーを押します。
Artifact Registryの認証
次に、Artifact RegistryにDockerイメージをプッシュするための認証を行います。
ポイントは、このコマンドを実行するとDockerコンテナの/root/.docker/config.json
に認証情報が作成されるので、
そのボリュームをマウントして、永続化していることです。
また、usr/bin/docker
と/var/run/docker.sock
をマウントすることで、Dockerコマンドを実行できるようにしています。
/usr/bin/docker
の部分はDockerのパスです。
もしDockerのパスが異なる場合は、適宜変更してください。
Dockerのパスを確認するには、次のコマンドを実行します。
which docker
docker run -it \ --volumes-from gcloud-config \ -v gcloud-config:/root/.docker \ -v /usr/bin/docker:/usr/bin/docker \ -v /var/run/docker.sock:/var/run/docker.sock \ gcr.io/google.com/cloudsdktool/google-cloud-cli:stable \ bash -c "gcloud auth configure-docker asia-northeast1-docker.pkg.dev"
イメージのプッシュ
次に、DockerコンテナイメージをArtifact Registryにプッシュします。
次のコマンドを実行してください。
<パス>
の部分には、先ほどタグ付けしたパスを貼り付けてください。
docker run -it \ --volumes-from gcloud-config \ -v gcloud-config:/root/.docker \ -v /usr/bin/docker:/usr/bin/docker \ -v /var/run/docker.sock:/var/run/docker.sock \ gcr.io/google.com/cloudsdktool/google-cloud-cli:stable \ bash -c "docker push <パス>/app"
pushに成功するとArtifact RegistryのリポジトリにDockerイメージが保存されます。
Cloud Runの設定
次に、Cloud Runの設定を行います。
画面上部の検索バーに「Cloud Run」と入力して、Cloud Runのページを開きます。
サービスを作成
ボタンをクリックして、サービスの作成画面を開きます。
サービスの作成画面になります。
コンテナイメージのURLには、先ほどArtifact RegistryにプッシュしたDockerイメージを選択します。
Dockerイメージの後に:latest
を付けると、最新のイメージが使用されるため、
毎回コンテナイメージのURLを変更する必要がなくなります。
今回は毎回最新のイメージを使用するため、:latest
を付けておきます。
たとえばプロジェクト名がsample-project
、リポジトリ名がsample-app
、イメージ名がapp
の場合、コンテナイメージのURLは次のようになります。
asia-northeast1-docker.pkg.dev/sample-project/sample-app/app:latest
サービスの名前はWebアプリケーションなので、かつDockerイメージ名と合わせてapp
とします。
リージョンは日本向けと仮定してasia-northeast1
(東京リージョン)を選択します。
誰でもアクセスできるように認証
のチェックボックスは外しておきます。
コンテナの設定
コンテナ、ボリューム、ネットワーキング、セキュリティ
のタブを開きます。
コンテナポートは3000
を指定します。
Ruby on Rails固有の設定ですが、DockerfileのCMDを見てみるとbin/thrust
が実行されていることがわかります。
こちらはRuby on Rails用のHTTP2プロキシであるThrusterの起動コマンドなのですが、こちらはデフォルトはHTTPは80ポート、HTTPSは443ポートで待ち受けています。
Cloud Runでなるべく無料で使う最小インスタンス設定でthrusterを使うと、ダウンタイムが生じてしまうため、
プロキシの後ろで3000番ポートで待ち受けしているRailsのアプリケーションに直接アクセスするように設定します。
そのため、コンテナポートは3000を指定します。
変数とシークレット
次に、変数とシークレット
のタブを開きます。
ここでは、先ほどSecret Managerに保存したRAILS_MASTER_KEY
をCloud Runの環境変数として設定します。
環境変数として公開されるシークレット
のセクションで、シークレットを追加
ボタンをクリックします。
名前にはRAILS_MASTER_KEY
を入力し、シークレットには先ほど作成したrails_master_key
を選択します。
バージョンはlatest
を選択します。
選択し終わったら、完了
ボタンをクリックします。
ボリュームのマウント
次に、ボリューム
のタブを開きます。
ここでは、Cloud Storageのバケットをマウントして、SQLite3のデータベースファイルを永続化します。
ボリュームを追加
ボタンをクリックします。
ボリュームのタイプはCloud Storageバケット
,
ボリューム名は任意の名前でよいですが、今回はstorage
とします。
バケットはあらかじめ作成したCloud Storageのバケットを選択します。
入力したら、完了
ボタンをクリックします。
マウントパスの設定
ボリュームを作成したら、コンテナタブに戻って、マウントパスを設定します。
ボリュームのマウント
のセクションで、先ほど作成したボリュームを選択します。
名前は先ほど作成したstorage
を選択します。
マウントパスは/rails/storage
を指定します。
sample_app
のDockerfileを確認するとWORKDIR
が/rails
になっています。
つまり、Railsのアプリケーションは/rails
ディレクトリに配置されます。
WORKDIR /rails
つぎにconfig/database.yml
を確認します。
production
の設定で、SQLite3のデータベースファイルはstorage/production.sqlite3
のように
storage
ディレクトリに配置されます。
そのため、マウントパスは/rails/storage
を指定します。
production: primary: <<: *default database: storage/production.sqlite3 cache: <<: *default database: storage/production_cache.sqlite3 migrations_paths: db/cache_migrate queue: <<: *default database: storage/production_queue.sqlite3 migrations_paths: db/queue_migrate cable: <<: *default database: storage/production_cable.sqlite3 migrations_paths: db/cable_migrate
他のWebアプリケーションの場合や、設定を変更した場合は、SQLite3のデータベースファイルが配置されるパスを指定してください。
Cloud RunからStorageへのアクセス権限の設定
Cloud RunからCloud Storageのバケットにアクセスするためには、Cloud Runのサービスアカウントに適切な権限を付与する必要があります。
画面上部の検索バーに「IAM」と入力して、IAMのページを開きます。
デフォルトのサービスアカウント(@development.gserviceaccount.com)の鉛筆アイコンをクリックして、編集画面を開きます。
次のようにロールを追加します。
run.developer
と入力して、Cloud Run でデベロッパー
を選択iam.serviceAccountUser
と入力して、サービスアカウントユーザー
を選択storage.admin
と入力して、ストレージ管理者
を選択
選択したら、画面最下部の保存
ボタンをクリックします。
これでCloud RunのサービスアカウントにCloud Storageのバケットにアクセスする権限が付与されました。
https://cloud.google.com/run/docs/configuring/services/secrets?hl=ja#required_roles
リビジョンスケーリングの設定
次に、リビジョンスケーリング
の設定をします。
SQLite3は単一のインスタンス向けなので、Cloud Runのインスタンスは1つに固定します。
最大インスタンス数
を1に設定します。
最小インスタンス数
は0に設定します。
起動時のブースト
はチェックを入れておくとコールドスタート時の起動時間が短縮されますが、
今回はなるべく無料で運用したいので、チェックは外しておきます。
起動時のブースト
を有効にすると、起動時間が短縮されますが、課金が発生する場合があります。
Cloud Runの作成
設定が完了したら、画面最下部の作成
ボタンをクリックします。
これでCloud Runのサービスが作成されます。
作成には数分かかりますので、しばらく待ちます。
Cloud RunのURLの確認
デプロイに成功すると、緑色のチェックマークが表示されます。
サービスのURLが表示されるので、クリックしてアプリケーションにアクセスします。
トラブルシューティング
もしデプロイに失敗した場合は、ログのタブを開いて、エラーメッセージを確認してください。
予算アラートの設定
Cloud Runは無料枠があるため、ポートフォリオや小規模な個人開発のプロジェクトであれば、無料で運用可能ですが、
利用状況によっては課金が発生する可能性があります。
そのため、予算アラートを設定しておくことをおすすめします。
画面上部の検索バーに「予算」と入力して、予算のページを開きます。
予算を作成
ボタンをクリックして、予算の作成画面を開きます。
範囲
任意の名前を入力、期間は月別、プロジェクトは今回作成したプロジェクトを選択します。
サービスはすべてのサービス、クレジットはチェックをつけます。
設定したら、画面最下部の次へ
ボタンをクリックします。
金額
予算金額はここでは100円とします。
このように設定しておけば、月間100円を超えるとアラートが通知されます。
範囲を月別に設定しているので、月初にリセットされます。
設定したら、画面最下部の次へ
ボタンをクリックします。
操作
次に、アラートの操作を設定します。
予算の金額を超えたとき
のセクションで、メール通知を受け取る
にチェックを入れておくと、
予算を超えたときにメールで通知されます。
予算の割合の設定はデフォルトのままでも十分ですが、必要に応じて変更してください。
設定が完了したら、画面最下部の終了
ボタンをクリックします。
デプロイのスクリプトを追加
毎回イメージのビルド、プッシュ、Cloud Runのデプロイを手動で行うのは面倒なので、
スクリプトを作成して自動化します。
sample_app
ディレクトリにbin/deploy
という名前のファイルを作成します。
ハイライトされている箇所は適宜変更してください。
プロジェクトIDはGoogle Cloud Consoleのプロジェクトを選択すると調べることができます。
#!/bin/bash -e
docker build -t sample_app . --no-cache
PROJECT_ID="プロジェクトのIDを入力"REPOSITORY="Artifact Registryのリポジトリ名を入力"IMAGE_NAME="app"REGION="asia-northeast1"SERVICE_NAME="app"
IMAGE_TAG="${REGION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${IMAGE_NAME}:latest"
docker tag sample_app "$IMAGE_TAG"
docker run -it --volumes-from gcloud-config \ -v gcloud-config:/root/.docker \ -v /usr/bin/docker:/usr/bin/docker \ -v /var/run/docker.sock:/var/run/docker.sock \ gcr.io/google.com/cloudsdktool/google-cloud-cli:stable \ bash -c "docker push $IMAGE_TAG"
docker run --rm --volumes-from gcloud-config \ gcr.io/google.com/cloudsdktool/google-cloud-cli:stable \ gcloud run deploy "$SERVICE_NAME" \ --image "${IMAGE_TAG}" \ --region "${REGION}" \ --project "${PROJECT_ID}"
実行権限を付与します。
パスワードの入力を求めらるので、パスワードを入力してください。
sudo chmod +x bin/deploy
継続的デプロイの設定
毎回デプロイスクリプトを実行するのも大変なので、継続的デプロイを設定します。
Cloud RunはCloud Buildと連携して、GitHubから自動的にデプロイすることができます。
手元のパソコンからGitHubにコードをプッシュすると、GitHubからCloud Buildがトリガーされ、
自動的にDockerイメージのビルド、Artifact Registryへのプッシュ、
Cloud Runへのデプロイが行われます。
GitHubのリポジトリを作成しましょう。
リポジトリを作成したら...or push an existing repository from the command line
のセクションに表示されているコマンドを実行して、リポジトリを初期化します。
※アカウント名、リポジトリ名は適宜変更してください。
git remote add origin https://github.com/ihatov08/cloudrun-sqlite.gitgit branch -M maingit push -u origin main
次にGoogle Cloud ConsoleのCloud Runのページで継続的デプロイの設定
ボタンをクリックします。
現時点ではGoogle CloudとGitHubの連携がされていない場合は、認証
をクリックして、GitHubの認証を行います。
また接続されたリポジトリで、今回作成したリポジトリを接続しましょう。
設定完了後は次のような画面が表示されます。
設定が終わったら次へ
ボタンをクリックします。
次にビルドの設定を行います。
ビルド構成は、今回はmainブランチにpushされたときにビルドを実行するように設定します。
ビルドタイプはDockerfile
を選択、ソースの場所は/Dockerfile
に設定します。
設定が完了したら保存
ボタンをクリックします。
設定が完了するとリポジトリからのデプロイが実行されます。
どのような処理が行われているかログ
リンクをクリックしてみましょう。
ログ画面を見てみると、ビルドの概要で3個のステップが実行されていることがわかります。
- Build
- Push
- Deploy
つまり、Docker イメージのビルド、Artifact Registryへのプッシュ、Cloud Runへのデプロイが自動的に行われています。
適当にコードを変更して、GitHubにpushして、Cloud Runのデプロイが自動的に行われることを確認してみてください。
これでGitHubにPushするだけでCloud Runにデプロイされるようになりました。
【番外編】さらに無料に近づける..
ここまででCloud RunでWebアプリケーションをほぼ無料(3円/月)で動かすことができます。
さらに無料に近づける方法があります。
ここまでの方法では、アクセスがほとんどなくてもArtifact Registryで(1日当たり0.1円とはいえ)料金が必須でかかってしまいます。
コンテナレジストリであるArtifact Registryを使用せずにDocker Hubなどの外部のコンテナレジストリを使用することで、さらに無料に近づけることができます。
しかし、この方法には制約があります。
Cloud RunでDocker Hubなどの外部レジストリを使用する場合は、
2パターンの方法があります。
非公開イメージの場合
非公開のDockerイメージを使用する場合は、Artifact Registryのリモートリポジトリを経由する必要があります。
そのため、Artifact Registryの課金は避けられません。
公開イメージの場合
公開イメージの場合は、Artifact Registryを経由する必要がないので、課金を回避できます。
しかし、イメージを公開する必要があるため、ソースコードやDockerイメージを公開しても問題ない場合に限ります。
ポートフォリオなどの場合は、GitHubもPublicリポジトリで公開することが多いので、
Dockerイメージも公開してしまって問題ないでしょう。
また後で詳しく解説しますが、外部レジストリかつ公開イメージの場合は、latestタグを使用するとキャッシュが効いてしまうのか、
デプロイしても更新されないことがあります。
そのため、毎回タグを変更してデプロイする必要があります。
対応策については後ほど説明します。
制約のある外部レジストリの使用
つまり外部のレジストリを使い無料で運用するには、以下の制約があります。
- イメージを公開する必要がある
- 継続的デプロイ(Cloud Build)が使えない
これらのデメリットを受け入れられる場合は、外部のコンテナレジストリを使用することで、さらに無料に近づけることができます。
では、外部のコンテナレジストリを使用する方法を説明します。
継続的デプロイを停止する
外部レジストリかつ無料で運用するためには、継続的デプロイを停止する必要があります。
Cloud Runのページで、継続的デプロイの設定を開きます。
無効にする
ボタンをクリックして、継続的デプロイを無効にします。
Docker Hubのアカウントを作成
Docker Hubのアカウントを作成します。
ターミナルからログイン
アカウントを作成したら、ターミナルからDocker Hubにログインします。
次のコマンドを実行して、Docker Hubにログインします。
docker login
ブラウザが開くのでConfirm
ボタンをクリックします。
イメージのpush
次に、Docker Hubにイメージをプッシュします。
今回はsample_app
という名前でイメージをプッシュします。
<Docker Hubのユーザー名>
の部分には、Docker Hubのユーザー名を入力してください。
docker tag sample_app <Docker Hubのユーザー名>/sample_app:latest
タグをつけ終わったらイメージをプッシュします。
<Docker Hubのユーザー名>
の部分には、Docker Hubのユーザー名を入力してください。
docker push <Docker Hubのユーザー名>/sample_app:latest
イメージをpushしたら、Docker Hubにアクセスして、イメージがアップロードされていることを確認します。
https://hub.docker.com/repositories
Cloud Runの設定
次に、Cloud Runの設定を行います。
Cloud Runのサービスの詳細ページで新しいリビジョンの編集とデプロイ
ボタンをクリックします。
コンテナイメージのURL
を修正します。
<Docker Hubのユーザー名>/sample_app:latest
のように、Docker Hubのユーザー名とイメージ名を指定します。
たとえばDocker Hubのユーザー名がihatov08
の場合、次のようになります。
ihatov08/sample_app:latest
修正したら、画面下部のデプロイ
ボタンをクリックします。
Cloud Runのリビジョンがデプロイされるので、成功することを確認します。
デプロイのURLを修正
前述したとおり、外部のコンテナレジストリを使用する場合は、
毎回タグを変更してデプロイする必要があります。
そのため、デプロイのURLも変更する必要があります。
イメージのタグにタイムスタンプを付けて、毎回異なるタグを使用するようにします。
bin/deploy
のスクリプトを修正します。
DOCKER_HUB_USERNAME
の部分には、Docker Hubのユーザー名を入力してください。
GCP_PROJECT_ID
の部分には、Google CloudのプロジェクトIDを入力してください。
イメージのタグにタイムスタンプを付けるために、TIMESTAMP
変数を追加します。
#!/bin/bash -e
TIMESTAMP=$(date +%Y%m%d%H%M%S)
DOCKER_HUB_USERNAME="Docker Hubのユーザー名を入力"IMAGE_NAME="sample_app"GCP_PROJECT_ID="プロジェクトのIDを入力"
docker build -t ${DOCKER_HUB_USERNAME}/${IMAGE_NAME}:$TIMESTAMP . --no-cache
docker push ${DOCKER_HUB_USERNAME}/${IMAGE_NAME}:$TIMESTAMP
docker run --rm --volumes-from gcloud-config \ gcr.io/google.com/cloudsdktool/google-cloud-cli:stable gcloud run deploy app \ --image ${DOCKER_HUB_USERNAME}/${IMAGE_NAME}:$TIMESTAMP \ --region asia-northeast1 \ --project ${GCP_PROJECT_ID}
スクリプトの修正によって、毎回異なるタグでデプロイされるようになります。
これで制約はあるものの、外部のコンテナレジストリを使用して、Cloud RunでWebアプリケーションを無料で動かすことができます。
まとめ
Cloud Runを使ってWebアプリケーションを無料で動かす方法を学びました。
他のPaaSと比較しても料金が安く、かつAWSと比較すると使いやすいのが特徴です。
ぜひ皆さんもポートフォリオや小規模な個人開発のプロジェクトで活用してみてください。