既存のRailsアプリにDockerfileを追加し、Railsの環境を新たに作る方法【Rails Postgres Docker】

#既存のRailsアプリにDockerfileを追加し、Railsの環境を新たに作る方法【Rails Postgres Docker】
## 検証済み環境
- ruby-2.6.3
- Rails 5.2.6
- macOS Catalina Version 10.15.7

## 前置き
先日Railsのアプリを開いて検証する必要があったため、Dockerを用いて、環境構築を行いました。
途中何回か詰まってしまったので、未来の自分が見返せるように手順をまとめておきます。

## 前提
- お使いのPCにDockerが導入されていること。
- Docker何となく触ってみないなという気持ちがあること
- Railsの勉強を始めて、最低1週間くらい経過していること
- Linuxコマンドを最低1週間くらい触ったことがあること

※Dockerがよくわからなくても大丈夫です。

## 早速トライ！
### 準備1
Desktop上に、適当なフォルダを作成しましょう。フォルダ名はなんでも大丈夫です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538308/12c9f510-a9b8-3918-219f-8cec95cb6e07.png)
今回はわかりやすく、"rails-docker"というフォルダを作成しました。

次に、"rails-docker"フォルダに開きたいRailsアプリのフォルダを設置します。

### 準備2
Railsアプリのフォルダの中に二つのファイルを追加します。ファイル名はなんでも良くないです。
下の二つと同じ名前のファイルを作成してください。Dockerfileに拡張子はないです。
- docker-compose.yml
- Dockerfile
![dockerrails1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538308/5aad8507-5c99-cf41-7c62-bc72977f21fe.png)


### Dockerfileの中身
※[アプリの名前]という部分には、開きたいRailsアプリの名前を入れましょう。[]はとってね。
※rubyのバージョンは、開きたいRailsアプリで使われているバージョンを指定してあげてください。Gemfileに書いてありますよ。今回は2.6.3で説明してますが、自身のバージョンに合わせて適宜編集をしてください。

``` Dockerfile
FROM ruby:2.6.3
RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y postgresql-client --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

WORKDIR /[アプリの名前]

ADD Gemfile /[アプリの名前]/Gemfile
ADD Gemfile.lock /[アプリの名前]/Gemfile.lock

RUN gem install bundler
RUN bundle install

ADD . /[アプリの名前]
```

### docker-compose.ymlの中身
※今回データベースはPostgresを使用します。
※portの番号（5432, 3003）は自分で適当に決めてもらっても構いません。なんでもいいです。

```docker-compose.yml
version: '3'
services:
  db:
    image: postgres
    environment:
      - POSTGRES_HOST_AUTH_METHOD=trust
    ports:
      - '5432:5432'
    volumes:
      - ./tmp/db:/var/lib/postgresql/data
  web:
    build:
      context: .
      dockerfile: Dockerfile
    command: bundle exec rails s -p 3003 -b '0.0.0.0'
    tty: true
    stdin_open: true
    depends_on:
      - db
    ports:
      - "3003:3003"
    volumes:
      - .:/[アプリの名前]
volumes:
  postgresql-data:
    driver: local
```

※web(Rails)とdb(Postgres)の二つのコンテナを起動させてるんだ、ということが簡単にわかればOKです。
※volumesというのは、コンテナ上のフォルダやファイルとローカル上（自分のPC）のフォルダとファイルを同期させるための記述です。

ここで、docker-compose.ymlファイルの存在理由について簡単に説明します。
Dockerを用いて、コマンドライン上で操作する時にdocker-composeを使わないと、非常に長いコマンドを実行しなくてはいけません。
コマンド文の内容をファイル化したものがdocker-compose.ymlです。

### database.ymlの編集
Postgresを使用するため、デフォルトの内容からは修正が必要です。
database.ymlはRailsアプリフォルダのconfigフォルダの配下にあるはずです。

```database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: [アプリの名前]_development

test:
  <<: *default
  database: [アプリの名前]_test

```

