Herokuへのデプロイ時に苦労した話
昨日完成したTodoアプリをHerokuにアップしました!
その際2箇所でつまづいたので、記録しておきます。
pg gemがインストールできない
HerokuではSQLiteがサポートされていないのでPostgreSQLを使います。
sqlite3 gemをproduction環境で使わないように、
そしてpg gemをproduction環境で使うようにgemfileを編集し、bundle install
したところ
Building native extensions. This could take a while... ERROR: Error installing pg: ERROR: Failed to build gem native extension. (略) Can't find the 'libpq-fe.h header
libpq-fe.h が見つからない、というエラーが出ました。
このエラーの処理は
$ sudo yum install postgresql-devel
で解決。
(yumというのを使ってPostgreSQLをインストールするということらしいです)
(本筋と関係なし)
無事にpg gemもインストールできたのでherokuにpushしました。
デプロイしたページにアクセスすると……
We're sorry, but something went wrong
ああ……
色々調べた結果、
「production環境でrails_12factorというgemを有効にする必要がある」
という情報にたどり着き、gemfileに追記したのですが
調べ直したところこの情報はRailsチュートリアル第4版から、つまりRails5になってからは記載が無くなった情報なので、今はもう必要ないのかもしれません。
本題は次のエラーです。
Userテーブル作成時のマイグレーションファイルを削除してしまった
heroku logs
で確認してみると、rootページへのGETリクエストは成功しているけどその後移動するログインページで500エラーが出ていました。
データベースの問題じゃないかと思ってdb:migrateを実行してみると……
$ heroku run rake db:migrate
Running rake db:migrate on ⬢ rocky-beyond-45744... up, run.9472 (Free) (0.8ms) SELECT pg_try_advisory_lock(2653661978130648765) (1.3ms) SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC Migrating to AddUserRefToTasks (20180827040204) (0.8ms) BEGIN == 20180827040204 AddUserRefToTasks: migrating ================================ -- add_reference(:tasks, :user, {:foreign_key=>true}) (略) (1.4ms) ROLLBACK (5.0ms) SELECT pg_advisory_unlock(2653661978130648765) rake aborted! StandardError: An error has occurred, this and all later migrations canceled: PG::UndefinedTable: ERROR: relation "users" does not exist (略) Caused by: ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "users" does not exist
usersテーブルが存在しない、というエラーが出ました。
ん?と思ってdb/migrateを確認すると、Userモデルを作成したときのマイグレーションファイルが無い。
Devise導入の際にrails g devise User
でUserモデルが作成できているのかわからず試行錯誤したのですが、
どうやらその時に作成されたマイグレーションファイルを削除してしまったようです。
解決方法
この記事を参考に以下の処理をしました。
状況
削除してしまったマイグレーションファイルのIDを調べます
$ bundle exec rake db:migrate:status
database: 省略/db/development.sqlite3 Status Migration ID Migration Name -------------------------------------------------- up 20180823030402 Create tasks up ★20180826083613 ********** NO FILE ********** up 20180827040204 Add user ref to tasks up 20180829041636 Add row order to tasks
NO FILE になっているIDが今回間違えて削除してしまったマイグレーションファイルです。
そして、Statusがupになっているマイグレーションファイルはデータベースに取り入れられているものです。
本番環境でマイグレーションを実行した時に、★20180826083613のファイルが存在しないので冒頭のエラーが出てしまった、という状況ですね。
対処方法
プロジェクトのdb/migrateディレクトリに移動します
$ cd db/migrate
ここで、先程確認した間違えて消してしまったファイルと同じIDのマイグレーションファイルを作成します。
$ touch マイグレーションID_ファイル名.rb
今回の場合だと
$ touch 20180826083613_devise_create_users.rb
になります。
作成したマイグレーションファイルに内容を書き込みます。
私の場合はDevise練習用に作成した別のプロジェクトがあったのでそこから引っ張ってきました。
# frozen_string_literal: true class DeviseCreateUsers < ActiveRecord::Migration[5.2] def change create_table :users do |t| ## Database authenticatable t.string :email, null: false, default: "" t.string :encrypted_password, null: false, default: "" (略) add_index :users, :email, unique: true add_index :users, :reset_password_token, unique: true # add_index :users, :confirmation_token, unique: true # add_index :users, :unlock_token, unique: true end end
これで間違えて削除してしまったマイグレーションファイルが復活した状態になったので
$ git add . $ git commit $ git push heroku master
でherokuにプッシュし、再度 本番環境でdb:migrate
$ heroku run rake db:migrate
うまくいきました!
これでアプリケーションの作成からHerokuへのデプロイまでをひと通り完了することができました。
次に何をするか考えようと思います。