Docker環境にRails5.2.1をVue.jsも添えて...DBはPostgreSQLだよ！

# Rails5.2.1環境にVue.jsを使っていこう！

すでにRailsの中にVue.jsを導入する手順はQiita内でもたくさんでてますね！[こちら一例](https://qiita.com/naoki85/items/51a8b0f2cbf949d08b11)

ただこちらは5.1版のため現在最新版になっている5.2版とは少し勝手が変わってきます。
ローカルに直接開発環境を用意してもいいのですが、今はもう平成の夏も終わり！ここはやはりDockerを使って開発環境を用意していきましょう！
今回はDBにPostgreSQLを用いています。Herokuでは積極的にフォローしているDBですので、Heroku環境でのアプリ開発を意識しました！

## DockerfileとDokcer-compose.ymlを用意しよう！

```:Dockerfile
# Rubyは2.5.0以上で
FROM ruby:2.5.0

ENV LANG C.UTF-8
# プロジェクト名にしておきましょう。 Rails new . とすると名前がカレントディレクトリになります
ENV WORKING_DIR /var/www/VueApp

WORKDIR $WORKING_DIR

# 基本項目をインストールします. vimはお好みで
RUN apt-get update -qq && \
    apt-get install -y sudo build-essential libpq-dev vim postgresql-client

# yarn環境の構築
RUN apt-get install -y curl apt-transport-https wget && \
    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

# nodejs環境の構築
RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - && \
    apt-get install nodejs

# Cannot find module node-sass対策
RUN yarn add node-sass

# Gemfileを事前にこのDockerfileと同じ場所に用意しておいてください
ADD ./Gemfile $WORKING_DIR
# Gemfile.lockの中身は空で
ADD ./Gemfile.lock $WORKING_DIR

RUN gem install bundler

RUN bundle install
```

お次にDockerfileと同じカレントディレクトリにdocker-compose.ymlを用意します

```:docker-compose.yml
version: '3'
services:
  db:
    image: postgres:10.1
    container_name: app_db
    environment:
      - "POSTGRES_USER=root"
      - "POSTGRES_PASSWORD=root"
    ports:
      - "5432:5432"
  web:
    build: .
    image: app
    container_name: main_app
    command: /bin/sh -c "rm -f ./tmp/pids/server.pid && ./bin/server"
    volumes:
      - .:/var/www/VueApp
    environment:
      - "DATABASE_HOST=db"
      - "DATABASE_PORT=5432"
      - "DATABASE_USER=root"
      - "DATABASE_PASSWORD=root"
    ports:
      - "3000:3000"
      - 8080:8080
    depends_on:
      - db
```

開発環境なので適当なユーザやパスワードを指定していますので、本番環境での運用はお控えください(まぁHerokuだと別に用意されるから平気だけど...)

注目するところは

```
command: /bin/sh -c "rm -f ./tmp/pids/server.pid && ./bin/server"
```

でしょうか。ここはRailsサーバとVue.jsのコンパイルを同時に実行するために必要なファイルを後々用意するので、この時点でサーバの立ち上げ方法を指定しておいてあります。

```
rm -f ./tmp/pids/server.pid
```
は

```
ctr + c 　　or　　 command + c
```

を実行してコンテナ内のRailsサーバを落とした際にserver.pidが残ってしまい、次にサーバを立ち上げたときにうまく実行されなくなってしまうため、実行時に一旦そのserver.pidファイルを削除するために用意したコマンドです。


さあ!用意は整いました！早速

```
docker-compose build
```
をして立ち上げましょう！そして

```
docker-compose run --rm web /bin/bash
```
を実行してコンテナ内に入りましょう！素敵なアプリ開発の船出です！


## RailsアプリにVue.jsを組み込もう！

お次にいよいよRailsアプリを開発していきます

```
rails new . --webpack=vue -f -d postgresql
```

--webpack=vueでwebpackerを使いながらVue.jsを使うことを明記します。
またオプションfによってGemfile, Gemfile.lockをRailsの中で生成される方へと自動的に上書きされるようにし、オプションdでDBを指定します。これにて一旦アプリができあがりました！

次にconfig/database.ymlにdocker-compose.ymlで設定した環境を適応させてあげます。

```:config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  # For details on connection pooling, see Rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  host: <%= ENV.fetch('DATABASE_HOST') { 'localhost' } %>
  port: <%= ENV.fetch('DATABASE_PORT') { 5432 } %>
  username: <%= ENV.fetch('DATABASE_USER') { 'root' } %>
  password: <%= ENV.fetch('DATABASE_PASSWORD') { 'root' } %>
```

これでDBを作ることができます。

```
rails db:create
```

を実行してdevelopment, test用のDBを作成しましょう。
そしていよいよVue.jsを呼び出します。まずは下記コマンドを実行します。

```
rails g controller home index
```

これでcontroller周りのファイルが作成されました。

```:config/routes.rb
Rails.application.routes.draw do
  root to: 'home#index'
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end
```

URLをルートに変更

```:app/views/hoge/index.html.erb
<%= javascript_pack_tag 'hello_vue' %>
```

先頭に上のタグを追加しちゃいましょう！これでapp/javascript/pack以下にあるhello_vueファイルが呼び出されます！

これで表示の準備は整いました！


## webpackerを使って表示しましょう！

残りもあと僅かです！まずは5.1版でも行った作業であるProcfile.devとbin/serverファイルをそれぞれ作り記述していきます。Procfile.devはプロジェクトのルートに作ってください。

```Procfile.dev
web: bundle exec rails s -b 0.0.0.0 -p 3000
# watcher: ./bin/webpack-watcher
webpacker: ./bin/webpack-dev-server
```

Procfile.devではオプションpでポートを、オプションbでバインドするIPアドレスを指定しておきましょう。そして実行する./bin/webpack-dev-serverを書きましょう。これでフロント側もサーバ側も一度に実行することができるようになりました。続いてbin/serverを作成します。

```:bin/server
#!/bin/bash -i
bundle install
bundle exec foreman start -f Procfile.dev
```

これでbin/serverと打つことで上のProcfile.devを実行することができます！docker-compose.ymlに書いたコマンドはここでした！

さて、bin/serverでforemanというコマンドがでてきました。gemにforemanを書きましょう。

```:Gemfile
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.0.5', '< 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'
  # ここを追加
  gem 'foreman'
end
```

そして

```
bundle install
```

しちゃいます!
あともう二点やっておきたいことがあります。

```:config/initializers/content_security_policy.rb
Rails.application.config.content_security_policy do |policy|
  policy.default_src :self, :https
  policy.font_src    :self, :https, :data
  policy.img_src     :self, :https, :data
  policy.object_src  :none
  # 条件分岐を追加. すでにpolicy.script_srcは書いてある
  if Rails.env.development?
    policy.script_src :self, :https, :unsafe_eval
  else
    policy.script_src :self, :https
  end
  policy.style_src   :self, :https
end
```

これはCSP対策で必要である。chromeとかで引っかかるので書いておくこと。
それともう一点

```:config/environments/development.rb
  # Cannot render console from Allowed networks 対策
  config.web_console.whitelisted_ips = '0.0.0.0/0'
```

これを追加してください。serverを立ち上げたときの警告対策です。

さーて！これで準備は整いました。exitしてコンテナ内のbundle installを反映させるため

```
docker-compose build
```

しちゃいましょう！そして

```
docker-compose up
```

してください！
localhost:3000で無事アクセスできたら成功です！！お疲れ様でした！！


### 参考

[Vue.jsとRailsでTODOアプリのチュートリアルみたいなものを作ってみた](https://qiita.com/naoki85/items/51a8b0f2cbf949d08b11)
[Rails+PostgreSQLの環境をdocker-composeで作成する](https://qiita.com/atzu/items/4ca6306087e3813b0941)
[ailsで「Cannot render console from Allowed networks」と言われたら](https://qiita.com/suin/items/9b567c63af73b235e458)