「Rails APIモードとReact Hooksを使ってToDoリストを作る」をdocker上に配置する

3 min read読了の目安(約3300字

目的

これもやったことの備忘録が目的になります。
Know Howより、How to methodな内容にします

背景

バックエンドとフロントエンドを分けたアプリケーションをdockerにあと乗せする記事がなかったため。
せっかくやったのだから記事にしちゃおうって考えです。

アウトライン

  1. docker-compose.ymlを用意する
  2. Dockerfile(Backend用)を用意する
  3. entrypoint.shを用意する
  4. Dockerfile(Frontend用)を用意する
  5. rails側の調整
  6. axiosmaterial-uiのインストール

やってみよう!

docker-compose.yml

既存のrailsアプリ等に「後からdocker」を用意する場合でも、
アプリを作り始める時でも、やることはほとんど変わりません。

docker-compose.ymlはメインのディレクトリ上に配置します。

docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.6
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    volumes:
      - mysql-data:/var/lib/mysql 
    ports:
      - "4306:3306" #別件で3306は使っていたので4306を指定しました

  app:
    build: 
      context: .
      dockerfile: Dockerfile_back
    command: /bin/sh -c "rm -f /myapp/tmp/pids/server.pid && bundle exec rails s -p 3001 -b '0.0.0.0'"
    image: rails:dev
    volumes:
      - .:/myapp    #myappというところは任意で設定してください
      - ./app/vendor/bundle:/myapp/vendor/bundle 
    environment:
      TZ: Asia/Tokyo
      RAILS_ENV: development
    ports:
      - "3001:3001"
    depends_on: 
      - db

  front:
    build: 
      context: todo_front
      dockerfile: Dockerfile_front
    volumes:
      - ./todo_front:/todo_front
    command: /bin/sh -c "cd todo_front && yarn && yarn start"
    ports:
      - "3000:3000"

volumes:
  mysql-data:
  bundle: 

Dockerfile(バックエンド用)を用意する

entrypoint.shを用意する

Rubyのバージョンを既存のrailsアプリのRubyバージョンを合わせました。
それとmyappというのは任意になります。合わせてもOKです!
SQLがmysql-clientと入力するとエラーになります。
いつしか、maliadb-clientに統一されたようです。

Dockerfile_backentrypoint.shdocker-compose.ymlと同じディレクトリ階層に配置しています。

Dockerfile_back
FROM ruby:2.6.3

RUN apt-get update && \
    apt-get install -y mariadb-client nodejs vim

RUN mkdir /myapp

WORKDIR /myapp

ADD Gemfile /myapp/Gemfile
ADD Gemfile.lock /myapp/Gemfile.lock

RUN gem install bundler
RUN bundle install

ADD . /myapp

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3001

CMD ["rails", "server", "-b", "0.0.0.0"]
entrypoint.sh
#!/bin/bash
set -e

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

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

Dockerfile(frontend用)

todo_frontディレクトリ上に配置します。

Dockerfile_front
FROM node:14

Rails川の調整

database.yml'を調整してあげます。 socket通信になっているので、host: db`に変えてあげます。

database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
- socket: /tmp/mysql.sock
+ host: db

axiosmaterial-uiのインストール

コンテナをバックグラウンドで立ち上げます。
そして、axiosやmaterial-uiをインストールします。
ちなみにexecはすでにコンテナが立ち上がっている状態で使えます。
コンテナが立ち上がっていない時はrunを使います。
終わったら、dbを作って、マイグレートして、植えて終わりになります。

console
$ docker-compose up -d #コンテナを立ち上げる
$ docker-compose exec front npm install axios
$ docker-compose exec front npm install @material-ui/core
$ docker-compose exec app bin/rails db:create
$ docker-compose exec app bin/rails db:migrate
$ docker-compose exec app bin/rails db:seed

localhost:3000にアクセスすると、前回と同じ画面が立ち上がるはずです。
終わり

終わりに

今回は、docker for Macの調子が悪く、何度もattachが発生しました。
再起動すると次のプロセスに行けました。
なんだろう、もう少しdockerの勉強した方がいいかなと思いました。