いけすの技術メモ

趣味開発etc.用の自己満ブログです

MENU

sinatraの開発環境をDockerfileを使って構築する。

今回も前回に引き続き、dockerで環境構築の学習を記しておく。 今回は主にDockerfileの作成手順についてフォーカスする。

前回、かなり適当に追記して動かしていたが、どうやら
コンテナの中に入る→作業する→うまくいってからDockerfileに記載
の手順を踏んだほうが良いらしいので、それに従って作業していくこととした。

目的

  • コンテナの中に入る→作業する→うまくいってからDockerfileに記載の手順でDockerfileを作成する
  • rubyフレームワークであるsinatraを用いて、ブラウザでトップページを表示する
$ 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をインストールする。 sinatrarailsより軽いフレームワークらしい。(へぇ〜)

# 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

f:id:IKDrocket:20210321222706p:plain

よしよし。

Dockerfileを書き換える(追加する)

うまく動いたので、さっき実行したコマンドをDockerfileに記載する。 CMDapp.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

やはり表示できた。 f:id:IKDrocket:20210321222706p:plain

まとめ

今回は、それほど詰まらなくてよかった!! 以下の動画に今回もお世話になりました。ありがとうございました。

www.youtube.com

ディレクトリ構成

.
├── 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