DockerでRailsの環境構築を一つ一つ丁寧に読み解きながらやってみた（docker-compose.yml編）

## この記事の内容
`Docker` & `Rails`で新規プロジェクトを立ち上げることになったので、Docker周りのファイルを丁寧に読み解きながら設定した時の話。

これまでに[Dockerfileの設定](https://qiita.com/tanutanu/items/808850ed7e4e8461b24b)はやっているので、今回はその続きから。

▼前回の記事
[RailsでDockerfile設定しながら、コマンド一つひとつ丁寧に読んでみた](https://qiita.com/tanutanu/items/808850ed7e4e8461b24b)

▼Railsのバージョン
６.1.4

## 参考にした内容
今回も[公式のRailsの設定ガイド(Quickstart: Compose and Rails)](https://docs.docker.com/samples/rails/)を参考にしつつ、バージョン等を最新版（2021年8月時点）にアップデートして作成しました。

- [Quickstart: Compose and Rails](https://docs.docker.com/samples/rails/)

あとは[こちらの記事](https://qiita.com/kodai_0122/items/795438d738386c2c1966)。当時初学者さんだったのにすごい。

- [DockerでRuby on Railsの環境構築を行うためのステップ【Rails 6対応】](https://qiita.com/kodai_0122/items/795438d738386c2c1966)


## `docker-compose.yml`の内容

まずは、[先にあげた公式ガイド](https://docs.docker.com/samples/rails/)の記述をバージョンだけ変えて記載しています。

公式でのコマンドの説明は[このぐらいしか記載が見つけられなかった](https://docs.docker.jp/compose/overview.html#compose)ので、各コマンドの説明は[先のあげたこちらの記事](https://qiita.com/kodai_0122/items/795438d738386c2c1966)から拝借しました。

```yaml:docker-compose.yml
version: "3.9"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: password
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
```

>**[version]** docker-composeのバージョンです。2019年10月現在、最新は'3'です。
**[services] **この下のハッシュにサービスを作りましょう。命名は自由ですが、通常はwebとdbと名付けます。
**[image]** 使用するimage（dbでPostgreSQLを指定しています）
**[volumes]** ディレクトリのマウント設定（dbデータなどを残せます）
**[build]** Dockerfileなどがあるパス（基本的にカレントディレクトリ）
**[command]** コマンド（server.pidファイルを削除してからrailsサーバー起動)
**[ports]** ポート番号。[ホスト：コンテナ]で設定。
**[depends_on]**　依存関係を示していて、起動順を指定できます。ここではdb→webへと起動します。

引用元：[DockerでRuby on Railsの環境構築を行うためのステップ【Rails 6対応】](https://qiita.com/kodai_0122/items/795438d738386c2c1966)

## Rails newする
そして、[公式ガイド](https://docs.docker.com/samples/rails/)に書いてあった通り、以下のコマンドで`Rails new`します。

```sh
$ docker-compose run --no-deps web rails new . --force --database=postgresql
```
`--no-deps` の部分は、リンクされたサービス（ここでは`web`）を開始しないようにComposeに指示している部分だそうです。こうすることでコンテナ内に新しいアプリを作れるのだそう。

上記を実行すると、こんなメッセージが出て立ち上げが終了します。

```sh
... # インストールされた諸々の gemの情報
Installing sass-rails 6.0.0
Bundle complete! 17 Gemfile dependencies, 73 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
       run  bundle binstubs bundler
       rails  webpacker:install
Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/
Exiting!
```

公式ガイドの説明は`Rails 5`の前提なので、`webpacker`周りの設定をする必要がありそうですね。

## もう一度イメージをbuildしてbundle installする
なお、公式ガイドには「これにて新しいGemfileが作成されているので、イメージをもう一度立ち上げて`bundle install`しましょう」的な記述があったので、コンソールで下記コマンドを実行します。

```sh
$ docker-compose build
```

`/test`など不要なディレクトリやファイルが含まれていないのを確認して、ここで一度コミットしておきます。

## DBとの接続設定をする
先に出ていた「Rails6関連の記載」も気になりますが、先にDBとの接続設定をやってしまいます。
Railsはデフォルトで`localhost`のDBを参照するようになっているので、`db`のイメージを作成するように書き換えます。

```yaml:confog.database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password
  pool: 5

development:
  <<: *default
  database: myapp_development


test:
  <<: *default
  database: myapp_test
```

こちらは公式の記述から何もいじっていません。
このまま、一回 `docker-compose down`して`docker-compose up`すると、（無事、DBへの接続を完了した上で）今度はこんなエラーが。

```sh
`rescue in load': Webpacker configuration file not found /myapp/config/webpacker.yml. Please run rails webpacker:install Error: No such file or directory @ rb_sysopen - /myapp/config/webpacker.yml
```
今度こそ`webpacker:install`をする必要がありそうです。

## Webpackerを導入する
調べたところ、Doker上でWebpackerをインストール＆立ち上げるには

- コンテナ内への`yarn`のインストール（Dockerfileに記載）
- コンテナ内で、`rails webpacker:install`

の２点が必要なようです。まずは前者から。

## yarnのimageへのインストール

`Dockerfile`にyarnをインストールするコマンドを追記します。追記箇所以外の記述の意味は[前回記事](https://qiita.com/tanutanu/items/808850ed7e4e8461b24b)をご参照ください。

- [RailsでDockerfile設定しながら、コマンド一つひとつ丁寧に読んでみた](https://qiita.com/tanutanu/items/808850ed7e4e8461b24b)

```dockerfile
FROM ruby:3.0.2
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

# ここを追記
RUN set -x && curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
  echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list

RUN set -x && apt-get update -qq && \
  apt-get install -yq build-essential yarn

WORKDIR /myapp

COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install

# Add a script to be executed every time the container starts.
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

# Configure the main process to run when running the image
CMD ["rails", "server", "-b", "0.0.0.0"]

```

記載は[下記の記事](https://zenn.dev/junki555/articles/7a7892c305358d65bede)を参考にしましたが、重複しているコマンドもあるので、もっと簡潔に書けそうです。。。
とりあえず今は時間がないので、これで我慢します。

- [Ruby:2.6 のdockerコンテナでrails6.0を入れようとしたらyarnがコケた](https://zenn.dev/junki555/articles/7a7892c305358d65bede)

## Webpackerをインストール
コンテナ内にWebpackerは下記のコマンドでインストールしました。
まず `docker-compose build`でコンテナを立ち上げたのちに、

```sh
docker compose run web bundle exec rails webpacker:install
```
上記のコマンドで、コンテナ内にWebpackerをインストールできます。

## rails db:create → アプリの立ち上げ

同じ要領で

```sh
docker compose run web rails db:create
```
したのちに、`localhost:3000`にアクセスすると...

[![Image from Gyazo](https://i.gyazo.com/feedbd6ffe64f2ee36ff465347b4137b.png)](https://gyazo.com/feedbd6ffe64f2ee36ff465347b4137b)

はい、無事Railsの初期画面が立ち上がりました！！:relaxed:

## 感想など

これからCIの設定やJSのライブラリの設定、ChromeDriverの設定などやっていくことを考えると、まだまだ先が長いですが、とりあえず一段落で嬉しいです:relaxed:

最近読んだ本にプロジェクトの初期設定は専門職がいるくらい大変な仕事、と書いてあったのですが、ホント、先が長いですね。。。

引き続きJS系ツールやテストツールの設定など書いて行けたらと思います。

【シリーズの他の読み物】
前の話
- [RailsでDockerfile設定しながら、コマンド一つひとつ丁寧に読んでみた](https://qiita.com/tanutanu/items/808850ed7e4e8461b24b)