1. minsu

    Posted

    minsu
Changes in title
+Docker + Rails + React
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,221 @@
+# Docker + Rails + React
+
+streampack の minsu です。
+
+今年の夏は主に室内で過ごしていましたが、先日帰省した折に中古のカメラを手に入れたので今後はアウトドアな趣味としてお散歩カメラをきめこみたいと思ってます。 ~~涼しくなったら、たぶん~~
+
+## 目的
+フロント: React
+バック: Rails
+を Docker を利用して構築します。
+
+React + Rails ですが webpacker を利用する方法で行います。
+
+## ファイルの用意
+
+まず、`Gemfile`、`Gemfile.lock`、`Dockerfile`、`dcocker-compose.yml`を用意します。
+
+```ruby:Gemfile
+source 'https://rubygems.org'
+gem 'rails', '5.1.4'
+```
+
+```dockerfile:Dockerfile
+FROM ruby:2.4.1
+
+RUN apt-get update -qq && apt-get install -y mysql-client build-essential nodejs apt-transport-https
+
+RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
+RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
+RUN apt-get update && apt-get install -y yarn
+
+RUN mkdir /app
+WORKDIR /app
+COPY Gemfile /app/Gemfile
+COPY Gemfile.lock /app/Gemfile.lock
+RUN bundle install
+COPY . /app
+```
+
+```yml:docker-compose.yml
+version: '3'
+services:
+ app:
+ build: .
+ command: /bin/sh -c "rm -f /app/tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
+ volumes:
+ - .:/app
+ ports:
+ - "3000:3000"
+ depends_on:
+ - db
+
+ db:
+ image: mysql:5.7
+ command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci
+ environment:
+ - MYSQL_ROOT_PASSWORD=root
+ volumes:
+ - mysql_vol:/var/lib/mysql
+
+volumes:
+ mysql_vol:
+```
+pid は、開発用WEBサーバを起動するときに tmp/pids/server.pidに書き込まれて終了するときに削除されるのですが、なんらかの要因で削除されずに終了した場合は起動中と判断されて新たにサーバを起動できないので`rm -f /app/tmp/pids/server.pid`で起動時に削除します。
+
+## rails new
+コンテナから rails プロジェクトを作成します。
+Gemfileは上書き、DBはMySQLを指定します。
+
+```
+$ docker-compose run app rails new . --force --database=mysql
+```
+
+docker-compose.yml の mysql の rootパスワードを `MYSQL_ROOT_PASSWORD=root` に設定したので config/database.yml の development に設定を追加しました。
+host も同じく指定した db に変更します。
+
+```yml:config/database.yml
+username: root
+password: root
+host: db
+```
+
+Gemfile に
+
+```ruby
+gem 'webpacker'
+gem 'react-rails'
+```
+を追加し、 bundle install しなおした後に
+
+```
+$ docker-compose build
+```
+次のコマンドを実行します。
+
+```
+$ docker-compose run app rails webpacker:install
+$ docker-compose run app rails webpacker:install:react
+$ docker-compose run app rails generate react:install
+```
+上の2行は rails new のタイミングで ` --webpack=react `のオプションを追加でも良かったみたいです。
+
+`package.json` の更新や
+`app/javascript/packs/`配下に `application.js`、`hello_react.jsx` が作成されます。
+
+## db、 model 作成
+適当な model と seeds データを用意して DB を作成後にデータを入れます。
+
+```
+$ docker-compose run app rails g model List title:string desc:string
+```
+
+```ruby:db/seeds.rb
+
+5.times do
+ List.create(
+ title: 'title_' + SecureRandom.hex(4),
+ desc: 'desc_' + SecureRandom.hex(4)
+ )
+end
+```
+
+```
+$ docker-compose run app rails db:create
+$ docker-compose run app rails db:migrate
+```
+
+作成したモデルを一覧表示させてみます。
+
+controller、view を作成
+
+```
+$ docker-compose run app rails g controller Lists index
+```
+
+```ruby:lists_controller.rb
+ def index
+ @lists = List.all
+ end
+```
+view では `javascript_pack_tag` と `react_component` のタグを用いて js を呼び出します。
+
+```erb:lists/index.html.erb
+<%= javascript_pack_tag 'application' %>
+
+<h1>Lists#index</h1>
+<%= react_component 'Lists', lists: @lists %>
+```
+
+## react component 作成
+順番が前後しましたが、 view で呼び出している components を実装します。
+
+```
+$ rails g react:component Lists
+```
+のコマンドで app/javascript/components/Lists.js が作成されるので編集します。
+
+```react:Lists.js
+import React from "react"
+import PropTypes from "prop-types"
+export default class Lists extends React.Component {
+ constructor(props){
+ super(props)
+ this.state = {
+ lists: []
+ };
+ }
+ componentDidMount(){
+ this.setState({
+ lists: this.props.lists
+ })
+ }
+ render () {
+ return (
+ <div>
+ <table>
+ <thead>
+ <tr>
+ <th>ID</th>
+ <th>Title</th>
+ <th>Description</th>
+ <th>created_at</th>
+ <th>updated_at</th>
+ </tr>
+ </thead>
+ <tbody>
+ {this.state.lists.map((list) => {
+ return (
+ <tr key={list.id}>
+ <td>{list.id}</td>
+ <td>{list.title}</td>
+ <td>{list.desc}</td>
+ <td>{list.created_at}</td>
+ <td>{list.updated_at}</td>
+ </tr>
+ );
+ })}
+ </tbody>
+ </table>
+ </div>
+ );
+ }
+}
+```
+
+## 動作確認
+rails, webpack を立ち上げます。
+
+```
+$ docker-compose up -d
+$ docker-compose run app bin/webpack-dev-server
+```
+
+`http://localhost:3000/lists/index` にアクセスします。
+<img width="822" alt="スクリーンショット 2019-08-30 15.19.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/399734/fbcf6e8d-06a2-5d16-44b5-aef433bf1a63.png">
+無事に一覧が表示されました。
+
+## まとめ
+起動の確認と表示までを行いました。
+
+この状態では何の機能もないので React での CRUD 操作を実装するまでを追記、または新しく記事にしたいと思います。