#0. はじめに
仕事でherokuを使うことは全くないのですが、プライベートで作ったリポジトリを外部に公開するときは、Railsプロジェクトであればherokuを使うのはとても手っ取り早い良い方法だと思います。
仕事で使っていない以上、年に数回しかherokuに触ることなく、その度ごとにheroku固有のやり方やコマンドを忘れてしまうので、まとめていきたいと思います。
逐次追記する予定です。
#1. herokuでRailsを使いつつ、デプロイ時にトランスパイルする
私が作るRailsプロジェクトの多くは、frontendディレクトリを持ち、その中はfrontendの世界観で構成されており、webpackを使ってbabel等でトランスパイルしたファイルをapp/assets配下に吐き出し、sproketsで呼び出すというやり方をすることが多いです。
この辺りは以前一緒に働いていた方のこちらの記事をご参照ください。
仕事では、様々な事情から、トランスパイルしたファイルをgitに追加して運用しているのですが、自動生成されたファイルをcommitするのはよろしくないという思いがあるので、プライベートで作っているプロジェクトでは、トランスパイルしたファイルはcommitに含めていません。
当然ながら、.gitignoreにはapp/assets配下は除くように設定してあります。
/app/assets/javascripts/*
このような状況の中で、herokuにdeploy時にwebpackのコマンドも実行してあげる方法を記述します。
今回のRailsプロジェクトのディレクトリ構成は、
.
├── Gemfile
├── (省略)
├── app
├── frontend
│ └── package.json -> ../package.json (symbolic link)
└─ package.json
となっており、普段は、frontendディレクトリ下でnpm run watch
やyarn watch
を実行して開発を行うことが多いです。
package.json
は当初は、frontend配下に置いていたのですが、herokuのnodeのbuildpacksではリポジトリ直下のpackage.json
を見に行くようなので、リポジトリ直下にpackage.json
を置き、frontendディレクトリ直下にはリポジトリ直下のpackage.json
に対してシンボリックリンクを貼るような形にしています。
デプロイ後にnpm run release
を実行するために、package.jsonのheroku-postbuild
を追加します。このスクリプトは、herokuのbuildpacks(後述)のnodejsのところで実行されます。cd ../
コマンドなどはもしかしたら不要かもしれません。
"scripts": {
"release": "webpack --mode production --config webpack.config.js",
"watch": "webpack --mode development --watch --config webpack.config.js",
"heroku-postbuild": "cd frontend; npm run release; cd ../"
}
herokuには、buildpacksというものがあり、rubyを選んだ場合は、rubyしかないはずです。heroku buildpacks
コマンドで確認できます。
$ heroku buildpacks
=== your-app-name Buildpack URLs
1. heroku/ruby
今回はnode.jsも使用したいため、buildpackを追加します。
heroku buildpacks:add --index 1 https://github.com/heroku/heroku-buildpack-nodejs
ここで注意は、--index 1
とすることです。これを忘れると、デプロイ後、アクセス時にnpm start
が走ってしまい、エラーとなります。
このコマンド実行後のbuildpacks
は以下のようになると思います。
$ heroku buildpacks
=== your-app-name Buildpack URLs
1. https://github.com/heroku/heroku-buildpack-nodejs
2. heroku/ruby
これで通常通りgit push heroku master
などとすればdeploy時にまずnpm run release
コマンドが走り、app/assets配下にファイルを置いてくれます。
その後、railsのdeployが始まり、その中で、assets:precompileが行われ、ここから先はsproketsの世界になります。
sproketsが嫌な方はuglifyやダイジェストの付与等もwebpackにやってもらうような設定にしても良いかと思います。
#2. postgisを入れる。
地理除法をPostgreSQL上で扱うために使われるのがpostgisです。これのheroku上での利用方法について記載します。
まずは、buildpackを追加します。
heroku buildpacks:add --index 2 https://github.com/cyberdelia/heroku-geo-buildpack.giat
herokuのpostgresqlに接続(接続方法は下記の「よく使うコマンド」参照)し、EXTENSIONを作成します。
CREATE EXTENSION postgis;
このままだと、migrationする際に怒られます。
undefined method `st_point' for #<ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition:0x00000004ab9ab0>
herokuの中の環境変数のDATABASE_URL
を書き換える必要があります。(参照)
default: &default
adapter: postgis
production:
<<: *default
url: <%= ENV.fetch('DATABASE_URL', '').sub(/^postgres/, "postgis") %>
最後にmigrationの実行しカラムを追加します。
heroku run rake db:migrate
#2. postgresqlのデータをバックアップする
完全にコマンドのメモです。
既存のバックアップファイルの確認。バックアップを一度も実行したことない場合はNo backups found.などと出るはずです。
$ heroku pg:backups --app your-app-name
# --app your-app-name は -a your-app-name と同じ意味。
=== Backups
ID Created at Status Size Database
──── ───────────────────────── ─────────────────────────────────── ─────── ────────
b002 2018-03-10 14:22:16 +0000 Completed 2018-03-10 14:22:17 +0000 39.41kB DATABASE
b001 2018-03-09 15:26:41 +0000 Completed 2018-03-09 15:26:42 +0000 34.71kB DATABASE
=== Restores
No restores found. Use heroku pg:backups:restore to restore a backup
=== Copies
No copies found. Use heroku pg:copy to copy a database to another
バックアップを行います。
$ heroku pg:backups:capture --app your-app-name
Starting backup of postgresql-pointy-60299... done
Use Ctrl-C at any time to stop monitoring progress; the backup will continue running.
Use heroku pg:backups:info to check progress.
Stop a running backup with heroku pg:backups:cancel.
Backing up DATABASE to b001... done
これを行なった後、再度heroku pg:backups --app your-app-name
を実行すれば、Backupsのところに表示されるはずです。IDのところが大事です。
バックアップファイルをlocalに持ってくる方法になります。Macユーザーでcurlが入っていない場合は、homebrewなどでinstallしてください。publick-urlのあとのb001の箇所は前述のIDのところ値を入れます。
$ curl -o `date "+%Y%m%d%H%M%S"`.dump $(heroku pg:backups public-url b001 --app your-app-name)
バックアップしたファイルでlocalのpostgresqlにリストアします。ファイル名はcurlしたときに保存されたファイル名を指定します。
$ pg_restore --verbose --clean --no-acl --no-owner -h localhost -d your_database_name 20180101000000.dump
よく使うコマンド
- sshする
$ heroku run bash
- 直接rails consoleに行きたい場合
$ heroku run console
- migrationを実行する
heroku run rake db:migrate
- databaseに接続したい場合
$ heroku run console
でrails consoleに入り、
config = ActiveRecord::Base.configurations[Rails.env] || Rails.application.config.database_configuration[Rails.env]
にて、password
を調べる。
$ heroku run bash
$ rails db
Password: # ↑で調べたpasswordを入力