Posted at

docker-composeでresponderを動かしてみた


概要

responderの超簡単な動作環境を作成しました。


環境


  • Docker 18.09.1

  • docker-compose 1.23.2

  • Python 3.7

  • responder 1.2.0


手順


ディレクトリ構成

ディレクトリ構成は非常にシンプル

root/

 ├ app/
 │ ├ Dockerfile
 │ ├ requirements.txt
 │ ├ app/
 │  └ sample.py
 └ nginx/
 ├ conf.d/
 │ └ app.conf
 └ nginx.conf/

各種ファイルの説明は順次行います。


docker-compose.yml

docker-compose.ymlを記載します。

今回は最小構成ということで、dbも無いシンプルな構成です。


docker-compose.yml

version: '3.4'

services:
nginx_proxy:
hostname: nginx_proxy
image: nginx:latest
ports:
- "80:80"
volumes:
- "./nginx/nginx.conf:/etc/nginx/nginx.conf"
- "./nginx/conf.d:/etc/nginx/conf.d"
responder:
hostname: responder
build:
context: "./responder"
image: "responder"
expose:
- "80"
command: /bin/sh -c "python /root/app/sample.py"
volumes:
- "./responder/app:/root/app"



Dockerfile(responder)

responderを可動させるイメージを作成します。

とは言ってもほぼPython3のイメージです。

ASGIはgunicornとかもインストールが必要なのかと思いましたが、uvicornを使用するそうなので不要とのこと。

後々はDB連携もさせたいですね。


Dockerfile

FROM python:3.7

MAINTAINER neight

ENV PYTHONUNBUFFERED 1
COPY requirements.txt /opt/app/
RUN pip install --no-cache-dir -r /opt/app/requirements.txt

WORKDIR /root



requirements.txt

responder==1.2.0



nginx

nginxを使用してリバースプロキシを行います。

このあたりも特に変わったことはしていないです。


nginx.conf

user  nginx;

worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

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

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;
#tcp_nopush on;

keepalive_timeout 65;

#gzip on;

include /etc/nginx/conf.d/*.conf;
}



app.conf

server {

listen 80;
server_name localhost;

location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://responder/;
}
}



sample code

responderの簡単なサンプルコードです。

公式の説明との違いはIPとPortの指定を行っています。

デフォルトだと127.0.0.1:5042となります。


sample.py

import responder

api = responder.API()

@api.route("/")
def hello_world(req, resp, *, hoge):
resp.text = "hello, world!"

if __name__ == '__main__':
# ここだけ違う
api.run(address='0.0.0.0', port=80)



起動

起動はdocker-composeを使用してupすれば終わりですね。


bash

$ docker-compose up -d


この状態でブラウザよりlocalhostにアクセスすれば確認できると思います。

お疲れ様でした。


responderの感想

自分はPythonのフレームワークはDjangoしか使用したことがなかったので、これを機にflaskfalcomも使用してみました。

4つのフレームワークを比較した感想としては、


  • DjangoはWebサイトを作成するのに特化しているのに対し、他3つはJSONを返す様なAPI作成に向いている(気がする)

  • フレームワーク全体が非常にシンプル(ミニマム)である

  • responderは書き方に統一感がある、かつ、flascとfalconの良いところを取り込んでいる(作者の意図通り?)

  • responderを使用する際は、responderについて調べるというよりも構成ライブラリについて調べるという流れになりそう

  • 非同期処理が簡単にかけるのはresponderの強力な長所

他にも、GraphQLも簡単に取り扱えるそうですが、筆者は詳しくないので割愛。


まとめ

responder良いですね。

筆者はPython初心者でシンタックスシュガーあたりで少し戸惑いましたが、それ以外はシンプルでわかりやすく簡潔に書けるのが非常に好印象です。

Pythonのフレームワーク戦争で勝ち残ってほしい一品です。