dockerでrails6の開発環境構築と躓きポイント

# 概要

「Quickstart: Compose and Rails」
https://docs.docker.com/compose/rails/

「もう環境構築で悩まない！Dockerを使ってRails環境構築！」
https://www.youtube.com/watch?v=BZS8AHF3TTo

「DockerでのRuby on Rails環境構築を一つずつ詳解する」
https://qiita.com/daichi41/items/dfea6195cbb7b24f3419

この記事をもとに

* ruby
* rails
* postgres

を設定していきます。

# 全体図

* プロジェクトのフォルダを作り、下記fileを作成
    * Dockerfile
    * Gemfile
    * Gemfile.lock
    * entrypoint.sh
    * docker-compose.yml
* dockerfileにてwebサーバーとdbをそれぞれコンテナビルド
* rails読み込む用のgemfile、gemfilerockを作成。これをもとに作業ディレクトリにrailsnewされる。
* `$ docker-compose run web rails new . --force --no-deps --database=postgresql --skip-bundle`
* `docker-compose build`
* `docker-compose up`で起動
* `docker-compose run web rake db:create`でdb作成

# 環境

- m2 macbookair
- rails6
- ruby2.6.6

# 手順

## 各file設置

### Gemfile

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

versionは適宜変更。今回はrails6で対応。

### Gemfile.lock

Gemfile.lockは空。Gemfileからビルド時に反映される。

### entrypoint.sh

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

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

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

### docker-compose.yml

```docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./docker/pg:/var/lib/postgresql
    ports:
      - '5432:5432'
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_USER: localhost
      POSTGRES_DB: test_db
  web:
    stdin_open: true
    tty: true
    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
```

### Dockerfile

```Dockerfile
FROM ruby:2.6

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list

RUN apt-get update -qq && apt-get install -y nodejs postgresql-client yarn
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# 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

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]
```

```
apt-get update -qq && apt-get install -y nodejs postgresql-client yarn
```

がm1,m2だとエラーが出る

https://qiita.com/hamuki72718/items/328b09308f73f5ace397

こちらの記事をもとに

```
RUN wget --quiet -O - /tmp/pubkey.gpg https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
```

に変更

### rails new

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

### bundle install

```
docker-compose build
```

上記コマンドでビルドし、bundle installを行う。これでrailsの読み込みもされる。

### db:create

```
$ docker-compose run web rake db:create
```

### db:migrate

```
$ docker-compose run web rake db:migrate
```

# つまづきポイント

## could not translate host name "db" to address: Name or service not

dbのpassがうまく渡せていなかった？

```docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./docker/pg:/var/lib/postgresql
    ports:
      - '5432:5432'
    environment:
      POSTGRES_PASSWORD: password
      POSTGRES_USER: localhost
      POSTGRES_DB: test_db
  web:
    stdin_open: true
    tty: true
    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
```

にしてdatabase.ymlを下記に

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

development:
  <<: *default
  database: myapp_development

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

## Webpacker::Manifest::MissingEntryError

docker-compose upで立ち上げた際に

```
Webpacker::Manifest::MissingEntryError
```

とエラーが。

https://zenn.dev/kantafukazawa/articles/8697bc02c23829

webpackがinstallされていないことが原因で上記の記事のようにdockerでwebpackをinstallするか、つど、docker-compose run webでdocker内部でinstallするかがある。今回はdocker内でinstallするのを採用

```
docker-compose run web rails webpacker:install
```

で

```
Overwrite /myapp/config/webpacker.yml? (enter "h" for help) [Ynaqdhm]
Overwrite /myapp/babel.config.js? (enter "h" for help) [Ynaqdhm] y
```

上書きするかと質問がくる。これは最新のwebpackにするためにy。


あとはdocker-compose up


# 運用面

## railsコマンドの打ち方

```
docker-compose run web rails ~
```

でrailsコマンドを打てる。

## gemfileのinstall

```
docker-compose run web bundle install
```

gemの永続化を行っていない状態だと上記をしてもgemがないと言われてしまうので都度buildする必要がある。下記の手順で永続化すると毎回buildしなくてもすむ。

参考記事
https://nishinatoshiharu.com/datavolume-for-gem/