目的
この記事では、軽量のDocker Imageを生成するDockerfileを作成する手順を書いていきます。
余談
有名な仮想化ソフトとして、Virtual Box(+ Vagrant)がありますが、以下のような問題点があります。
- 仮想マシン起動が遅い
- イメージの容量が大きい
- 2GBとか
勿論、Virtual Boxは、ホストOS(PC)の中にそのままOSを立ち上げるため、ネットワーク周り等扱いやすいと言えば扱いやすいのですが、仮想マシン立ち上げ時に時間がかかったり、ほかの人と同じ環境を共有する際、2GBのイメージを交換したりするのは大変です。
そこで、Dockerという仮想化ソフトの出番ですが、実際に使ってみると初心者は特に、以下の課題が発生するかと思います。
- Docker Imageが1GBを超える
仮想環境のイメージを共有する際、Virtual Boxとは異なり、Imageを生成するためのテキストで記述されたDockerfileを使用することに関しては、イメージ共有を効率化するのですが、何も考えずイメージを作成していしまうと、1GBのイメージになってしまい、それなりにリソースを食います。
やはり、かっこいいのは、軽量化されたイメージだと思うので、今回は自分で目的に沿ったイメージを作成したいと思います。
開発環境
今回のDocker Imageは、以下の環境で作成/テストを行います。
- OS: Windows 10
- Docker: Docker Toolbox version 19.03.1
Dockerfileの作成
ゴール
Ruby on RailsのWebアプリケーション(rails newした初期アプリ)が入っているDocker Imageを生成するDockerfileを作成します。
ハードウェア容量が少ないサーバー等に需要があるかと思います。
また、Docker Imageを共有するときも、軽い方がImageの生成が素早くていいと思います。
作成するDocker Image
Ruby公式の軽量イメージのalpineイメージ
を使用します。
このalpineイメージ、最小のソフトしかインストールされていない為、Ruby on Railsのアプリケーション起動に必要なソフトをインストールしながらDockerfileを作成します。
インストールするアプリケーションのバージョンは、以下です。
- Ruby: 2.6.5
- Ruby on Rails: 6.0.1
Dockerfileの作成手順
Dockerfileを作成するの手順は以下の様に行います。
- ベースイメージのPull
- ベースコンテナの立ち上げ
- コンテナ内で必要ソフトのインストール
- Dockerfileの作成
- Dockerfileの実行
地道な作業になりますが、やる気をそがれず、後戻りせず行うためには、上記のような手順になるかと思います。
それでは、実際にイメージを作成していきます。
Dockerはインストールするされていることが前提で解説をします。
1.ベースイメージのPull
以下のコマンドでベースとなるDocker Imageをローカルにダウンロードします。
どのバージョンのRubyイメージがあるかは、公式HPのDescription
タブに記述があります。
docker pull ruby:2.6.5-alpine3.10
2.ベースコンテナの立ち上げ
以下のコマンドで、Pullしたイメージを使用し、コンテナを立ち上げます。
docker run -it ruby:2.6.5-alpine3.10 /bin/ash
alpineイメージでは、bash
は使用できないため、/bin/ash
を指定して実行します。
3.コンテナ内で必要ソフトのインストール
コンテナ内でRailsアプリケーションを立ち上げるために必要なソフトをインストールします。
インストールしたソフトやコマンドに関しては、Dockerfileまたはメモに書き残します。
エラーが発生した場合、エラー文を読んだり、検索したりして対処を行います。
また、コマンド実行後に、y/n
の選択肢が出る場合は、記録を行い、Dockerfileでは-y
などのオプションをつけて記述していきます。
今回は、railsをインストールして、必要なパッケージをインストールする方法をとりました。
コンテナ内で実行したコマンド
/ # apk update
/ # apk add yarn nodejs
/ # gem install bundler
/ # gem install rails <- C compilerなどがなく エラー
/ # apk add gcc
/ # apk add g++
/ # apk add make
/ # gem install rails <- 成功
/ # mkdir app
/ # cd app
/ # rails new . <- sqlite3がなくエラー
/ # apk add sqlite-dev
/ # rails s
... <- rails sができるまで試す
apk update
apk add yarn nodejs
gem install bundler
apk gcc g++ make
apk add sqlite-dev
...
4.Dockerfileの作成
3でメモしたコマンドを元に、Dockerfileを作成します。
作成したDockerfileが以下です。
FROM ruby:2.6.5-alpine3.10
ENV APP_HOME /app
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
ADD . $APP_HOME
RUN apk update \
&& apk add --no-cache gcc g++ make sqlite-dev yarn nodejs \
&& gem install bundler \
&& bundle install \
&& yarn install
EXPOSE 3000
CMD ["rails", "s", "-b", "0.0.0.0"]
5.Dockerfileの実行
4.で作成したDockerfileを実行します。
railsのアプリケーションディレクトリの中に、Dockerfileを置き、イメージを生成します。
ディレクトリは以下のような構成になります。
app/
├ Dockerfile
├ bin/
├ config.ru
├ Gemfile
├ Gemfile.lock
├ lib/
├ node_modules/
├ postcss.config.js
├ Rakefile
├ storage/
├ tmp/
├ yarn.lock
├ babel.config.js
├ config/
├ db/
├ log/
├ package.json
├ public/
├ README.md
├ test/
└ vendor/
また、4.でrails s
を実行した際に、Please add gem 'tzinfo-data' to your Gemfile and run bundle install
といったエラーが出たので、ホストOSのGemfileを変更します。
- (修正前) gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
+ (修正後) gem 'tzinfo-data'
以下のコマンドでDockerfileをビルドします。
docker build -t rails-app .
作成したイメージを使用して上手くコンテナが起動できない場合は、以下のコマンドを使用して、ログを確認しつつ、エラーを解消していきます。
docker logs <コンテナID>
作成したイメージからコンテナを立ち上げ、ブラウザなどから、Railsアプリケーションの起動が確認できれば終了です。
docker run -d -p 3000:3000 rails-app
curl http://192.168.99.100:3000
公式イメージとの比較
Rubyの公式イメージにrailsをインストールしたDocker Imageと比較しました。
イメージ名 | 容量 |
---|---|
rails-app | 649MB |
ruby(公式) | 1.29GB |
容量はあくまでも参考にしてください。
そもそも、Rubyの公式イメージ自体、840MBあるので、今回作成したイメージが軽量化されていることがわかります。
docker-composeを使用して、ホストOS側のアプリケーションディレクトリをマウントすると、もっとイメージ自体の容量が少なくなります。
Macを使用して、ホストOSからエディタで開発をする場合はdocker-composeを使用した方がいいかもしれません。
ポイントとしては、rails new .
をするまでの過程の中で、必要最低限のものしかインストールしない事だと思います。
例えば、alpine-sdk
をインストールすれば、gccやmakeがインストールできるのですが、その他gitやcurlなど必要のない物もインストールされてしまいます。
なので、gem install rails
やbundle install
した際にエラーが出て、インストールが必要なものだけ入れるのが良いと思います。
また、今回使用したruby:2.6.5-alpine3.10
には、vi
が入っていたので、この辺りも削除するとよいと思います。