
背景
データの修正のために、ちょっとしたバッチを書くことになりました。環境はEC2でAmazon Linux2でした。
rbenvをインストールしようかなと思って準備をし、いざrubyをインストールしようとしたところで、gccが入っておらずコンパイルができないことに気がつきました…
いつもならyum install -y gccなど行うところですが、パッケージの追加もあまりしてほしくないということだったので、Dockerコンテナで実行することにしました。
Dockerfileの作成
まずはDockerfileを作成します。
EC2上に適当なディレクトリを作成して、その中にDockerfileを作成します。
1 | $ mkdir app |
ベースイメージの取得
それではDockerfileのFROMに記載するベースイメージを決めようと思います。
Docker image Rubyでググると、Rubyのオフィシャルイメージが見つかります。

以前Rubyコミッタの方が最新のバージョンを使うのが速度的には一番良いとおっしゃっていたので、最新の3.0.2を利用します。
Dockerfileつづき
先程のRubyのオフィシャルイメージのページの下の方を見ていくと、How to use this imageというセクションがあり、実際の利用方法が記載されています。
例に書いてあるのを倣って作成し一度ビルドしてみます。Dockerfileは以下のようになりました。
1 | $ cat Dockerfile |
Gemfileは今回必要となるデータベース(MySQL RDS)への接続と、その接続のための認証情報を取得するためのgemのみ記載しました。
1 | $ cat Gemfile |
イメージのビルド
ではこれでビルドします
1 | $ docker build -t my-ruby-app . |
Gemfile.lockはなかったですね。Dockerfileの7行目からGemfile.lockを削除して再実行します。
1 | $ docker build -t my-ruby-app . |
エラーになってしまいました。調べてみると、Dockerfileの3行目にある
1 | RUN bundle config --global frozen 1 |
で、GemfileやGemfile.lockの変更を禁止しているからのようです。
https://bundler.io/v2.2/man/bundle-config.1.html
その行を削除しても良いのですが、一般的にimageのビルドはそのビルドしたimageをデプロイして動作させるので、デプロイの一環でもあります。上記のbundlerのマニュアルにもある通り、--deploymentフラグを有効にすると、BUNDLE_FROZENもtrueになるようですし、Gemfile.lockはソースコード管理されているはずなので、Dockerfileはこのままでいきます。
Gemfile.lockの作成
ではGemfile.lockはどのように作成すれば良いでしょうか。
先程のDockerHubのページに作成方法が書いてありました。
1 | Generate a Gemfile.lock |
イメージのバージョンだけ現在の3.0.2に合わせて実行してみます。
1 | $ docker run --rm -v "$PWD":/usr/src/app -w /usr/src/app ruby:3.0.2 bundle install |
無事Gemfile.lockが作成できました。
再ビルド
ではもう一度ビルドしてみます。
1 | $ docker build -t my-ruby-app . |
イメージを確認します
1 | $ docker images | grep -i ruby-app |
ちょっとサイズが大きい気がしますが、ビルドできました。
スクリプトの実行
では実行します。なにも指定しなければ、Dockerfileで最後に記述したコマンドが実行されます。
1 | $ docker run my-ruby-app |
実行ログなどを出力したい場合は、Gemfile.lockを作成した時のようにログを置くディレクトリを-vでマウントします。
test.rb
1 | require 'dotenv' |
1 | $ docker run -v "$PWD":/usr/src/app my-ruby-app |
無事書き込みできていました。
まとめ
環境を変更することなく実行できるコンテナの長所を利用するといろんなことができるようになると思います。
これからはなにかを行うにしても1から実行環境を整えることもなくなりそうですね。便利な世の中になりました。






