Windows 10 HomeでRails6 on Dockerの環境構築[PostgreSQL]

#はじめに
Windows10 Homeでrails6のDockerの環境構築に3日間程沼に嵌っていたので、備忘録も含め書いていこうと思います。Macでは上手くいくけどWindowsでは上手くいかない部分が多々あったのでそれについて纏めています。


#環境構築手順
##1.必要なファイル・フォルダの作成

作業フォルダ内に以下のファイルを作成
**・Dockerfile
・Gemfile
・Gemfile.lock（空のファイル）
・entrypoint.sh
・docker-compose.yml**


###1-1.Dockerfile
```Dockerfile:Dockerfile
FROM ruby:2.6.6

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 -qq && apt-get install -y nodejs postgresql-client yarn
RUN mkdir /ATSapp
WORKDIR /ATSapp
COPY Gemfile /ATSapp/Gemfile
COPY Gemfile.lock /ATSapp/Gemfile.lock
RUN bundle install
COPY . /ATSapp

# 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-2.Gemfile
```Gemfile:Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.6'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 5.0'
# Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false

gem 'bcrypt',  '3.1.12'

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '~> 3.2'
  # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

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

###1-3.Gemfile.lock
```Gemfile.lock:Genfile.lock(空のファイル)
```

###1-4.entrypoint.sh
```sh:entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /ATSapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
```

###1-5.docker-compose.yml
```yml:docker-compose.yml
version: "3"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/test_db
    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:
      - .:/ATSapp
    ports:
      - "3000:3000"
    depends_on:
      - db

volumes:
  test_db:
    external: true


```




##2.ビルドしていく
以上のファイルの準備が整ったらいよいよ作成していきます。
→[よく使うコマンド集](#よく使うコマンド集)

###2-1.docker-compose build
```
$ docker-compose build
```

###2-2.DBの作成・マイグレート
```
$ docker-compose run web rails db:create
$ docker-compose run web rails db:migrate
```

###2-3.webpackerのインストール
```
$ docker-compose exec web rails webpacker:install
```

###2-4.docker-compose up
```
$ docker-compose up
```

###2-5.動作確認
http://localhost:3000 にアクセスし、railsが立ち上がっていることを起動！

#よくあるエラー集
以下には恐らくWindowsでDockerを構築する際の特有のエラーや、よくあるエラー対処法を書いていきます。

##postgreSQLにvolumeがマウントできない

**原因：** **postgresqlのデータ永続化が上手くいっていない**

```
data directory "/var/lib/postgresql/data" has wrong ownership
The server must be started by the user that owns the data directory.
child process exited with exit code 1
initdb: removing contents of data directory "/var/lib/postgresql/data"
```

**解決策：** **docker-compose.ymlでvolumesを定義してやる。**

```docker-compose.yml
version: "3"
services:
  db:
    image: postgres
    volumes:
      - ./tmp/db:/var/lib/postgresql/test_db
    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:
      - .:/ATSapp
    ports:
      - "3000:3000"
    depends_on:
      - db
#ここに追記
volumes:
  test_db:
    external: true

```
これで、
```docker volume create --name test_db```
をした後に
```docker-compose run```
にて解決できると思われます。

##レンダリングができない
**原因：アクセス元のIPアドレスが 127.0.0.0の場合だけ使えるというセキュリティがかかっている**

```
Started GET "/" for ○○○.○○○.○○.○ at 2021-05-14 23:14:04 +0000
web_1  | Cannot render console from ○○○.○○○.○○.○! Allowed networks: 127.0.0.0/127.255.255.255, ::1
```

**解決策：IPアドレスをホワイトリストに登録する。**

```config/environment/development.rb
config.web_console.whitelisted_ips = '○○○.○○○.○○.○'
```

##localhostに接続できない

**解決策：ホストOSのportとコンテナのportを繋いでやる**

ポートフォワーディングの設定をホストポート3000,ゲストポート3000を追加。

##Windowsでのgit cloneは改行コードの自動変換に注意
デフォルトの設定だとWindowsではgit cloneした際に、**勝手に改行コードがCRLFに変換されてしまいます。**このままだとエラーが起きてしまう為、自動変換しないように以下を実行してからgit cloneしてください

```
$ git config --global core.autocrlf false
```

##シンボリックリンクエラー
パッケージのインストール時にシンボリックリンクエラーが出る

###**対処方法1：install時に```--no-bin-links```をつける**

これをつけることで、シンボリックリンクの作成を回避するようになります。
例）
```yarn install --no-bin-links```

###**対処方法2：シンボリックリンクの作成を許可する**


windowsで、
ローカルセキュリティーポリシーを開き、

**セキュリティの設定：
→ローカルポリシー
→ユーザーの権限の割り当て
→シンボリックリンクの作成
→Usersを追加して再起動**

でいけるのですが**windows 10 homeでは標準ではこの機能は使えない**ので、以下の手順でローカルセキュリティポリシーを使えるようにしていきます。

###ローカルセキュリティポリシーをwin 10 homeで使用可能にする：

```.bat:グループポリシーエディター.bat
@echo off 
pushd "%~dp0" 

dir /b %SystemRoot%\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientExtensions-Package~3*.mum >List.txt 
dir /b %SystemRoot%\servicing\Packages\Microsoft-Windows-GroupPolicy-ClientTools-Package~3*.mum >>List.txt 

for /f %%i in ('findstr /i . List.txt 2^>nul') do dism /online /norestart /add-package:"%SystemRoot%\servicing\Packages\%%i" 
pause
```

①上記のファイルをグループポリシーエディター.batという名前で保存
②作成したファイルを管理者権限で実行
③実行後、qpedit.mscというファイルを実行する事でGUIでグループポリシーエディターを操作できるようになる。
1回サインアウトが必要！


#よく使うコマンド集
（webはサービス名です）

・ディレクトリ確認
```docker-compose exec web rails dir```

・ファイル削除
```docker-compose exec web rails rm file_name```

・ディレクトリ削除
```docker-compose exec web rails rm -rf dir_name```

・シンボリックリンクの作成を回避しながらinstall
```docker-compose exec web yarn install --no-bin-links```

・バージョン確認
```docker-compose exec web package_name --version```

・gemfileからgemをインストール
```docker-compose exec web rails bundle install```

・webpackerのコンパイル
```docker-compose exec web rails webpacker:compile```

・ビルドする
```docker-compose build```

・db作成
```docker-compose run web rails db:create```

・dbマイグレーション
```docker-compose run web rails db:migrate```

・ボリュームの確認
```docker-compose volume ls```

・ボリュームの削除
```docker-compose volume rm volume_name```

・コンテナの起動
```docker-compose up```

・マシンの確認
```docker-machine ls```

・コンテナの確認
```docker-compose ps -a```

・デフォルトではコンテナとネットワークを削除
```docker-compose down```

・稼働中のコンテナの停止
```docker-compose stop```

・ログの確認
```docker-compose logs```


#最後に
以上です！まだまだ初学者なので間違っている部分とかあれば教えてください！
#参考

・[Docker for Windowsでpostgresのデータマウントができない人へ](https://qiita.com/ko-da-k/items/47b96883144a5bf1cb1e)
・[気をつけて！Git for Windowsにおける改行コードGit](https://qiita.com/uggds/items/00a1974ec4f115616580)
・[Docker Composeを使った初期装備なRails6/PostgreSQL環境の作り方](https://qiita.com/tanaken0515/items/0e207160c25a6b815561)