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