2018年4月30日月曜日

docker-compose を使って Sinatra を nginx 配下で動かす方法

概要

nginx を挟んでいたほうが何かと便利なので試してみました
最終的には docker-compose で nginx と Sinatra が上がってきます

$ tree . -I vendor
.
├── Dockerfile.web
├── Gemfile
├── Gemfile.lock
├── app.rb
├── config.ru
├── docker-compose.yml
└── nginx.conf

環境

  • macOS 10.13.4
  • docker-compose 18.04.0-ce

Sinatra アプリの作成

  • vim config.ru
require './app.rb'
run MyApp
  • vim app.rb
require 'sinatra/base'

class MyApp < Sinatra::Base
  get '/' do
    request.host
  end
end

アプリはリクエストのホストヘッダを返すだけです

  • vim Dockerfile
FROM ruby

ADD . /home
WORKDIR /home
RUN bundle install --path vendor

CMD ["bundle", "exec", "rackup", "config.ru", "-o", "0.0.0.0"]

nginx.conf の作成

今回の肝の部分かと思います

  • vim nginx.conf
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    upstream app {
        server web:9292; 
    }

    server {
        listen       80;
        server_name  localhost;

        location / {
            proxy_pass http://app;
            proxy_set_header Host $host;
        }
    }
    include servers/*;
}

ポイントは proxy_set_header Host $host; です
これがないと Sinatra で 404 エラーが発生した際に正常に表示されません
Sinatra はリクエストされた Host ヘッダを見て画像などの情報を取得します
もし上記の nginx.conf の設定がない場合 Host 情報が app となってしまい画像などを取得しにいくサーバも http://app となり正常に取得できません

なので Host ヘッダをちゃんと設定することで Sinatra が正常に画像などを取得できるようにします

docker-compose.yml の作成

  • vim docker-compose.yml
version: '2'
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile.web
    expose:
      - "9292"
  proxy:
    image: nginx
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    links:
      - "web"

作成した nginx.conf を volumes を使って nginx コンテナ内の nginx.conf に上書きします
web 側のポート解放はホスト側の解放は不要なので expose を使っています
直接ホストから Sinatra にアクセスしたいのであれば ports を使うと良いと思います

動作確認

  • docker-compose up -d

で起動しましょう
nginx と Sinatra が上がってきます
nginx 側にアクセスすれば良いのです http://localhost にアクセスしましょう
するとそのまあプロキシして Sinatra アプリの情報が表示されると思います
また、http://localhost/hoge などにアクセスしてもちゃんと Sinatra のエラー画面が表示されることが確認できると思います

最後に

nginx + Sinatra を docker-compose で動かしてみました
今回 upstream を使っていますがなくても大丈夫です
将来的にアプリをポート分散などさせたい場合は upstream を定義したほうが良いかと思います

nginx を入れた理由としては同一マシン内で別アプリを動かした際に nginx でルーティングすることができるのと、同一マシンに別のドメインを振って VirtualHost の server_name でバランシングできることかなと思います
単一ホストだけで動作させている場合などには必須の構成かなと思います

ただこの構成にすることで nginx の管理、チューニングをする必要が出てくるのでそれはそれで面倒かなとも思います

0 件のコメント:

コメントを投稿