Dockerを使ってrails6の環境を構築する

## はじめに
Dockerを使ってRailsの環境を構築しようと思います。

## 前提
`ruby 3.0.6`
`rails 6.1.0`
`node 14.x`

### Rails new
最初にrubyの環境を整えてからrailsをインストールします。

```dockerfile:Dockerfie
FROM ruby:3.0.6

RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

WORKDIR /myapp
```

```yml:docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build: .
    command: bash
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    depends_on:
      - db
```

このファイルが作成できたら以下のコマンドを実行してコンテナの中に入ります。

```terminal
docker-compose exec web
```

コンテナの中に入った状態でrailsをインストールします。

```terminal:コンテナ
gem install -v 6.1.0 rails
```

ここではバージョンに6.1.0を指定してインストールしています。
インストールできたらバージョンに6.1.0を指定してrailsアプリケーションを作成しましょう。

```terminal:コンテナ
rails _6.1.0_  new . --database=postgresql
```

上のコマンドを実行したら以下のようなエラーメッセージが表示されるかもしれませんが、後で対応します。

```terminal
Yarn not installed. Please download and install Yarn from https://yarnpkg.com/lang/en/docs/install/
```

railsアプリケーションも作成できたので`Dockerfile`と`docker-compose.yml`を更新します。

```Dockerfile:Dockerfile
FROM ruby:3.0.6

RUN apt-get update -qq && apt-get install -y nodejs postgresql-client

WORKDIR /myapp

COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock

RUN bundle install

EXPOSE 3000

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

```yml:docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  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
```

### フロントエンド
先ほど発生していたyarnがインストールされていないという課題に対応します。
またrails6ではnodeのバージョンが新すぎるとうまく動かないため、バージョンは14系をインストールするようにしてます。

```dockerfile:Dockerfile
FROM ruby:3.0.6

RUN apt-get update -qq && apt-get install -y curl postgresql-client

RUN curl -sL https://deb.nodesource.com/setup_14.x | bash - \
    && apt-get install -y nodejs \
    && 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 \
    && apt-get update && apt-get install -y yarn

WORKDIR /myapp

COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock

RUN bundle install

EXPOSE 3000

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

`Dockerfile`を更新したらビルドしてコンテナにyarnを追加しましょう。

```terminal
docker-compose build
```

yarnの追加ができたらrailsにwebpackerを追加してあげます。

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

### DB
次はDB周りの設定です。
database.ymlとdocker-compose.ymlでパスワードを設定してあげます。

```yml:config/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

production:
  <<: *default
  database: myapp_production
  username: postgres
  password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>
```

```yml:docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: password
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  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
```

コンテナをビルドしてあげたらrailsのDBを作成できます。

```terminal
docker-compose run web rails db:create
```

### 微調整
以降は私の環境だけかもしれないのですが、webpackerを使ってコンパイルしようとするとエラーが発生したため対応しようと思います。

最初に発生したエラーはこちらです。

```terminal
Error: Cannot find package '@babel/plugin-proposal-private-methods' imported from /myapp/babel-virtual-resolve-base.js
```
エラーメッセージ通り足りないパッケージをインストールしてあげましょう。
```terminal
docker-compose run web yarn add @babel/plugin-proposal-private-methods
```

次に発生したエラーはこちらです。

```terminal
Error: [BABEL]: --- PLACEHOLDER PACKAGE ---
This @babel/plugin-proposal-private-property-in-object version is not meant to
be imported. Something is importing
@babel/plugin-proposal-private-property-in-object without declaring it in its
dependencies (or devDependencies) in the package.json file.
Add "@babel/plugin-proposal-private-property-in-object" to your devDependencies
to work around this error. This will make this message go away
```

これについてもエラーメッセージ通り開発環境にパッケージをインストールしてあげます。

```terminal
docker-compose run web yarn --dev add @babel/plugin-proposal-private-property-in-object
```

私の環境では以上二つの対応をすることでwebpackerに関するエラーも消えました。
コンテナを立ち上げることでrailsの画面を確認できました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551042/99435709-7a67-dd35-5922-548523897316.png" width="600" />