3行
- Rails アプリの開発において、手元の開発環境では Rails アプリのみをホストマシン上で実行、MySQL や Redis などのミドルウェア類は Docker コンテナ (Docker for Mac) 上で実行するという構成が好き
- Rails アプリで MiniMagick を使おうとすると Rails アプリを実行している環境に ImageMagick をインストールする必要があるが、開発するアプリケーションによって利用したいバージョンが異なるかもしれないし、開発者の OS によってインストールの手順も異なったりするし、そもそもローカルマシンの環境を汚したくない
- ImageMagick をインストールした Docker コンテナを用意し、MiniMagick gem からそれを利用させるようにした
実装
ディレクトリ構成
ふつうの Rails アプリの構成に、アプリケーションを実行するスクリプト dev/start
と docker-compose.yml
を追加し、MiniMagick が Docker コンテナを利用するための設定として config/initializer/minimagick.rb
を追加している。
. ├── app ︙ └── config │ └── initializers │ └── minimagick.rb ├── dev │ └── start ├── docker-compose.yml └── tmp └── images
config/initializers/minimagick.rb
MiniMagick は内部でシステムの ImageMagick コマンドを実行しているがそのコマンドに prefix を付加できるオプションが用意されており、ここに docker exec <コンテナ名>
を指定することで MiniMagick から Docker コンテナの ImageMagick を利用するようにしている。
https://github.com/minimagick/minimagick/blob/d484786f35e91f107836d3c86aca61d50a35820b/lib/mini_magick/tool.rb#L126
require "mini_magick" if Rails.env.development? ::MiniMagick.configure { |config| config.cli = :imagemagick config.cli_prefix = %w[docker exec imagemagick] } end
docker-compose.yml
MySQL 等のミドルウェアと一緒に ImageMagick 用のコンテナも立てるようする。このコンテナは立ちっぱなしにしておいて、docker exec imagemagick <ImageMagickコマンド>
のように実行するようにしている。ImageMagick が入った Docker イメージは Docker Hub で適当に検索して出てきたやつを使った https://hub.docker.com/r/v4tech/imagemagick
MiniMagick は扱う画像ファイルの置き場所に Dir.tmpdir
、つまり Linux では環境変数 TMPDIR
で指定されたディレクトリを利用するので、ホストマシンのそのディレクトリを imagemagick コンテナにマウントして共有する必要があり、volumes
にその旨を記述している。
version: '3.7' services: db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: hoge MYSQL_USER: hoge ports: - "3307:3306" imagemagick: container_name: imagemagick image: v4tech/imagemagick volumes: - $TMPDIR:$TMPDIR tty: true command: "/bin/ash"
dev/start
環境変数 TMPDIR
にパスを指定しつつコンテナ群と Rails アプリを起動するスクリプト。
#!/bin/sh -eu SCRIPT_DIR=$PWD/$(dirname $0) ROOT_DIR=$SCRIPT_DIR/.. TMPDIR="$ROOT_DIR/tmp/images" # imagemagick コンテナと共有するために TMPDIR のパスを明示的に指定 docker-compose up -d bin/rails server
以上の実装で MiniMagick は Docker コンテナ内の ImageMagick を利用するようになり、ローカルマシンに ImageMagick をインストールせずに済む ☺️
なおこれは Rails アプリをホストマシンで動かしたい開発環境に限った話で、本番環境で Rails アプリを Docker コンテナとして実行している場合は普通にそのコンテナに ImageMagick をインストールしていればよい。