Dockerfile 応用

1. 作業ディレクトリと、Gemfile、Dockerfileを作成。

cd 作業ディレクトリ

.
├── Dockerfile
└── src
    └── Gemfile

src/Gemfile

ちなみにGemfileとは、gemが記述されているファイルのことです。gemのバージョン管理を行うものです。

# frozen_string/literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}"}

gem "sinatra"

sinatra」はRuby on Rails よりもかなりライトなRuby用Webアプリケーションフレームワーク

これを、Rubyのパッケージ管理ツールであるgemを利用して使用する設定となっている。

Dickerfile

FROM ruby:2.7

WORKDIR /var/www

COPY ./src /var/www

CMD ["/bin/bash"]

dockerのイメージを作成するための雛形。.srcフォルダの内容をコピーして、Docker環境の/var/wwwディレクトリに貼り付けている。コマンドでbashを利用できるようにしている。

2. イメージを作成

 docker image build -t sample/sinatra:latest .

3. コンテナを起動

docker container run -it -p 4567:4567 --name sinatra -v ${PWD}/src:/var/www sample/sinatra:latest
  • itオプションをつけておくと、インタラクティブモードが使えて、bashがそのまま実行できるようになる。

4567はsinatraがデフォで持っているポート番号なのでそのまま利用。

ソースコードの共有は -v以降。

  • vはボリュームのオプション、という意味。

${PWD}/srcが自分のバソコン側(自分のホスト側)、/var/www

がdockerのディレクトリ。

意味は、自分の現在のソースディレクトリを、dockerの/var/wwwに同期させるよ・共有するよ、という意味。

こうすることで、現在のソースディレクトリの中身を、docker内の指定のディレクトリへ共有される形になる。

これをやらないと、毎回毎回「イメージ」を作り直さないと反映されなくなる。よって、こうして、ローカルのコードを修正かけても、docker側のコードも修正させるという仕組みが大切。

sample/sinatra:latest で、コンテナに名前をつける、ということ。

すると

root@f69217114e62:/var/www#

とターミナルのディレクトリを示すところが変化。

dockerのコンテナが作成され実行され、設定していたbashのコマンドが起動した、ということになる。プラス、-itも指定していたので、そのまま使用中のターミナルでbashでコマンドが実行できることになる。

試しに

ls
cat Gemfile
pwd

などで確認すると、srcディレクトリの内容がそのまま確認できる=同期されていることがわかる。

では、gemのライブラリをインストールする。

以下をbashコマンドで実行。

(あまりこの命令文の中身は深く考えなくて大丈夫)

#ライブラリをインストールするディレクトリを指定
bundle config --local set path 'vendor/bundle'

bundle install

動かす対象のアプリケーションのコードを書いていく。

app.rb

require "sinatra"

configure do
  set :bind, '0.0.0.0'
end

get '/' do
  'Hello world!'
end

ではbundleコマンドでapp.rbを立ち上げてみる。

bundle exec ruby app.rb

>>
[2023-02-22 04:25:26] INFO  WEBrick 1.6.1
[2023-02-22 04:25:26] INFO  ruby 2.7.7 (2022-11-24) [x86_64-linux]
== Sinatra (v3.0.4) has taken the stage on 4567 for development with backup from WEBrick
[2023-02-22 04:25:26] INFO  WEBrick::HTTPServer#start: pid=41 port=4567
172.17.0.1 - - [22/Feb/2023:04:26:47 +0000] "GET / HTTP/1.1" 200 12 0.0029
172.17.0.1 - - [22/Feb/2023:04:26:47 UTC] "GET / HTTP/1.1" 200 12

すると、このようにサーバーが4567ポートで立ち上がったので、

localhost:4567でアクセスしてみると、hello,world! が表示されている。

■ここまでの流れをもう一歩、コンパクトにまとめる

Dickerfileを編集

FROM ruby:2.7

WORKDIR /var/www

COPY ./src /var/www

# 追記
RUN bundle config --local set path 'vendor/bundle' \
 && bundle install

CMD ["/bin/bash"]

長くなったところは、「\」で改行でき、「&&」で「RUN 〜」が2行になったのを1行にまとめることができる。

Control + C で起動中サーバーを終了。

exit

で一度dockerの中から抜け出す。

コンテナを削除

docker container rm sinatra

(残っていたら)イメージを削除

docker rmi sample/sinatra

イメージを作り直す

docker image build -t sample/sinatra:latest .

コンテナを作り直す。

今回はbashを利用しないので、インタラクティブモードにする必要がないので、「-it」パラメーターは削除。

すると、サーバーが立ち上がる。

docker container run -p 4567:4567 --name sinatra -v ${PWD}/src:/var/www sample/sinatra:latest

>>
[2023-02-22 06:04:10] INFO  WEBrick 1.6.1
[2023-02-22 06:04:10] INFO  ruby 2.7.7 (2022-11-24) [x86_64-linux]
== Sinatra (v3.0.4) has taken the stage on 4567 for development with backup from WEBrick
[2023-02-22 06:04:10] INFO  WEBrick::HTTPServer#start: pid=1 port=4567

念の為ブラウザでlocalhost:4567 を確認。