既存のRails6プロジェクトをDockerに乗せるハンズオン

# はじめに
作成済みのRails6プロジェクトをDocker上で動作させる手順のハンズオンです。
※DBを使用しないプロジェクトとなっています。

# 環境
macOS Catalina 10.15
Ruby 2.6.5p114
Rails 6.0.1
Docker for mac 19.03.2

# 流れ
1. 適当な名前で`rails new プロジェクト名 -O`する（-O：DBなしで作成する）
2. `rails s`で起動できるか確認する（local環境にyarnがインストールされている必要があります）
3. 確認用のページを作る(見出しだけのhtml.erbとか)
4. Dockerに必要なファイルの作成（今回はDBを使用しないver）
5. Dockerで起動

# Railsプロジェクトを作成
今回は"qiita_test"というプロジェクト名で進めます

```
$ rails new qiita_test -O
```
作成したら、とりあえず`rails s`で起動確認しましょう。

# 確認用ページ作成
次に、確認用ページを作成します。なぜ確認用ページが必要かというと、私がDocker上でウェルカムページの表示には成功したものの、自分で作成したページの表示にかなり苦労したからです。

```
# コマンド一発で、必要なものを揃えましょう
# rails generate controller [コントローラ名] [アクション名]
$ rails generate controller home test
```
そしたらすかさず`rails s`で起動して、[http://localhost:3000/home/test](http://localhost:3000/home/test)を確認しましょう。
Home#testとか表示されてればokです。

# Dockerに必要なファイルを揃える
以下のファイルが必要なファイルとなります。railsプロジェクトのルートディレクトリに作成しましょう。
- Dockerfile
- docker-compose.yml

## Dockerfile
Dockerfileとは、Dockerのimageを作るために必要なファイルです。
ファイル名は一般的にDockerfileとなっていますが、別の名前でも構いません。
書き方としては、FROMでimageの指定、RUNでOSコマンドの実行、ADDでコンテナへのファイル配置、CMDでコンテナ起動時に実行するコマンドの定義となっています。

```Dockerfile:Dockerfile
# Rubyのバージョン
FROM ruby:2.6.5

# curl -sS でエラー以外の出力の抑制
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

# yarn node.jsのインストール(apt-get -yでyes/noを聞かれないようにする必要がある)
RUN apt-get update && \
apt-get install -y yarn nodejs --no-install-recommends && \
rm -rf /var/lib/apt/lists/*

# プロジェクトのディレクトリをコンテナに作成
RUN mkdir /qiita_test

# 作業ディレクトリに↑で作成したディレクトリを指定
WORKDIR /qiita_test

# Gemfileを作業ディレクトリにコピー
ADD Gemfile /qiita_test/Gemfile
ADD Gemfile.lock /qiita_test/Gemfile.lock

# gemのインストール
RUN gem install bundler
RUN bundle install

# プロジェクト本体をコンテナにコピー
ADD . /qiita_test

# コンテナ起動時にRailsサーバーが起動するようにする
CMD ["rails", "server", "-b", "0.0.0.0"]

```

## docker-compose.yml
docker-compose.ymlはDockerのimageをビルドしたり、コンテナを起動するための情報を記述するファイルです。
環境変数の指定で、Railsの実行モードの指定もします。(development, test, productionの3つから指定)

```docker:docker-compose.yml
# docker-composeのバージョン
version: '3'

# コンテナの情報
services:
  # コンテナ名(webが一般的？)
  web:
    # Dockerfileを元にbuildする
    build:
      # Dockerfileの配置ディレクトリ
      context: .
      # imageのビルドに用いるDockerfileの指定
      dockerfile: Dockerfile

    # 環境変数の設定
    # RAILS_ENVにdevelopmentを指定で、実行モードを開発モードに
    environment:
      RAILS_ENV: development

    # コンテナ起動時に実行するコマンド
    # pid情報の削除とRailsサーバー起動
    command: /bin/sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"

    # 既存のRailsプロジェクトをマウントする
    volumes:
      - .:/qiita_test
    # コンテナの3000ポートとlocalhostの3000ポートをマッピング
    ports:
      - "3000:3000"

```

# Dockerで起動
コンテナを起動すると同時にRailsサーバーも立ち上がる想定です。
プロジェクトのルートディレクトリに移動し、以下のコマンドでコンテナを起動

```console
# ビルド(初回や、Dockerファイル、docker-compose.ymlに変更があった場合などに実施)
$ docker-compose build

# コンテナの作成、起動
$ docker-compose up
```
upすると、前回の記事でも紹介した例のアレのせいで、コンテナが止まります。
コンテナ上でコマンドを実行するには、以下のコマンドです。
※Dockerfileにこのプロセスを記載したかったのですが無理でした、、方法を知っている方がいらっしゃいましたらご教示ください。

```console
# docker-compose run [docker-composeで決めたコンテナ名] [実行したいコマンド]
$ docker-compose run web yarn install --check-files
```
再び`docker-compose up`でコンテナを作成、起動します。
そしたら、冒頭でテスト用に作成したページ([http://localhost:3000/home/test](http://localhost:3000/home/test))にアクセスして、特にhtml.erbをいじっていない場合は以下のページが表示されることを確認します。コンテナの停止はCtrl+Cです。
<img width="514" alt="スクリーンショット 2019-12-07 22.45.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414958/ded3fdee-e843-dd6c-accd-bae3616ece70.png"　width=50%>
今後は、`docker-compose build`をしないのであれば、`docker ps -a`で対象のコンテナIDを確認して、`docker-compose start [コンテナID]`でコンテナの起動(railsの起動)ができます。止める場合は`docker-compose stop [コンテナID]`です。バックグラウンドでサーバーを起動しているので、コンテナを起動して少し時間をおいてからページにアクセスしましょう。

以上になります。お疲れ様でした。

# 参考にさせていただいたサイト
docker-compose公式リファレンス
[https://docs.docker.com/compose/compose-file](https://docs.docker.com/compose/compose-file)