Rails
Makefile
docker
docker-compose

Makefileを使ってスマート?にDocker+Railsの開発をしようとした

はじめに

周りの人にDockerを勧めているが手応えがない😢
知人に相談したところ「Makefileを使えばコマンド入力が簡単になるので、誰でも触りやすいくてオススメ」と言われた。
aliasも1つの方法だけれども、簡単に共有できるMakefileに魅力を感じた。

というわけで、自分なりに書いてみる。
改善の意見があれば、ぜひコメントで教えてほしい

今回やったこと

1. コマンドの省略

Dockerを用いてRailsの開発をするときは、Docker Composeを使うのでコマンドが長くなってしまう

$ docker-compose exec web rails db:create

例をあげるとこんな感じ。
railsコマンド使うときに、毎回 docker-compose exec web を打つのはストレスだ。
これがMakefileを使うことで…

$ make dbc

かなり短くなる!

2. コマンドの複合

Dockerを使っていると、Gemfileを操作した後には必ず docker-compose build をする。
この記事のようにすると回避できるが、Gemfileから記述を消した不要なgemは残ってしまう
(少なくとも私が試した限りでは)
このままでは、いちいち不要なgemを選択してアンインストールすることになる。

$ docker-compose exec web gem uninstall [gem_name]
$ docker-compose exec web bundle install

面倒だからgemの削除とbundle installをこのコマンドで一括で行えるようにしてみた。

$ make br

ファイルの作成

Makefile

Makefile
FIG = docker-compose
WEB = $(FIG) exec web
RAILS = $(WEB) rails

# コンテナ操作コマンド等
build:
    @$(FIG) build
up:
    @$(FIG) up -d
down:
    @$(FIG) down
restart:
    @$(FIG) stop
    @$(FIG) start
clean:
    @docker image prune
    @docker volume prune

# bundle installコマンド
bi:
    @$(WEB) bundle install
br:
    @$(WEB) gem uninstall -aIx
    @make bi

# railsコマンド
rc:
    @$(RAILS) console
rr:
    @$(RAILS) routes
rt:
    @$(RAILS) test

# dbコマンド
dbc:
    @$(RAILS) db:create
dbm:
    @$(RAILS) db:migrate
dbs:
    @$(RAILS) db:seed

使いそうなコマンドをいくつかピックアップしてまとめた。
変数を使うことができるのは:ok_woman:

$ make [ターゲット名]

makeのあとにターゲット名(build, up等)を打つだけで、長いコマンドを実行することができる。

Dockerfile

Dockerfile
FROM ruby:2.5.1
ENV LANG C.UTF-8

RUN apt-get update -qq && apt-get install -y \
    build-essential \
    nodejs \
 && rm -rf /var/lib/apt/lists/*

RUN gem install bundler

WORKDIR /tmp
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install

ENV APP_HOME /myapp
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
ADD . $APP_HOME

docker-compose.yml

docker-compose.yml
version: '3'

services:
  web:
    build: .
    ports:
      - "3000:3000"
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/myapp
      - bundle:/usr/local/bundle
    depends_on:
      - db
  db:
    image: mysql:5.7
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
    ports:
      - '3306:3306'
    volumes:
      - mysql_data:/var/lib/mysql

volumes:
  bundle:
    driver: local
  mysql_data:
    driver: local

試してみる

①必要なイメージのpull&イメージの作成

まずはこれから。docker-compose build

$ make build

②イメージからコンテナを作成&起動

普段はこのコマンドを打った後に作業を行う。docker-cpmpose up

$ make up

③起動したコンテナを停止&削除

作業を終わるときに打つコマンド。upのときに作られたvolumeは残る。docker-cpmpose down

$ make down

④コンテナの再起動

調子が悪いときはこれを打ってみる。docker-cpmpose stop && docker-cpmpose start

$ make restart

⑤不要なイメージと使われていないvolumeを削除

放置してると容量が食われるので、定期的に打ちたいコマンド。docker image prune & docker volume prune

$ make clean

⑥bundle install

Gemfileの記述に基づいてgemの追加をする。docker-cpmpose exec web bundle install

$ make bi

⑦不要なgemを削除してからbundle install

Gemfileの記述に基づいてgemの更新をする。
docker-cpmpose exec web gem uninstall -aIx && docker-cpmpose exec web bundle install

$ make br

⑧dbの操作

dbを作成       docker-compose exec web rails db:create
dbのマイグレーション docker-compose exec web rails db:migrate
dbに初期値を投入   docker-compose exec web rails db:create

$ make dbc
$ make dbm
$ make dbs

⑨railsコマンド

コンソールの起動   docker-compose exec web rails console
ルーティングの確認  docker-compose exec web rails routes
テストの実行     docker-compose exec web rails test

$ make rc
$ make rr
$ make rt

おわりに

長く鬱陶しいdockerコマンドが短くなったのは快適になった。
しかし、rails generate等のコマンドを打ちたいときは不便に感じたので使う場所は限られる。
引数を与えて入力することもできるが、少し面倒になるのでスマートではない。

「やっぱりaliasは便利だな」

もちろんMakefileも便利なので、aliasを使わないならありだろう。