モチベーション
Rackを知るために、小さなRackアプリケーションを動かしてみたいです。
Rubyは気軽にgem installすると環境が汚れるのでsandboxが欲しいです。
そこでdockerを使ってみます。
ベースにするDokerfile
library/ruby - Docker Hubのruby:2.4-alpine
を使います。
事前に必要なもの
- my_rack_app.rb
- Gemfile
my_rack_app.rb
Rack: a Ruby Webserver Interfaceのサンプルを元に修正します。
shebang
を設定します。
my_rack_app.rb
#! /usr/bin/env ruby
require 'rack'
app = Proc.new do |env|
['200', {'Content-Type' => 'text/html'}, ['A barebones rack app.']]
end
Rack::Handler::WEBrick.run app, {Host: '0.0.0.0'}
Perl, Python 及び Ruby スクリプトにおける正しいshebangの書き方 - Qiita
shebangを設定しないと
こんなエラーが出ます。
panic: standard_init_linux.go:175: exec user process caused "exec format error" [recovered]
panic: standard_init_linux.go:175: exec user process caused "exec format error"
goroutine 1 [running, locked to thread]:
panic(0x88f8a0, 0xc820126d20)
/usr/local/go/src/runtime/panic.go:481 +0x3e6
github.com/urfave/cli.HandleAction.func1(0xc8200f32e8)
/tmp/tmp.n151sEscRu/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/urfave/cli/app.go:478 +0x38e
panic(0x88f8a0, 0xc820126d20)
/usr/local/go/src/runtime/panic.go:443 +0x4e9
github.com/opencontainers/runc/libcontainer.(*LinuxFactory).StartInitialization.func1(0xc8200f2bf8, 0xc82001a0c8, 0xc8200f2d08)
/tmp/tmp.n151sEscRu/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/factory_linux.go:259 +0x136
github.com/opencontainers/runc/libcontainer.(*LinuxFactory).StartInitialization(0xc820059630, 0x7fbe739ea728, 0xc820126d20)
/tmp/tmp.n151sEscRu/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/factory_linux.go:277 +0x5b1
main.glob.func8(0xc820076a00, 0x0, 0x0)
/tmp/tmp.n151sEscRu/src/github.com/opencontainers/runc/main_unix.go:26 +0x68
reflect.Value.call(0x7f45a0, 0x9a4d88, 0x13, 0x8ebac8, 0x4, 0xc8200f3268, 0x1, 0x1, 0x0, 0x0, ...)
/usr/local/go/src/reflect/value.go:435 +0x120d
reflect.Value.Call(0x7f45a0, 0x9a4d88, 0x13, 0xc8200f3268, 0x1, 0x1, 0x0, 0x0, 0x0)
/usr/local/go/src/reflect/value.go:303 +0xb1
github.com/urfave/cli.HandleAction(0x7f45a0, 0x9a4d88, 0xc820076a00, 0x0, 0x0)
/tmp/tmp.n151sEscRu/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/urfave/cli/app.go:487 +0x2ee
github.com/urfave/cli.Command.Run(0x8ee970, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x984240, 0x51, 0x0, ...)
/tmp/tmp.n151sEscRu/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/urfave/cli/command.go:191 +0xfec
github.com/urfave/cli.(*App).Run(0xc820001800, 0xc82000a100, 0x2, 0x2, 0x0, 0x0)
/tmp/tmp.n151sEscRu/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/urfave/cli/app.go:240 +0xaa4
main.main()
/tmp/tmp.n151sEscRu/src/github.com/opencontainers/runc/main.go:137 +0xe24
Rackアプリケーションの起動時に引数を追加
{Host: '0.0.0.0'}
を追加します。
Rack::Handler::WEBrick.run app, {Host: '0.0.0.0'}
Rack 1.6 からは、明示的に指定しない限り localhost のみを listen するような変更が加わった
オプションはHost
で指定します。
ホストで実行権限を設定します。
chmod +x my_rack_app.rb
実行権限を設定しないと
こんなエラーがでます。
docker: Error response from daemon: invalid header field value "oci runtime error: container_linux.go:247: starting container process caused \"exec: \\\"./my_rack_app.rb\\\": permission denied\"\n".
Gemfile
rackだけ入れます。
source 'https://rubygems.org'
gem 'rack'
Dockerfile
FROM ruby:2.4-alpine
COPY Gemfile /
RUN bundle install --clean
COPY my_rack_app.rb /
CMD ["./my_rack_app.rb"]
実行
docker build -t my-ruby-app .
docker run --rm -p 8080:8080 my-ruby-app
--rm
をつけて、終了時にコンテナを破棄します。
-p
をつけて、ホストのポートにマッピングします。
外部ネットワークからコンテナにアクセスするには,コンテナを起動するときに外部ポートをdocker0に晒した内部portにマップする必要がある
動作確認
curlコマンドで動作確認します。
curl localhost:8080
で
A barebones rack app.
が、帰ってきます。