既存のRailsアプリにDockerを導入する

# 1.はじめに
開発途中のアプリにDockerを導入したので記事として残します。

# 2.環境
ruby: 2.6.4
Rails: 6.1.7
DB: postgresSQL

# 3.導入手順 
### 事前準備
Dockerのインストール
以下の記事を参考にさせていただきました。
[DockerをMacにインストールする](https://qiita.com/kurkuru/items/127fa99ef5b2f0288b81)

インストールできたら以下コマンドを実行して確認してみてください
```
$ docker -v
$ docker-compose -v
```
バージョンが表示されていたらOKです

### 1.既存アプリ直下にdockerfileを作成
```
touch dockerfile
```

ファイル内に以下を追加します。
```diff_ruby:dockerfile
FROM ruby:2.6.4 #①
RUN apt-get update -qq&& apt-get install -y build-essential libpq-dev nodejs #②
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 \
    && apt-get update && apt-get install -y yarn
RUN mkdir /アプリ名 #④
WORKDIR /アプリ名 #⑤
ADD Gemfile /アプリ名/Gemfile #⑥
ADD Gemfile.lock /アプリ名/Gemfile.lock #⑦
ENV BUNDLER_VERSION=2.0.2 #⑧
RUN gem install bundler -v "$BUNDLER_VERSION" && bundle install #⑨
ADD . /アプリ名 #⑩
```

①ベースイメージとしてRubyの特定のバージョンを使用します。

②システムパッケージを更新し、必要なパッケージをインストールします。
- build-essentialはビルドに必要なツールを含み、libpq-devはPostgreSQL用の開発ヘッダをインストールします。
- nodejsはJavaScriptランタイムです。

③Yarnの公式GPGキーを取得し、APTリポジトリに追加します。これによりYarnをインストールできるようになります。

④作業ディレクトリとして使用するディレクトリを作成します。

⑤以降の命令で使用する作業ディレクトリを設定します。

⑥⑦GemfileとGemfile.lockをコピーします。

⑧Bundlerの特定のバージョンを環境変数として設定します。

⑨特定のバージョンのBundlerをインストールし、Gemfileに基づいて依存関係を解決します。

⑩残りのアプリケーションコードをコピーします。

### 2.既存アプリ直下にdocker-compose.ymlを作成
```
touch docker-compose.yml
```
ファイル内に以下を追加します。

```diff_ruby:docker-compose.yml
version: '3' #①
services:
  db:
    image: postgres #②
    environment: #③
      POSTGRES_USER: username
      POSTGRES_PASSWORD: password
  web:
    build: . #④
    command: bundle exec rails s -p 3000 -b '0.0.0.0' #⑤
    stdin_open: true #⑥
    tty: true
    volumes:
      - .:/アプリ名 #⑦
    ports:
      - "3000:3000" #⑧
    depends_on: #⑨
      - db
```
①Docker Composeファイルのバージョン指定です
 
②PostgreSQLの公式Dockerイメージを使用しています。
- これにより、PostgreSQLサーバーがコンテナ内で実行されます。

③Dockerのコンテナ内で使用される環境変数を設定します。
- Dockerコンテナはホストマシンの環境と完全に分離されて動作するため、コンテナ内部で環境変数を設定する必要があります。

④カレントディレクトリにあるDockerfileを使用してイメージをビルドします。
- Railsアプリケーションのコンテナイメージを作成します。

⑤Railsアプリケーションを起動するためのコマンドです。
- bundle exec rails sはRailsでサーバーを起動。
- -p 3000はポート番号を3000に設定しています。
- -b '0.0.0.0'はすべてのホストからの接続を受け入れるように指定しています。

⑥stdin_openとは標準入出力とエラー出力をコンテナに結びつける設定です。
- ttyとは、擬似端末(キーボードによる入力)をコンテナに結びつける設定です。

⑦ローカルの現在のディレクトリをコンテナ内の /One_Trip にマウントします。
- これにより、コードの変更が反映されます。

⑧ホストの3000番ポートとコンテナの3000番ポートをマッピングします。
- これにより、ホストマシンからRailsアプリケーションにアクセスできます。

⑨webサービスはdbサービスが起動した後に起動するように依存関係が設定されています。

### 3.config/database.ymlの書き換え
```diff_ruby::database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  host: db #追記
  username: 〇〇
  password: 〇〇
  pool: 5

development:
  <<: *default
  database: docker-rails-pg-sample_development
```
developmentがdocker-composeで起動したイメージdbを使うように設定を記述。

### 4.buildする
```
docker-compose build
```

### 5.データベースを作成・マイグレーション

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

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

# 6.コンテナ起動
```
docker compose up
```
`http://localhost:3000/`で接続できていれば成功です！

# 7.Docker導入までに発生したエラー
## 1.BUNDLERのバージョンがないと怒られた
```
 > [7/8] RUN bundle install:                                                                                                                                                                                    
#11 0.429 /usr/local/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': Could not find 'bundler' (2.0.2) required by your /アプリ名/Gemfile.lock. (Gem::GemNotFoundException)                               
#11 0.429 To update to the latest version installed on your system, run `bundle update --bundler`.
#11 0.429 To install the missing version, run `gem install bundler:2.0.2`
#11 0.433 	from /usr/local/lib/ruby/2.6.0/rubygems.rb:302:in `activate_bin_path'
#11 0.433 	from /usr/local/bin/bundle:23:in `<main>'
```
どうやら、BUNDLER2.0.2のバージョンがないよと言われていたので、バージョンの指定をするため以下を追記・変更で解決しました。
```diff_ruby:dockerfile
FROM ruby:2.6.4
RUN apt-get update -qq&& apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /アプリ名
WORKDIR /アプリ名
ADD Gemfile /アプリ名/Gemfile
ADD Gemfile.lock /アプリ名/Gemfile.lock
+ ENV BUNDLER_VERSION=2.0.2
- RUN bundle install
+ RUN gem install bundler -v "$BUNDLER_VERSION" && bundle install
ADD . /アプリ名
```

## 2.コンテナが起動できないエラー(A server is already running.)
下記記事を御覧ください
[A server is already running. Check /アプリ名/tmp/pids/server.pid.](https://qiita.com/uuuDi_97722/items/23446f32035b6740b459)