amakanの開発環境をDockerに移行した

https://amakan.net/ のこの辺の改善の続き。

環境構築

docker が動く環境なら、git clone して bin/setup を叩けば開発が始められる。

$ cat bin/setup
#!/bin/bash
set -ex

docker-compose up -d
docker-compose run --rm node yarn install
docker-compose run --rm puma bundle install
docker-compose run --rm puma bundle exec rake db:create db:load:schema
docker-compose up -d

やっているのはこういう処理。

  1. イメージのダウンロードとビルド
  2. ライブラリのインストール
  3. DBスキーマの作成
  4. コンテナの起動

bundle と node_modules は volume を利用してマウントしているので、ビルド後に手元でインストールする必要がある。代わりに、これらが変更されるたびにビルドを行う必要はない。

開発者が1人しか居ない上に開発機が1つしかないので、ビルド済みのイメージをレジストリにアップロードして管理したりはしていない。

様子見

docker-compose ps で様子を見られる。

$ docker-compose ps
      Name                    Command               State               Ports
-----------------------------------------------------------------------------------------
amakan_mysql_1     /entrypoint.sh mysqld            Up      0.0.0.0:3306->3306/tcp
amakan_nginx_1     nginx -g daemon off;             Up      443/tcp, 0.0.0.0:8080->80/tcp
amakan_node_1      yarn run watch                   Up
amakan_puma_1      bundle exec puma -C config ...   Up      0.0.0.0:3000->3000/tcp
amakan_redis_1     docker-entrypoint.sh redis ...   Up      0.0.0.0:6379->6379/tcp
amakan_sidekiq_1   bundle exec sidekiq --queu ...   Up

docker-compose.yml

長いので Gist に置いた。特筆すべきことはあまり無い。

https://gist.github.com/r7kamura/ef929a88e291581af8d6345ff9c7f8cd

docker/rails/Dockerfile

rails (pumaとsidekiq) 用の Dockerfile はこういう感じにした。レビューお願いします。mysql-client のバージョン指定が甘いかも。

FROM ruby:2.4.0-preview3

WORKDIR /app

RUN mkdir -p /app/tmp/cache \
  && mkdir -p /app/tmp/pids \
  && mkdir -p /app/tmp/sockets

RUN apt-get update \
  && apt-get install --yes --no-install-recommends mysql-client \
  && rm -rf /var/lib/apt/lists/*

ENV BUNDLE_PATH /bundle

ディレクトリ構成

それぞれのコンテナの作成に必要なデータは、./docker ディレクトリ以下に入れている。

$ tree --charset unicode ./docker
./docker
|-- nginx
|   `-- nginx.conf
|-- node
|   `-- Dockerfile
`-- rails
    `-- Dockerfile

3 directories, 3 files

bundle install

Gemfile が更新されたときはこうする。

docker-compose run --rm puma bundle install

yarn install

package.json が更新されたときはこうする。

docker-compose run --rm node yarn install

rspec

手元で RSpec を実行するときはこう。

docker-compose run --rm puma bundle exec rspec /path/to/test_spec.rb

rails c

コンソールを利用するときはこう。

docker-compose run --rm puma bundle exec rails c

CI

CircleCI では Docker を使っていない。Circle CI 2.0 beta では Docker コンテナで色々できるが、docker-compose.yml 風のコードを circle.yml に設定しないといけなくて、面倒でまだ試していない。

デプロイ

デプロイは完全に CircleCI に任せているのであまり影響が無かった。Capistrano が動いて SSH の鍵さえ指定できれば動くので、恐らく puma 用のコンテナからでもデプロイできる。

本番環境

本番環境ではまだ Docker を使っていない。いまECSを利用して試してみているところで、上手くいけば移行するつもり。VPC 環境への移行や blue-green deployment 方式への移行なども同時にやる予定。