HerokuにRailsアプリをデプロイしたときの備忘録です。
Herokuの基礎知識
あまり正確ではないかもしれませんが、理解のために要所々々で他(AWS等)のアナロジーを使用します。
dyno
Heroku内のアプリケーションはdyno(ダイノ)というlinuxコンテナの集合で実行されるそうで、dynoにはWeb, Worker, One-offという3つのプロセスタイプが存在します。HTTPリクエストを受け付けるのはWebで、workerは主にバックグラウンドジョブ、キューイングシステム、タイムドジョブ等の非同期処理に使用されます。つまりRailsアプリケーションはWebを担当します。
sulg
デプロイされたコードをパッケージしたもの。dynoで実行される。
buildpack
buildpack はデプロイされたコードを slug に変換する役目を担い、slug は dyno 上で実行することができます。 buildpack は一連のスクリプトで構成され、プログラミング言語に応じて、スクリプトは依存関係の取得や、生成されたアセットまたはコンパイル済みコードの出力などを行います。 この出力は slug コンパイラによって slug にアセンブルされます。
Dockerfileのようなものですね。つまりコンテナのビルドに利用されるものなので__Dockerfileと併用できません。__便利なだけに惜しい。
Procfile
起動時にアプリケーションが実行するコマンドの集合。ルートディレクトリに設置する。Procfileを使用しない場合はDockerfileのCMDなどが実行される。
add-ons
Heroku アドオンは、データストレージ、監視、分析、データ処理などの、アプリケーションをサポートするコンポーネントです。
AWSで例えるなら: dynoがECSでHerokuアドオンはRDSとかCloudWatchとかECSに連携するサービス
heroku.yml
Herokuアプリを定義するためのもの。アドオン、環境変数、起動時に実行するコマンドなどをまとめて定義できます。
AWSで例えるなら: ECSのタスク定義
Heroku CLI
インストールは以下を参照。
https://devcenter.heroku.com/ja/articles/heroku-cli
CLIコマンドは以下を参照。
https://devcenter.heroku.com/ja/articles/heroku-cli-commands
Dockerデプロイ
Dockerデプロイに関しては以下を参照。
https://devcenter.heroku.com/ja/articles/container-registry-and-runtime
Rails x nginx
1. buildpackを使用する場合
公式のbuildpackを使用します。buildpackを追加するコマンドは以下。
heroku buildpacks:add heroku-community/nginx -a <アプリ名>
nginxとソケット接続するには以下を行う必要があります。
- Your webserver listens to the socket at /tmp/nginx.socket.
- You touch /tmp/app-initialized when you are ready for traffic.
- You can start your web server with a shell command.
unicornはドキュメントのセットアップの欄に記載されているので、ここではpumaのセットアップのみ記載します。
# 1 /tmp/nginx.socketでlisten
bind "unix:///tmp/nginx.socket"
# 2 masterプロセスがworkerプロセスを生成するときに/tmp/app-initializedを生成する
require 'fileutils'
on_worker_fork do
FileUtils.touch('/tmp/app-initialized')
end
3. Procfileの内容を以下に設定
web: bin/start-nginx bundle exec puma -C config/puma.rb
2. Dockerfileを使用する場合
私が調べた範囲ではPhusion Passengerを利用するしかなさそうです。
参考
passenger-dockerでRailsアプリをコンテナ化する(3. 本番モードでコンテナ化する)
3. リバースプロキシ(nginx)を使用しない場合
Webへのポート番号はHeroku側が勝手に割り振って値を$PORTに代入するので
port ENV.fetch("PORT") { 3000 }
bundle exec puma -C config/puma.rb
とすれば外部から接続できます。
Rails x MySQL
公式のadd-onを使用します。add-onを追加するコマンドは以下。
heroku addons:create cleardb:<plan> -a <アプリ名>
無料のプランはigniteです。
上記のコマンドを実行するとデータベースのURLが環境変数に追加されます。環境変数を表示するコマンドは以下。
heroku config -a <アプリ名>
CLEARDB_DATABASE_URL: mysql://<ユーザー名>:<パスワード>@<ホスト名>/<データベース名>?reconnect=true
$CLEARDB_DATABASE_URLの情報からconfig/database.ymlに設定した環境変数にそれぞれ値を代入します。
CircleCIでデプロイ
公式にOrbsがあります。
https://circleci.com/developer/orbs/orb/circleci/heroku
Long-lived APIキーを生成するコマンドは以下。
heroku authorizations:create
生成したトークンをHEROKU_API_KEYとしてCircleCIの環境変数に設定することで
heroku container:login
でherokuのコンテナを操作できるようになります。
因みにDockerコマンドで直接pushする場合、イメージのタグは:latestでないとreleaseしたときに404エラーになります。
Route53で取得したドメインを使用する
以下の記事が参考になりました。
- Herokuでカスタムドメイン(ルートドメイン)を使うためにCloudFrontを設定する
- HerokuアプリにAWS Route53 で取った独自ドメインを割り当て、 Certificate Manager + Cloudfront を使ってhttps化する
HerokuアプリはTerraformでも定義できます。
https://registry.terraform.io/providers/heroku/heroku/latest/docs