rails

Rails馴れ初め

ActiveRecordが使いやすく、ちょっとしたアプリをモノシリックにすぐ作れるので大変重宝するRails。
思えば学生の時初めてお金を貰って作ったのもRailsアプリだったので個人的に愛が深い。
現職でもちょっとしたツールやデモ開発で活躍している。

そんなRailsにも環境構築の壁があり、windowsだと難易度が跳ね上がる。
macやlinuxならrbenvとかでそこそこローカルを綺麗に開発できた気がする。
Virtual Box + VagrantでLinux環境を用意するのが一昔前のアプローチだった。

だが今から始めるならより楽なDockerを使いたい。

Railsとは

Rubyのwebアプリ用フレームワーク。設定より規約?だかそういう考え方の元作られた。
確かに右も左も分からない初心者に設定やらデザインパターンやらを見せても圧倒されるだけなので、レールに沿ってやればそれなりのものができるRailsは良いもの。

Dockerとは

Dockerはアプリケーションの実行環境を提供するソフトウェアである。
Dockerを語る上で欠かせないのがコンテナという概念だ。コンテナは小さいLinuxのようなものである。
コンテナに様々なアプリケーションを乗せて実行することができ、コンテナ同士は区切られているため環境を汚すことがない。

またDockerfileというファイルにコンテナを作成する手順を定義することができ、一度作ったコンテナは何度でも気軽に破壊、生成を繰り返すことができる。

アプリケーションは多数のコンテナが寄り集まって構成されることが多い。
複数の独立したコンテナを繋ぎ、1つのアプリとして成立させるのがオーケストレーションという考え方である。
オーケストレーションはここではDocker Composeというソフトを使う。

Docker-compose/DockerでRails環境構築

Dockerfileというファイルを作成し、以下を貼り付ける。
これがコンテナの設計図になる。
バージョン2.5のrubyが入ったコンテナをベースに、さらにnode.jsをインストールし、ローカルにあるGemfileをコンテナの中にコピーしてbundle installする、、、
みたいなことが書いてある。

FROM ruby:2.5
RUN apt-get update -qq && apt-get install -y nodejs
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp

# Start the main process.
CMD ["rails", "server", "-b", "0.0.0.0"]

webコンテナに渡すGemfileとGemfile.lockを作成。

$touch Gemfile Gemfile.lock

Gemfileの中身に以下を記述。Gemfile.lockは空ファイルでいい。

source 'https://rubygems.org'
gem 'rails', '~>5'

docker-compose.ymlを作成し、以下を貼り付け。

version: '3'
services:
  db:
    image: mysql:5.7.19
    environment:
      - MYSQL_ROOT_PASSWORD=root
    ports:
      - "3307:3306"
    volumes:
      - ./tmp/db:/var/lib/mysql
  web:
    build: .
    environment:
      RAILS_ENV: development
    command: bash -c "bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/myapp
      - bundle-data:/usr/local/bundle
    ports:
      - "3000:3000"
    depends_on:
      - db
volumes:
  bundle-data:

下記コマンドを実行。

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

volumesの設定がうまくいっていれば、railsお馴染みのファイルができているはず。

$ ls
app  config     db                  Dockerfile     Gemfile       lib  package.json  Rakefile   storage  tmp
bin  config.ru  docker-compose.yml Gemfile.lock  log  public README.md  test     vendor

Docker on Linuxの場合、rails newでできたファイルはroot所有となっているため、下記コマンドでユーザー所有に戻すらしい。

sudo chown -R $USER:$USER .

Gemfileが新しくなっているためリビルドする。
GemfileかDockerfileを弄った時は毎回リビルドする。

docker-compose build

config/database.ymlをmysqlコンテナに向ける。
docker-composeでdbコンテナを定義しているので、ホスト名はdbで名前解決できる。

default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: root
  host: db

webコンテナでrails db:createコマンドを叩く

docker-compose run web rails db:create

これでdocker-compose upすると、docker-compose.ymlのwebで定義したcommandが実行され、サーバーが立ち上がる

docker-compose up

ちなみにtmp/pids/のなかにserver.pidがあると排他制御に引っかかり、rails sが失敗する。

公式ドキュメントではentrypoint.shを追加してserver.pidを削除してからrails sするサンプルが載っているのでそちらも参考に。
https://docs.docker.com/compose/rails/

じゃあどうやって開発していくのか、みたいな記事をそのうち更新予定。

Dockerすらまともに動かない時の悲痛な叫びは下記に随時書いていく予定。
Docker for Windowsで困ったら