Docker＆Rails６の環境を構築してみる。

# 本記事について（お断り）

この記事は、しがないプログラミング初心者がお勉強よろしくプログラミング・技術に触れるべく、行ったことの備忘録として書き綴ったものです。ご了承ください。
ご指摘は甘んじて受け入れます🙇‍♂️

# 目的

ここではひとまず自分で必要なファイルの準備から、Railsのアプリケーションを起動できるまでを目指します。

# 参考

今回の作業は下記の記事を参考にさせていただいてます。とても勉強になりました。ありがとうございます。
[Quickstart: Compose and Rails | Docker Documentation](https://docs.docker.com/compose/rails/)
[https://qiita.com/kodai_0122/items/795438d738386c2c1966#2-2-bundle-install](https://qiita.com/kodai_0122/items/795438d738386c2c1966#2-2-bundle-install)
[https://qiita.com/at-946/items/2fb75cec5355fad4050d](https://qiita.com/at-946/items/2fb75cec5355fad4050d)



# 環境構築手順

#1.準備

**1-1フォルダの作成**

まずは作業を行うためのフォルダを任意に作成します。
作成したフォルダに移動しておきます。

```
$ mkdir myapp
$ cd my app
```

**1-2Dockerfileの作成**

フォルダ内にDockerfileを作成します。
公式ページ内：[クイックスタート](https://docs.docker.com/compose/rails/)を参考にバージョンだけ変えて作成しました。

```Docker:Dockerfile
FROM ruby:2.6.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
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"]
```

**1−3Gemfileの作成**

ここではインストールするRailsのバージョンを６に指定します。あわせてGemfile.lockも作成しておきます。中身は何も書かなくてOKです。

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

```
$ touch Gemfile.lock
```

**1-4entrypoint.shの作成**

コンテナが起動した時に、Railsのserver.pidを毎回削除してくれる様です。（英語得意ではないので書いてあること違ってたらすいません）よくこのファイルが残っててコンテナの中身を消しにいくの大変だった思い出。

```bash: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 "$@"
```

**1-5docker-compose.ymlの作成**

docker-compose.ymlは、魔法の様なファイルです。必要なアプリ（web、dbアプリ）を構成するサービスやそのイメージをまとめて実行してくれます。（~~英語得意ではないn~~自分がこのファイルを使ってみての感覚で話してるとこもあるので、誤解を招く様な表現があったらすみません）

```yaml:docker-compose.yml
version: '3'
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
```

ここでは、DB（PostgreSQL）、webの二つを実行してもらう様記載します。

ここまでできたら、ファイルの準備は完了です。

# 2.プロジェクトのビルド

**2-1rails new**

`docker-compose run` コマンドを使って、`rails new`していきます。

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

これで、myappフォルダの中に見慣れたフォルダ構成ができてきます。
ターミナルの最後で、以下の様にメッセージを出してきます。

```bash:
Could not find gem 'pg (>= 0.18, < 2.0)' in any of the gem sources listed in your Gemfile.
Run `bundle install` to install missing gems.
```

`bundle install`してねというメッセージでした。

**2-2bundle install**

Dockerfileで`bundle install`する様記述してあるため、イメージをビルドする際に勝手にやってくれます。

```bash:
$ docker-compose build
```

**2-3DB接続設定**

Railsのconfg/database.ymlを、以下に書き換えます。

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

development:
  <<: *default
  database: myapp_development


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

**2-4Dockerコンテナ起動**

```bash:
$ docker-compose up
```

するとなんだか色々エラーだと言われました。

```bash:
db_1   | Error: Database is uninitialized and superuser password is not specified.
.
.
.
web_1  | /usr/local/bundle/gems/webpacker-4.2.2/lib/webpacker/configuration.rb:95:in `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 (RuntimeError)
```

上のエラーは、PostgreSQLのパスワードが必要なために出てきたメッセージです。`confg/database.yml`に追記しておきます。

```yml:config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password: password  # <= この部分
  pool: 5

```

もう一つのエラーは、Rails6からWebpackerがデフォルトで導入されるため、Webpackerのインストールを求めるものでした。
で、そのWebpackerのインストールにはyarnやNode.jsのインストールが必要だそうです。

それらに対応するため、Dockerfileを編集する必要があります。

```docker:Dockerfile
FROM ruby:2.6.5
RUN apt-get update -qq && apt-get install -y nodejs postgresql-client
# yarnインストール
RUN apt-get update && apt-get install -y curl apt-transport-https wget
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 && apt-get install -y yarn
# Node.jsインストール
RUN curl -sL https://deb.nodesource.com/setup_7.x | bash - && \
  apt-get install nodejs
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"]
```

それではWebpackerをインストールしてみます。

```bash:
$ docker-compose stop
$ docker-compose down
$ docker-compose run web bundle exec rails webpacker:install
.
.
Webpacker successfully installed 🎉 🍰
```

無事Webpackerのインストールに成功しました。
もう一度、コンテナを起動します。

```bash:
$ docker-compose up
```

**2-5DB作成**

DBを作成します。これで完了です。

```bash:
$ docker-compose run web rails db:create
Starting myapp_db_1 ... done
Created database 'myapp_development'
Created database 'myapp_test'

```

**2−6アクセスしてみる**
ブラウザで[http://localhost:3000/](http://localhost:3000/)にアクセスしてみます。お馴染みの画面が出迎えてくれ無事成功しました！

<img width="400" alt="Rails6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563494/495dc756-eede-ba53-bc5b-1c77ad0e88a0.png">
Yay!



# まとめ
DockerでRails６の環境を作成してみました。
実際やってる時は、作業フォルダの名前とDockerfileに指定しているフォルダ名が違ったりして、色々と他にも手こずってました。他の方の一助になれば幸いです。