17
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Docker + Rails6 + React + TypeScript の環境構築

Last updated at Posted at 2021-05-07

streampack の endo です。
ローカルで、Docker + Rails6 + React(react-rails) + TypeScript の環境を作る機会があり、ちょっと苦労したので備忘録になります。

Docker 上に Rails プロジェクトを作成する

まずは Docker 上に Rails プロジェクトを作成。DB は MySQL5.7。

適当なディレクトリを作り、

  • Gemfile
  • Gemfile.lock
  • Dockerfile
  • docker-compose.yml

の 4 ファイルを作成する。

Gemfile
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "rails"
Gemfile.lock(空ファイル)

Dockerfile
FROM ruby:2.7.2

RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
  && apt-get update \
  && 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 build-essential \
  libpq-dev \
  nodejs \
  yarn

RUN mkdir /myapp

ENV APP_ROOT /myapp
WORKDIR $APP_ROOT

ADD ./Gemfile $APP_ROOT/Gemfile
ADD ./Gemfile.lock $APP_ROOT/Gemfile.lock

RUN bundle install
ADD . $APP_ROOT
docker-compose.yml
version: "3"
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: demo-db
    ports:
      - "3306:3306"
    volumes:
      - demo-db:/var/lib/mysql

  web:
    build: .
    command: rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    links:
      - db

volumes:
  demo-db:

docker-compose run コマンドで Rails プロジェクトの作成。

shell
$ docker-compose run web rails new . --force --no-deps --database=mysql

Rails プロジェクトを作成できたら、build する。

shell
$ docker-compose build

データベースの作成

config/database.yml を編集する。

config/database.yml
## 編集した箇所のみ抜粋
default: &default
  password: password # docker-compose.yml の MYSQL_ROOT_PASSWORD: で設定したパスワード
  host: db # localhost → db に変更

データベースを作成する。

shell
$ docker-compose run web rake db:create

Docker の起動

Docker を起動する。

shell
$ docker-compose up

http://0.0.0.0:3000 にアクセスすると、Rails の初期画面が表示される。

この時 shell に以下のようなエラーが出るときは、

shell
Cannot render console from 172.20.0.1! Allowed networks: 127.0.0.0/127.255.255.255, ::1

config/environments/development.rb に

config/environments/development.rb
Rails.application.configure do
  config.web_console.permissions = '0.0.0.0/0'
end

を追加すればエラーログが消える。

React の導入

react-rail を使って react を rails プロジェクトに導入する。

Gemfile
gem 'react-rails'

再度 build を実行する。

shell
$ docker-compose build

下記コマンドを実行する。

shell
$ docker-compose run web rails webpacker:install       # OR (on rails version < 5.0) rake webpacker:install
$ docker-compose run web rails webpacker:install:react # OR (on rails version < 5.0) rake webpacker:install:react
$ docker-compose run web rails generate react:install

実際に React が導入されているか確認する。

controller の作成。

shell
$ docker-compose run web rails g controller sample index

以下のファイルが作成されていれば OK。

app/controllers/sample_controller.rb
class SampleController < ApplicationController
  def index
  end
end

react コンポーネントファイルの作成。

shell
$ docker-compose run web rails g react:component Sample

app/javascript/components/Sample.tsx が作成されるので、以下のように修正する。

app/javascript/components/Sample.jsx
import React from "react";
const Sample = () => {
  return <>this is react sample.</>;
};

export default Sample;

view の作成。
app/views/sample/index.html.erb を作成し react コンポーネントを読み込む。

app/views/sample/index.html.erb
<%= react_component 'Sample' %>

ルーティングを追加する。

config/routes.rb
Rails.application.routes.draw do
  get "sample", to: "sample#index"
end

Docker を起動し、http://0.0.0.0:3000/sample にアクセスする。「this is react sample.」の文字が表示されていれば OK。

TypeScript の導入

React が導入できたので、以下コマンドで TypeScript 導入する。

shell
$ docker-compose run web bundle exec rails webpacker:install:typescript
$ docker-compose run web yarn add @types/react @types/react-dom

無事インスールが終えたら sample.jsx の拡張子を sample.tsx に修正する。

app/javascript/components/Sample.tsx
import React from "react";
const Sample: React.FC = () => {
  return <>this is typescript sample.</>;
};

export default Sample;

ここまで修正したら再度 http://0.0.0.0:3000/sample にアクセスし、「this is typescript sample.」の文字が表示されていることを確認する。

JS の修正時にホットリロードさせる

Docker の場合は $ bin/webpack-dev-server のコマンドを直接叩くとエラーがでるっぽいので docker-compose.yml を修正した。

version: "3"
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: demo-db
    ports:
      - "3306:3306"
    volumes:
      - demo-db:/var/lib/mysql

  web: &web
    build: .
    command: rails s -p 3000 -b '0.0.0.0'
    environment:
      WEBPACKER_DEV_SERVER_HOST: webpacker
    volumes:
      - .:/myapp
    ports:
      - "3000:3000"
    links:
      - db

  webpacker:
    <<: *web
    command: bundle exec bin/webpack-dev-server
    depends_on: []
    environment:
      WEBPACKER_DEV_SERVER_HMR: "true"
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
    ports:
      - "3035:3035"

volumes:
  demo-db:

webpacker の service を追加。それに伴い web の service も修正。

$ docker-compose up で Docker を起動し、http://0.0.0.0:3000/sample にアクセスする。app/javascript/components/Sample.tsx のファイルを適当に書き換えて保存するとホットリロードすることがわかる。

まとめ

以上で Docker + Rails6 + React(react-rails) + TypeScript の環境構築ができました。Docker は初心者なので(間違っていたらご指摘ください)、諸々調べながら記述しております。react-railsRails6TypeScript を使ってる情報は(特に最近では)意外と少なく感じたので、やはり Rails は API モードで使うのが主流なのだと思いました。react-rails を使用している方の参考になれば幸いです。

参考

Docker を使って Rails6 環境の構築をしてみる - Qiita
【Rails, React】Webpacker と TypeScript のセットアップ - Qiita
docker で webpacker が遅い問題を改善する - Qiita
GitHub - reactjs/react-rails: Integrate React.js with Rails views and controllers, the asset pipeline, or webpacker.
GitHub - rails/webpacker: Use Webpack to manage app-like JavaScript modules in Rails

17
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?