Herokuの登録からRailsアプリ（docker）のデプロイまで


# 内容

Docker勉強会用にHerokuの登録からデプロイまでの流れをまとめる。
[Docker 公式](https://docs.docker.com/samples/rails/)を参考にRailsアプリを作成する。

# 開発環境

MacOS Big Sur

Homebrew：3.3.1
Docker：20.10.8
Docker Compose：v2.0.0
heroku：7.59.1

# 登録方法
[heroku](https://jp.heroku.com/)から新規登録する。
無料アカウントを作成後、アカウントをアクティブ化するためのメールが届くので、リンクをクリックする。

[多段階認証(MFA)の登録](https://devcenter.heroku.com/articles/multi-factor-authentication)を求められるので、好きなものを追加する。

これで、登録は完了。

# heroku CLIのインストール

[The Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli)に書いてある下記のmac用のコマンドを実行する。

```
brew tap heroku/brew && brew install heroku
```

<details><summary>途中でエラーが発生した場合</summary><div>
自分の場合は途中でエラーが発生しました。

```
==> Installing heroku from heroku/brew
Error: Your Command Line Tools are too outdated.
Update them from Software Update in System Preferences or run:
  softwareupdate --all --install --force

If that doesn't show you any updates, run:
  sudo rm -rf /Library/Developer/CommandLineTools
  sudo xcode-select --install

Alternatively, manually download them from:
  https://developer.apple.com/download/all/.
You should download the Command Line Tools for Xcode 13.0.
```
内容を確認すると、コマンドラインツールが古いようなので、上から順番にコマンドを実行する。

```
softwareupdate --all --install --force
```
上記コマンドを実行後にCLIインストール用のコマンドを実行する。
同じエラーの時は、次のコマンドを実行する。

```
sudo rm -rf /Library/Developer/CommandLineTools
sudo xcode-select --install
```

再度、CLIインストール用のコマンドを実行する。
（多分これで成功するはず。）

</div></details>

# herokuへログイン

```
heroku login
```

上記コマンドを実行後、以下のように表示されるので、内容の通り、キーボードをタップする。
タップ後、ブラウザが立ち上がり、herokuのログイン画面が表示されるので、ログインする。

```
heroku: Press any key to open up the browser to login or q to exit: 
```

# Webアプリの作成

Ruby on Railsを使用したアプリを作成する。

ディレクトリ構造

rails_app/
 -docker-compose.yaml
 -dockerfile
 -entrypoint.sh
 -Gemfile
 -Gemfile.lock

公式のQuickstart: Compose and Railsを参考にして以下のファイルを作成する。

・docker-compose.yaml
・dockerfile
・entrypoint.sh
・Gemfile
・Gemfile.lock

Gemfile.lockのみ空ファイルを作成する。

```docker-compose.yaml
version: "3.9"

# コンテナ情報
services:
# データベースコンテナの情報（dbというサービス名で登録）
  db:
# 起動するコンテナ名を明示的に示す
    container_name: postgresql_db
# 利用するイメージの指定（バージョンは指定なし）
    image: postgres
# 記憶領域のマウント設定
# ローカルのデータディレクトリ：./tmp/db
# DockerEngine上のLinuxのディレクトリ：var/lib/postgresql/data
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
# db接続用のパスワード
# config/database.yamlのdefaultのpasswordにも同じパスワードを設定する
    environment:
      POSTGRES_PASSWORD: password
# アプリケーションのコンテナ（rails）の情報
  web:
    container_name: rails_app
# ビルド時のパスを設定（Dockerfileのパスを指定。gitリポジトリのパスなども可）
    build: .
# 起動時のコマンド情報
# rm -f tmp/pids/server.pidでtmp/pids/server.pidを削除してからrailsを起動する
# 上記コマンドを実行しないと、rails起動時にserver.pidがなんとか・・・とエラーになる
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app
# 別のサービスに依存していることを示す（上記のdbに依存していることを示す）
    depends_on:
      - db
# ポート番号のマッピング
    ports:
      - 3000:3000
```

db接続用としてPOSTGRES_PASSWORDは任意のパスワードを設定する。（ここではpasswordとしている）


```dockerfile.
FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
RUN mkdir /app
WORKDIR /app
ADD Gemfile /app/Gemfile
ADD Gemfile.lock /app/Gemfile.lock
RUN bundle install
ADD . /app

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]
```

```entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /app/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```

```Gemfile.
source 'https://rubygems.org'
gem 'rails', '~>5'
```

下記コマンドを実行して、プロジェクトを構築する。

```
docker-compose run --no-deps web rails new . --force --database=postgresql
```

再ビルドを行う。

```
docker-compose build
```

データベース接続用の設定を行う。
passwordにはdocker-compose.yamlで設定したPOSTGRES_PASSWORDのパスワードを入力する。

```app/config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password
  pool: 5

development:
  <<: *default
  database: app_development


test:
  <<: *default
  database: app_test
```

# デプロイ

herokuへのデプロイ方法は「事前にビルドしてデプロイする方法」と「heroku.yml を使用して Docker イメージをビルド​して、デプロイする方法」の2つがあるそうですが、今回は前者の方法でデプロイします。

herokuにログインしている状態で開始する。

以下のコマンドでherokuアプリを作成 createの後ろに名前を入力すると、その名前でアプリが作成される。

```
heroku create
```
イメージをビルドして、herokuにプッシュする

```
heroku container:push web
```

イメージをリリースする

```
heroku container:release web
```
ブラウザがオープンする（アプリを確認できる）

```
heroku open
```


#参考
https://docs.docker.com/samples/rails/

https://qiita.com/y_shinoda/items/1d02d3c63e003e6c7ea2

https://devcenter.heroku.com/categories/deploying-with-docker

https://programmingmemo.com/docker-rails-heroku/#Rails