はじめに
職場でRedmine使って色々管理している流れで、ちょっと自宅でお試し環境を作りたくなり、ついでにGCPのAppEngineも試したかったので、AppEngine上でRedmineを実行してみた際の手順をまとめてみました。
参考
環境
- ローカルにgcloudコマンドラインツールを入れるのが面倒だったので、GCPのコンソールから支えるCloudshellから操作を行いました。
- データベースにはCloud SQLを使って構築したPostgreSQL11を使っています。
- mysqlを使わなかった理由: Cloud Shell環境でgem install mysql2が失敗したから。(mysql-develが必要なのだが、Cloud Shell環境にインストールするのは難しそうだとハナから諦めました。)
- AppEngineはFlexible環境を使いました。
- 標準環境を使わなかった理由: Ruby2.5の環境がなかったから。
手順
まずは、プロジェクトを作成します。
Cloud Shellなら、gcloudコマンドがすぐに使えて楽。
# ここでは"testtest-001"という名前のプロジェクトを作っています。
gcloud projects create testtest-001 --name testtest-001
# 作ったら、カレントプロジェクトに設定してあげます。
gcloud config set project testtest-001
次に、データベースのインスタンスを作成
PostgreSQL 11のインスタンスには仮想サーバのサイズ指定が必要とのことで、cpuとmemoryサイズを指定しています。(1cpu, 4GB memoryにしておきました。)
gcloud sql instances create test-redmine-001 --no-backup --database-version=POSTGRES_11 --root-password=PASSWORDYYYYMMDD --region=asia-northeast1 --cpu=1 --memory=4G
できたか確認します。
gcloud sql instances describe test-redmine-001
一応、コンソールからも確認してみたところ、
「課金を有効にしますか?」
的な事を聞かれます。
躊躇したくなりますが、無料トライアル期間中なので、OKしてしまった。
(無課金では試せません。あしからず。。)
Cloud SQL APIを有効にします。
全てコマンドでできました。
# まず、Cloud SQL Admin APIのサービス名を確認
gcloud services list --available | egrep "SQL"
# => 結果から、sqladmin.googleapis.comをコピーしまして。
# まず、Cloud SQL Admin APIを有効化
gcloud services enable sqladmin.googleapis.com
# => 以下のような結果になればOK
# Operation "operations/[なんかのID]" finished successfully.
続いてCloud Build APIも有効化します。
SQL Admin APIの際とほとんど似たような手順(名前を確認して有効化)ですね。
gcloud services list --available | egrep "build"
=> cloudbuild.googleapis.com
gcloud services enable cloudbuild.googleapis.com
そしたら、CloudBuildのサービスアカウントに編集者権限を付与
ここ、Cloud Build APIを有効化しておかないと、「そんなアカウントはありません」エラーとなりますのでご注意を。
gcloud projects add-iam-policy-binding [プロジェクトID] --member=serviceAccount:[プロジェクト番号(※)]@cloudbuild.gserviceaccount.com --role=roles/editor
# 例
# gcloud projects add-iam-policy-binding testtest-001 --member=serviceAccount:123456789012@cloudbuild.gserviceaccount.com --role=roles/editor
# ※プロジェクト番号は以下のコマンドの結果で調べられます。(一番右の数字。。PROJECT_IDじゃないので気をつけましょう。)
gcloud projects list
# 出力例>
# PROJECT_ID NAME PROJECT_NUMBER
# testtest-001 testtest-001 123456789012
# testtest-003 testtest-003 345678901234
いよいよ、redmineの本体を準備。
まずはgithubからredmine本体を取得。
# githubからcloneします。
git clone https://github.com/redmine/redmine.git
そしてdatabase.ymlの設定
# redmineのディレクトリに移動
cd redmine
# database.yml.exampleをコピーしてdatabase.ymlを作る(自信ある方はゼロから作っても大丈夫。)
cp config/database.yml.example config/database.yml
# コピーできたら、database.ymlの編集です。
# production環境の接続設定だけいじりました。
vi config/database.yml
# 中身は次のセクションを参照してください。
database.ymlの中身はこちら。
production:
adapter: postgresql
database: redmine
host: '/cloudsql/testtest-001:asia-northeast1:test-redmine-001'
# <= "/cloudsql/" に
# <= "gcloud sql instances describe インスタンス名"で取得したconnectStringの値をつなげるのです。
username: postgres
password: "PASSWORDYYYYMMDD" # <= postgresユーザのパスワード
次、デプロイに便利なappengineを追加
appengineはGCP環境にrubyアプリをデプロイするための便利Gemです。
bundle addしてから、bundle installします。
# まずはappengineをGemfileに追加。(直接編集しても良い。)
bundle add appengine
# そして、bundle installといきます。
# (これやらなかったら、あとのデプロイ(gcloud app deploy)で失敗した。。)
bundle install
そして、appengineにデプロイしてもらうためのapp.yamlを作ります。
チュートリアルには作る場所がはっきり書かれてない気がしますが、アプリケーションのルートディレクトリに作ります。
(githubからクローンした人は、redmineディレクトリ直下です。)
# まずはチュートリアルからもらった内容をそのまま書いてしまいます。
entrypoint: bundle exec rackup --port $PORT
env: flex
runtime: ruby
env_variables:
SECRET_KEY_BASE: [SECRET_KEY]
beta_settings:
cloud_sql_instances: [YOUR_INSTANCE_CONNECTION_NAME]
そして、上のファイルの[SECRET_KEY]を以下のコマンドの結果で上書きします。
bundle exec rails secret
# 出力例=>
881cf9bd..... 長いのとセキュリティ上良くないので以後省略。。すみません。
さらに、[YOUR_INSTANCE_CONNECTION_NAME]
をインスタンス接続名で上書き。
(/cloudsql/は書きません。)
以下実際に設定してみたサンプルです。
# 実設定入れてみた感じ。
entrypoint: bundle exec rackup --port $PORT
env: flex
runtime: ruby
env_variables:
SECRET_KEY_BASE: 881cf9bd.....(本当はすげー長い。)
beta_settings:
cloud_sql_instances: testtest-001:asia-northeast1:test-redmine-001
ようやくAPP Engineを作ってデプロイ!
こちらもコマンドで。
今回の手順、コンソールを使う作業はほとんど行いませんでした。
gcloud app create --region=リージョン名(ap-northeast-1などなど)
# --regionを指定しない場合は、途中で聞かれます。
# 仕掛けて、トイレ行って戻ったときに終わってなくてがっかりしました。
できたかな?
できたら、デプロイ!!(急ぎすぎですが、大丈夫。)
gcloud app deploy
# 途中で確認画面が出ますので元気に"Y"で答えましょう。
そして一度失敗を経験する。
先ほどのコマンドですが、最後必ず失敗します。
Updating service [default] (this may take several minutes)...failed.
ERROR: (gcloud.app.deploy) Error Response: [9]
Application startup error! Code: APP_CONTAINER_CRASHED
bundler: failed to load command: rackup (/app/vendor/bundle/ruby/2.6.0/bin/rackup)
ActiveRecord::NoDatabaseError: FATAL: database "redmine" does not exist
# => そりゃそうだよ、redmineなんていうデータベース作ってないもん。
気を取り直してDBの準備。
失敗しても落ち込む暇はないのです。
DBを準備しましょう。
# まずはデータベースを作成
bundle exec rails appengine:exec -- bundle exec rails db:create
# 出力例
# ---------- CONNECT CLOUDSQL ----------
# cloud_sql_proxy is running.
#
# ---------- EXECUTE COMMAND ----------
# bundle exec rails db:create
# Created database 'redmine'
#
# ---------- CLEANUP ----------
# PUSH
# DONE
#
# 次にテーブルの作成など。
bundle exec rails appengine:exec -- bundle exec rails db:migrate
# 出力例
# ---------- CONNECT CLOUDSQL ----------
# cloud_sql_proxy is running.
#
# ---------- EXECUTE COMMAND ----------
# bundle exec rails db:migrate
#
# ...ここから、create table結果の嵐。
#
# ---------- CLEANUP ----------
# PUSH
# DONE
#
# んで、デフォルトデータの投入(これやらないと使い物にならんですね。redmine)
bundle exec rails appengine:exec -- bundle exec rails redmine:load_default_data REDMINE_LANG=ja
# <= コマンドの後ろに"REDMINE_LANG=ja"で使用言語を設定しているところがミソ。
# <= 。。。無いとプロンプトが返されるみたいでタスクが失敗します。
# 出力例
# ---------- CONNECT CLOUDSQL ----------
# cloud_sql_proxy is running.
# ---------- EXECUTE COMMAND ----------
# bundle exec rails redmine:load_default_data REDMINE_LANG=ja
# Default configuration data loaded.
# ---------- CLEANUP ----------
# PUSH
# DONE
隊長!起動準備が整いました。
- アプリケーションはエラーを起こしながらもデプロイはできた。
- データベースインスタンスを起動して、redmine用のデータベースもできた。
- データベースのテーブル作成もできた。
- デフォルトデータも投入した。
ということで、起動準備完了。
先ほどデプロイに失敗したやつを起動して差し上げます。
# まずはサービスの状態を確認。
> gcloud app versions list
# 出力例(STOPPEDになってますね。)
# SERVICE VERSION.ID TRAFFIC_SPLIT LAST_DEPLOYED SERVING_STATUS
# default 20200412t165521 1.00 2020-04-12T11:00:15+09:00 STOPPED
# そしたら、起動
> gcloud app versions start 20200412t165521
# 出力例
# Starting the following versions:
# - testtest-001/default/20200412t165521
Do you want to continue (Y/n)? Y <= 続けてよいか聞かれるのでYを答える。
# Waiting for operation [apps/testtest-001/operations/349e4332-2923-40de-a840-12f034daa670] to complete...done.
隊長!お気を確かに!!
!!やった起動成功!!!と誰もが思います。
早速、ページが開けるかみてみましょう。
ページのアドレスは以下のコマンドで確認できます。
gcloud app services browse default --no-launch-browser
# 出力例
SERVICE URL
default https://testtest-001.an.r.appspot.com
ブラウザにアドレスをコピペして。。。
表示!!でき。。ない。
・・・Temporary Unavailable的なメッセージが。。
・・・30秒後にもう一回来いとな。
任務完了
ということで、念のため1分待ってからもう一回アクセス。
やっと会えた!
ハマったことまとめ。
- サービス起動してからページが開けるようになるまでに、結構時間がかかるのを知らず、最初は非常に焦って、色々調べてしまいましたが、「待てば良い」それだけでした。
- 他にも、API有効化してから使えるようになるまで、タイムラグがある感じがします。ので、「ちょっと待ってみる」気持ちの余裕が必要かと。
- 当初、Cloud ShellはApp Engineの実行環境ではない。というのになかなか気がつかず(お恥ずかしい。。)、プロジェクト移動したのに同じディレクトリが見えるのが「何かの間違い」だと思い込み、無駄な時間を過ごしました。
- ドキュメントページに用意されているチュートリアルを試さずに始めてしまったので、理解に時間がかかりました。やはり、チュートリアル素晴らしい。