Fly.io→GCP移行計画
全体像
code:plan.md
【事前作業】
Phase 1 ✅ Cloud SQL セットアップ
Phase 2 ✅ コード変更(feature ブランチで)
Phase 3 ✅ GCP セットアップ
Phase 4 ✅ Docker ビルド & イメージ push
【本番切り替え】一気にやる(約1時間)
★ メンテモード ON ★
Phase 5 ✅ 最終ダンプ → Cloud SQL に投入
Phase 6 ✅ Cloud Run デプロイ
Phase 7 ✅ フロントのAPI向き先切り替え & 動作確認
Phase 8 ✅ Fly.io 停止
NeonDBのセットアップ(CloudSQLにすることにした)
会員登録してDB準備する。→なし
GCPのセットアップ
CloudRun
Artifact Registry 作成
Secret Manager に登録
請求アラート
止める方法
もう少し調べる
M1/M2 Mac の場合は --platform linux/amd64 が必須。これを忘れると Cloud Run で動かない。
なぜ?
mac上でビルドした時に、arm64 向けのイメージが作られることにより、CloudRunのアーキテクチャで動かない
実際
ドキュメント
それ以前にIAMの設定したほうがいいかも。
実装変更
ポスグレのgem入れる
productionの接続情報変える
メンテ画面
Dockerfileに必要なランタイム入れる
DBのバックアップを取る
Fly.ioからバックアップをとっておく。NeonDB用。
今のサービスではそこまでは求めないとはいえ、移行期間中の書き込みどうしよう。
メンテ期間を用意すればいい
バックアップを取るのは、メンテ画面にしてから。
でも最初にできるかどうか試すのはあり。
データ移行
SQLite の dump から PostgreSQL 向けに変換して流す
もう少し詳しく調べる
メンテナンス画面
DBの移行と同時に走らせるリリース
そのドメインにアクセスしたらメンテ画面に移動させる感じ
セキュリティ
Neonに接続できるDBを制限する。
Cloud Run はリクエストのたびにインスタンスが起動し、Google の IP プールから動的に IP が割り当てられます。固定 IP ではないので、Neon 側で「この IP だけ許可」ができません。
な〜る
勉強代覚悟でGCPのDB利用してもいいかもな。GCPにしよう。
---
Actions
これはまあ後ででいいかな。
---
ここから実践
GCP設定
IAM
必要なもの作る。
APIを有効化したらサービスアカウントが発行されたので、それにIAMで権限付与していく。
https://scrapbox.io/files/69bc84d2b9e150750aebc7db.png
編集者権限は消して、他のを付与した。
Cloud SQL
https://scrapbox.io/files/69bc8674b9e150750aebc8e2.png
最初だけON
DBの種類選択
名前が「本番」とかあるけど、これはGCP上での呼び名だからまあ気にしなくてスペックを見ればいい
db-f1-micro
Cloud SQL Auth Proxy が IAM 認証を通った接続だけを許可するから、Public IPで良い
共有コア
CPU を複数のインスタンスで共有する
✅ できた
Cloud Run
特に難しいことはなくできた。
デフォルトのヘルスチェックは8080ポートなのでそこだけ後でDockerfileを変える。
起動しただけだな。
TODO
--set-secrets DATABASE_URL=DATABASE_URL:latest
こういうデプロイは面倒だから後でactionsにするとか調べる
Artifact Registory
Dockerイメージ置く場所
不変のイメージタグは無効
「同じタグ名で上書き push を禁止する」設定
常に最新版
コスト抑えられる
バックアップとかとるならこれかな
クリーンアップポリシーも1
ここは色々設定した。
✅ できた
Secret Manager
環境変数置く場所
https://scrapbox.io/files/69bcd3bdb9e150750aec1e45.png
Cloud Run はデフォルトでこのサービスアカウントを使って動く。
そのアカウントにSecret Manager にアクセスしていいという権限は付与すみ。
請求アラート
✅設定した。
ここで見覚えのないプロジェクトが出ていたが、プロジェクトナンバーが出ているだけだった。
gcloudやpythonに少しはまる。
実装
メンテモードやgemの切り替えなどのPR作成。タイミング見てマージする。
ただし、Fly.ioが壊れないようにメンテ部分だけのデプロイがいいかな。
flyioはhealth check用のエンドポイントにアクセス失敗しないようにする必要があった。
DB移行準備
SQLite→Postgresの情報調べる
pgloader
今後の値については、ActiveRecordがいい感じにしてくれるから問題なし
cloud-sql-proxyも使う
Cloud SQL Auth Proxy は、承認済みネットワークや SSL の構成を必要とせず、安全にインスタンスにアクセスできる Cloud SQL コネクタです。
gcloud auth application-default loginをした上で利用する
The proxy has started successfully and is ready for new connections!
別ターミナルで実行できる状態になった。
問題
localhost がIPv6の ::1 に解決されていた
MacのDNS解決では localhost が IPv6アドレス ::1 に変換されることがある
psqlは ::1:5432 に接続しようとした
Auth Proxyは 127.0.0.1(IPv4)でリッスンしていた
ログに Listening on 127.0.0.1:5432 と明示されている通り、IPv4のみ待ち受けていた
結果として接続先(::1)と待ち受けアドレス(127.0.0.1)が一致せず接続失敗
解決
-h 127.0.0.1 でIPv4アドレスを明示した
これによりpsqlが 127.0.0.1:5432 に接続しようとした
Auth Proxyの待ち受けアドレスと一致したので接続成功
sqliteの本番データを手元に落としてきた
cloud-sql-proxyで接続しつつ、pgloaderで移行
パスワードがまた問題起こしたので、色々やった
code:plain
Auth Proxyの場所127.0.0.1
接続しようとした場所が ::1
同じlocalhostという名前なのに、別の場所である
そんな場所ない!と弾かれた
✅ ログが出て成功table name errors rows bytes total time
件数もあってそう
Docker Build
本番用のイメージをビルド
gcloud auth configure-docker
pushするとartifact registoryに行く
確認できたので、コード変更をマージしてメンテ変数セット。次はDB移行へ。
→と思ったがコード差分がflyioを壊しそうなので、落ち着いてまた後で。
pgloader使うかは要調査
メンテモードに入れた後
Cloud Run
コマンドでデプロイ。
エラーログ確認
code:plain
gcloud logging read
エラーたち
記号とエンコードに関する問題が起きた
再プッシュ時に、イメージも再プッシュしないといけなかった
gcloudがpg gem 読み込まない現象で激ハマり
DB名が違ってdb:prepareができな買った
config.cache_store = :memory_store, { size: 32.megabytes } productionで読み込みたいミング悪いところに書いていた
Dockerのキャッシュ
COPY . . のような命令でファイルをコピーする前の層がキャッシュされていると、ファイルを変更しても古いキャッシュが使われることがある
DBユーザー名
postgresはデフォルトだった
GUIから作る場合ユーザータブ
デプロイできたが、502
前のリビジョンのキャッシュだった
https://scrapbox.io/files/69bddfcdb9e150750aed0ff6.png
フロントが指すAPIのURL変更
データ移行後に変更
Devtool見ても向き先が古いままだった
変更後にredeployが走らなかったので手動実行
サービスURL
常に最新(アクティブな)リビジョンに自動で向く
フロントのAPIの向き先に設定すべきURL
再デプロイしても変わらない
リビジョンURL
特定のリビジョンに直接アクセスするURL
デプロイのたびに新しいものが増える
古いバージョンのテストなどに使う
エラー
向き先はあっていて、ルーティングもあっているが502が変える。
完了!!!!
後で
Cloud Loggingの値段
プロジェクトの最初の 50 GB は、無料枠の割り当て分になりますのでご注意ください。
大丈夫そう
AI総括
全体の流れ
Fly.io + SQLite → Cloud Run + Cloud SQL (PostgreSQL) への移行
フロントエンドは変更なし
Phase 1〜3:事前準備
IAM設定、Cloud SQLインスタンス作成
コード変更(Gemfile, database.yml, Dockerfile 等)
Artifact Registry, Secret Manager, 請求アラート設定
Phase 4:Dockerビルド&デプロイ
トラブルと解決策
Cloud SQLに接続できない
原因:インスタンス名ミス
対策:正しいインスタンス名に修正
Thrusterが8080をlistenしない
原因:HTTP_PORT のデフォルトが3000になっていた
対策:Dockerfile に ENV HTTP_PORT=8080 を追加
pgが見つからないエラー
原因:Dockerのキャッシュが古かった
対策:--no-cache でリビルド
Phase 5:データ移行(SQLite → PostgreSQL)
pgloaderを使用して移行
パスワード系のエラー
Phase 6:本番切り替え
1. フロントのAPIの 向き先をCloud RunのURLに変更
2. 動作確認OK → Fly.ioをGUIから停止