sinatraの開発環境をDockerfileを使って構築する。
今回も前回に引き続き、dockerで環境構築の学習を記しておく。 今回は主にDockerfileの作成手順についてフォーカスする。
前回、かなり適当に追記して動かしていたが、どうやら
コンテナの中に入る→作業する→うまくいってからDockerfileに記載
の手順を踏んだほうが良いらしいので、それに従って作業していくこととした。
目的
$ mkdir sinatra_app $ cd sinatra_app/ $ mkdir src $ touch src/Gemfile $ touch src/app.rb $ touch Dockerfile
ディレクトリ構成
. ├── Dockerfile └── src ├── Gemfile ├── Gemfile.lock ← 後で勝手に生成される └── app.rb
Gemfile
今回はGemfileでsinatra
をインストールする。
sinatra
はrails
より軽いフレームワークらしい。(へぇ〜)
# frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem "sinatra"
Dockerfile
WORKDIR
を指定することで中に入ったときのカレントディレクトリを指定できるみたい。
あと、CMD ["/bin/bash"]
でコンテナ実行でコンテナ内のbashにアクセスできると。
FROM ruby:3.0 WORKDIR /var/www COPY ./src /var/www CMD ["/bin/bash"]
app.rb
前回webrick
を使ったスクリプトより簡素で直感的なスクリプトだな〜と思った。
require 'sinatra' configure do set :bind, '0.0.0.0' end get '/' do 'Hello world!' end
イメージの作成・起動
一通り、ファイルが揃ったので、dockerのイメージを作成してみる。
$ docker image build -t sample/sinatra:latest .
問題なく、作成できた。
では、コンテナを作成・起動!!
ポートはsinatra
だとデフォルトは4567らしいのでそのまま指定。
今回は、コンテナ内の/var/www
と/src
をマウントした。
これによって、Gemfileなどを書き換えたときに再びdocker build
でイメージを作成し直さなくてもよくなるらしい。
便利!!
また、-it
を追加すると、コンテナの起動と同時にコンテナ内に入れるとのこと。
$ docker container run -it -p 4567:4567 --name sinatra -v ${PWD}/src:/var/www sample/sinatra:latest
これでコンテナの中のbashを起動できた。
ので、bundle install
でGemfileの内容をインストール。
root@3922a38386d9:/var/www# bundle config --local set path 'vendor/bundle' root@3922a38386d9:/var/www# bundle install Fetching gem metadata from https://rubygems.org/.... Resolving dependencies... Using bundler 2.2.3 Fetching ruby2_keywords 0.0.4 Fetching rack 2.2.3 Installing ruby2_keywords 0.0.4 Installing rack 2.2.3 Fetching tilt 2.0.10 Installing tilt 2.0.10 Fetching mustermann 1.1.1 Fetching rack-protection 2.1.0 Installing rack-protection 2.1.0 Installing mustermann 1.1.1 Fetching sinatra 2.1.0 Installing sinatra 2.1.0 Bundle complete! 1 Gemfile dependency, 7 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed.
できたっぽいので、さっそくwebサーバーを起動してみると・・・
root@3922a38386d9: /var/www# bundle exec ruby app.rb /usr/local/bundle/gems/sinatra-2.1.0/lib/sinatra/base.rb:1755:in `detect_rack_handler': Server handler (thin,puma,reel,HTTP,webrick) not found. (RuntimeError) from /usr/local/bundle/gems/sinatra-2.1.0/lib/sinatra/base.rb:1493:in `run!' from /usr/local/bundle/gems/sinatra-2.1.0/lib/sinatra/main.rb:45:in `block in <module:Sinatra>'
は?
となったところで、前回起きたことを連想しながらググってみたところやはりwebrick
がruby3.0からデフォルトで入っていないことが原因だった。
sinatra
だけでは動かないのね。
ということで、Gemfileにgem "webrick"
を追加。
再び、実行してみると、
root@3922a38386d9: /var/www# bundle exec ruby app.rb [2021-03-21 13:12:08] INFO WEBrick 1.7.0 [2021-03-21 13:12:08] INFO ruby 3.0.0 (2020-12-25) [x86_64-linux] == Sinatra (v2.1.0) has taken the stage on 4567 for development with backup from WEBrick [2021-03-21 13:12:08] INFO WEBrick::HTTPServer#start: pid=70 port=4567 172.17.0.1 - - [21/Mar/2021:13:12:29 +0000] "GET / HTTP/1.1" 200 12 0.0216 172.17.0.1 - - [21/Mar/2021:13:12:29 UTC] "GET / HTTP/1.1" 200 12 - -> / 172.17.0.1 - - [21/Mar/2021:13:12:29 +0000] "GET /favicon.ico HTTP/1.1" 404 469 0.0071 172.17.0.1 - - [21/Mar/2021:13:12:29 UTC] "GET /favicon.ico HTTP/1.1" 404 469 http://localhost:4567/ -> /favicon.ico
よしよし。
Dockerfileを書き換える(追加する)
うまく動いたので、さっき実行したコマンドをDockerfileに記載する。
CMD
もapp.rb
を実行するように書き換える。
FROM ruby:3.0 WORKDIR /var/www COPY ./src /var/www # 追加 RUN bundle config --local set path 'vendor/bundle'\ && bundle install # 追加 CMD ["bundle", "exec", "ruby", "app.rb"] # 削除 #CMD ["/bin/bash"]
ということで、一度コンテナから抜けて、イメージを作り直す。
root@3922a38386d9:/var/www# exit exit $ docker rm sinatra sinatra $ docker image build -t sample/sinatra:latest . [+] Building 9.2s (9/9) FINISHED => [internal] load build definition from Dockerfile 0.1s => => transferring dockerfile: 231B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/ruby:3.0 0.0s => [internal] load build context 0.0s => => transferring context: 121B 0.0s => [1/4] FROM docker.io/library/ruby:3.0 0.0s => CACHED [2/4] WORKDIR /var/www 0.0s => CACHED [3/4] COPY ./src /var/www 0.0s => [4/4] RUN bundle config --local set path 'vendor/bundle' && bundle install 8.3s => exporting to image 0.4s => => exporting layers 0.4s => => writing image sha256:459c4bd2f174ea1f7837279ec43165b9ed83e3a47502cda1910cfa1dedc33266 0.0s => => naming to docker.io/sample/sinatra:latest 0.0s
そして再び、コンテナ作成・起動!!
今回はコンテナに入る必要はないので、-it
は不要。
$ docker container run -p 4567:4567 --name sinatra -v ${PWD}/src:/var/www sample/sinatra:latest [2021-03-21 13:56:15] INFO WEBrick 1.7.0 [2021-03-21 13:56:15] INFO ruby 3.0.0 (2020-12-25) [x86_64-linux] == Sinatra (v2.1.0) has taken the stage on 4567 for development with backup from WEBrick [2021-03-21 13:56:15] INFO WEBrick::HTTPServer#start: pid=1 port=4567
やはり表示できた。
まとめ
今回は、それほど詰まらなくてよかった!! 以下の動画に今回もお世話になりました。ありがとうございました。
ディレクトリ構成
. ├── Dockerfile └── src ├── Gemfile ├── Gemfile.lock └── app.rb
Gemfile
# frozen_string_literal: true source "https://rubygems.org" git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } gem "webrick" gem "sinatra"
Dockerfile
FROM ruby:3.0 WORKDIR /var/www COPY ./src /var/www RUN bundle config --local set path 'vendor/bundle'\ && bundle install CMD ["bundle", "exec", "ruby", "app.rb"]
app.rb
require 'sinatra' configure do set :bind, '0.0.0.0' end get '/' do 'Hello world!' end