Qiitaの記事前回の試行錯誤の続きです。

gemを足すたびにイメージを作り直すのはやっぱりどうもしっくりこなかったので、アプローチを変えました。 まず、以下のような単独のdockerfileを用意して自前のイメージ(lm-ruby)を作ります。

Herokuで動かしやすくするため、postgresqlも入れてます。あとはお好みで…。

# Alpine image (mainly)for Rails project.
FROM ruby:2.7.2-alpine3.12

RUN apk update && apk upgrade \
  && apk add --no-cache build-base \
    postgresql-client postgresql-dev \
    imagemagick6 imagemagick6-dev imagemagick6-c++ readline-dev \
    sqlite-dev nodejs tzdata \
  && gem update \
  && gem install rails -v '~> 5.2' -N \
  && gem install pg rmagick sassc sqlite3 -N

# RUN apk add --no-cache mysql-client mysql-dev && gem install mysql2
# RUN apk add --no-cache yarn  # for Rails 6
# RUN apk add bash  # for Debug

WORKDIR /home

以下のようなコマンドでイメージを作成します。

docker build --tag lm-ruby . -f lm-ruby-alpine

このイメージが準備できた状態で、以下のようなdocker-compose.ymlを作成します。

version: '3.8'
services:
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: secret
    volumes:
      - ./tmp/postgresql/data:/var/lib/postgresql/data
  web:
    image: lm-ruby
    command: sh -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - ./:/home
      - bundle:/usr/local/bundle
    ports:
      - "3000:3000"
    depends_on:
      - db
volumes:
  bundle:

docker-compose.ymlを置いたフォルダで以下のコマンドを実行すると、railsのプロジェクトが生成されます。

docker-compose run web rails new . --database=postgresql --skip-git

config/database.ymlを調整してdbイメージに接続するようにします。 Gemfileも(放っておくと色々警告が出るので)編集が必要かもしれません。 その後、データベースの作成コマンドを実行して、upすると、Railsの初期ページが見えるはずです!

docker-compose run web rails db:create
docker-compose up

http://localhost:3000

bundlerがインストールするgemをvolumeに切り出して永続化しているところがポイントです。 ただこのパスがプラットフォームごとに異なるので、alpine以外のイメージを利用する場合はこのままでは動かないと思います(動くように見えるけど、 dockerを再起動するとgemが毎回消えてしまいます)。余談ですが、alpineって確かにベースは小さいけど、色々足すと結局同じようなサイズに落ち着きますよね…。似た構成でubuntuをベースにしたイメージと2MBしか変わりませんでした(alpine: 797MB,ubuntu: 799MB)。