### Gemfileの編集
※Postgresを使用するため、pgジェムを入れること

```Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.3'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.6'
gem 'pg'
gem 'puma', '~> 3.11'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'


gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'pry-byebug'
gem 'bootsnap', '>= 1.1.0', require: false

group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

```

#### 以上で準備完了です。
## ターミナルで操作をしていきましょう。
まずは、ターミナルで先ほど作成したフォルダ[rails-docker]の下の[アプリ名]フォルダに移動します。
次に、

```
$ docker-compose build
```
を実行します。

```実行結果.text
$ docker-compose build                                                                                                               ✔  1m 19s  ruby-2.6.3 
db uses an image, skipping
Building web
Step 1/10 : FROM ruby:2.6.3
 ---> 8fe6e1f7b421
Step 2/10 : RUN apt-get update && apt-get install -y nodejs --no-install-recommends && rm -rf /var/lib/apt/lists/*
 ---> Using cache
 ---> d5077b1e3d4a
Step 3/10 : RUN apt-get update && apt-get install -y postgresql-client --no-install-recommends && rm -rf /var/lib/apt/lists/*
 ---> Using cache
 ---> ea103045a2c

〜〜
以降、step10まで続く、、bundle installがされてSuccessfullyと表示されれば大丈夫です！
```

次に、

```
$ docker-compose run web rails db:create db:migrate
```
を行います。
rails db:createで、データベースの作成が行われます。
rails db:migrateでマイグレーションが行われます。

**が、しかしここでうまくいかなかった場合は、以下を試してください。**

```
$ docker-compose run web bundle exec rails db:create db:migrate
```

```実行結果.text
Creating [アプリ名]_web_run ... done
== 2021120XXXXXX1 Create[テーブル名]: migrating ======================================
-- create_table(:[テーブル名])
   -> 0.0585s
== 2021120XXXX11 Create[テーブル名]: migrated (0.0587s) =============================
```
こんな感じで、マイグレーションまで無事に行われれば、成功です。

失敗する場合は、エラー文をコピペしてぐぐって見ましょう。
ちなみに私はここで失敗しました。こんな感じのエラーが出ましたね。

```
PG::ConnectionBad: could not translate host name "db" to address: Name or service not known
```
とか

```
Couldn't create '_development' database. Please check your configuration.
```

とか。
まあ、この手のエラーは「データベースがうまく作れませんでした」、という意味なので、
docker-compose.ymlもしくは、database.ymlにどこかミスがないかを確認してみましょう。
できなければ、きちんとエラー文をググりましょう。1時間くらい調べればなんとかなるはずです。それ以上やってダメでしたら、最初からやり直してみましょう。プログラミング学習には根気の良さが必要です。

ここまでくれば、いよいよrailsのアプリが実行できます。

```
$ docker-compose up
```
で実行してみましょう。

```実行結果.text
Starting [アプリの名前]_db_1 ... done
Starting [アプリの名前]_web_1 ... done
Attaching to [アプリの名前]_db_1, [アプリの名前]_web_1
db_1   |
（省略）
db_1   | 2021-XX-XX XXXXX UTC [1] LOG:  database system is ready to accept connections
web_1  | => Booting Puma
web_1  | => Rails 5.2.6 application starting in development
web_1  | => Run `rails server -h` for more startup options
web_1  | Puma starting in single mode...
web_1  | * Version 3.12.6 (ruby 2.6.3-p62), codename: Llamas in Pajamas
web_1  | * Min threads: 5, max threads: 5
web_1  | * Environment: development
web_1  | * Listening on tcp://0.0.0.0:3003
web_1  | Use Ctrl-C to stop
```
こんな感じに出力されれば、成功です！
ブラウザで localhost:3003 をみてみましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538308/2ba5dbfc-0bad-3f98-d70d-5ee67a84b8e1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538308/55a8ed28-0a4b-c231-431d-80bba4195a77.png)

以上です！