Rails on DockerをHerokuでDeployするまで

# はじめに
Rails on DockerのアプリケーションをHerokuにデプロイするメモ。

# 前提
docker-compose.ymlの中身は以下の通り。ローカルではappとdbの2つのコンテナを作って開発してました。

```yaml:docker-compose.yml
version: "3"

services:
  db:
    container_name: sample_db
    image: postgres:11.5-alpine
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  
  app:
    container_name: sample_app
    build: .
    volumes:
      - .:/app
    depends_on:
      - db
    ports:
      - 3000:3000
```
Rails用のappサービスとPostgreSQLをDBとして使うためのdbサービスを定義している。
Herokuでこの2つのコンテナを稼働させようと思ったけど、Herokuの制約でvolumeは使用できない（Herokuのfilesystemは一時領域）のでPostgreSQLはHerokuのadd-onsのものを利用する。
つまり、appサービスで定義しているコンテナをHerokuで起動させ、add-onsのPostgreSQLと接続されることでデプロイが完了する。今回のアプリケーションではDockerfileはappサービス側分しかないので、Herokuがいい感じにコンテナの管理もしてくれる。

また、Herokuのアカウント登録は完了している前提で書きます。
macでbrewコマンドが使えることも。

# 手順
1. herokuコマンドのインストール
2. heroku-cliにログイン
3. Container Registryにログイン
4. Herokuでアプリを新規作成
5. Container Registryにdocker imageをpush
6. Heroku add-onsのpostgresqlを作成
7. webプロセスタイプをリリース
8. DB migration
9. 動作確認

### herokuコマンドのインストール
詳細は公式サイトから。「[The Heroku CLI | Heroku Dev Center](https://devcenter.heroku.com/articles/heroku-cli#download-and-install)」

macの場合は

```
$ brew tap heroku/brew && brew install heroku
```
でインストールできます。

### heroku-cliにログイン
以下のコマンドからHerokuにログインします。

```
$ heroku login

Logging in... done
Logged in as xxxxxxxxxx@sample.com
```
ブラウザに遷移するのでログインすればそのアカウントでheroku-cliを使えるようになります。

### Container Registryにログイン
Container RegistryはHerokuでDockerイメージをデプロイするためのサービスです。まずはContainer Registryにログインします。

```
$ heroku container:login

Login Succeeded
```

### Herokuでアプリを新規作成
heroku-cliからアプリを新規作成します。`$ heroku create [app name]`でアプリ名を指定するとそのアプリ名で作成されます（下記の例は"sample-app"というアプリ名にした場合）。アプリ名を指定しない場合はHerokuが適当につけてくれます。

```
$ heroku create sample-app

Creating ⬢ sample-app... done
https://sample-app.herokuapp.com/ | https://git.heroku.com/sample-app.git
```

### Container Registryにdocker imageをpush
ローカルで作成したdocker imageをHerokuのContainer Registryにpushします。`$ heroku container:push [process type]`でpushできます。

```
$ heroku container:push web
```
process type（プロセスタイプ）はHerokuの中のアプリケーションの区切りみたいなものです。`web` process typeは予約語みたいなものでwebサーバーとして起動させるやつに割り振らねばなりません。

プロセスタイプの理解が弱くて、`app`を指定していてハマってました...
参考）[Heroku Dynos - 設定 | Heroku](https://jp.heroku.com/dynos/configure)

### Heroku add-onsのpostgresqlを作成
前提で述べた通り、Herokuではvolumeを使えないのでadd-onsのpostgresqlをDBとして使うことが推奨されています。postgresql add-onsの詳細は「[Heroku Postgres - Add-ons - Heroku Elements](https://elements.heroku.com/addons/heroku-postgresql)」に載っていますが、今回は無料のHobby Devを利用します。

```
$ heroku addons:create heroku-postgresql:hobby-dev
```

### webプロセスタイプをリリース
5でpushしたwebプロセスタイプをdynoでリリースしてきます。

```
$ heroku container:release web
```

### DB migration
通常のrailsアプリケーションと同様、`db:migrate`を事前に実行します。`db:create`はすでにされているらしい（addons:createの時点かな）。今回は[seed_fu](https://github.com/mbleigh/seed-fu)を使って初期データを投入したいのでそれも実施します。

```
$ heroku run rails db:migrate
$ heroku run rails db:seed_fu #seed_fuを使っている場合のみ
```

### assets:precompile
production環境の場合、assetのプリコンパイルが必要です。

```
$ heroku run rails assets:precompile
```
これでアセットのプリコンパイルも完了。

### 動作確認
ここまででデプロイ完了です。動作確認してみます。

```
$ heroku open
```
ブラウザでアプリが見れたら成功です。
サンプルの成果はこちら --> [hiradumi](https://hiradumi.herokuapp.com/)

# Appendix
上記の手順だとRAILS_ENV=developmentでアプリが立ち上がっている状態です。
productionで立ち上げるためには

```
$ heroku config:add RAILS_ENV=production
```
で環境変数をセットします。
また、assets:precompileらへんのエラーが出てアプリが立ち上がらなくなったりした場合は、「[Herokuで "is not present in the asset pipeline." が出るときの応急処置 - コネクト](https://connect-solution.net/jp/2019/07/03/heroku%E3%81%A7-is-not-present-in-the-asset-pipeline-%E3%81%8C%E5%87%BA%E3%82%8B%E3%81%A8%E3%81%8D%E3%81%AE%E5%BF%9C%E6%80%A5%E5%87%A6%E7%BD%AE/)」などを参考にして応急処置を。

# Reference
- [The Heroku CLI | Heroku Dev Center](https://devcenter.heroku.com/articles/heroku-cli#download-and-install)
- [Heroku CLI Commands | Heroku Dev Center](https://devcenter.heroku.com/articles/heroku-cli-commands)
- [Heroku Dynos - 設定 | Heroku](https://jp.heroku.com/dynos/configure)
- [Heroku Postgres - Add-ons - Heroku Elements](https://elements.heroku.com/addons/heroku-postgresql)
- [DockerでRailsの環境構築してHerokuへデプロイする - Qiita](https://qiita.com/fuku_tech/items/dc6b568f7f34df10cae7)