はじめに
ポートを1つにまとめたいけど、Apacheやnginxを使ってちゃんと作りこむほどでもないし...と思っていたら、Tinyproxyを見つけました。
最低限の設定をしたらすぐに使えて、メモリ消費量も少ないようです。
The memory footprint tends to be around 2 MB with glibc
というわけで、試しにリバースプロキシとしてwebアプリを動かしてみました。
環境
$ tinyproxy -v
tinyproxy 1.10.0
サンプルアプリ
docker-composeでリバースプロキシ(Tinyproxy)とwebアプリを動かします。
docker-compose.yml
version: '3'
services:
# リバースプロキシ
tinyproxy:
image: vimagick/tinyproxy
ports:
- "8080:8080"
volumes:
- ./tinyproxy:/etc/tinyproxy
restart: unless-stopped
# -dでフォアグラウンド起動(デフォルトはバックグラウンド)
entrypoint: tinyproxy -d -c /etc/tinyproxy/reverseproxy.conf
# webアプリ(何でもいいけどここではワンライナーREST API)
web:
image: ghcr.io/syuparn/webawk:0.3.0
entrypoint: ./webawk.sh 'GET("/names") { b["names"][1]="Taro"; res(200, b) }'
パス /example/
配下は example.com
、/web/
配下はwebコンテナへプロキシしています。
tinyproxy/reverseproxy.conf
# Tinyproxyの設定
User nobody
Group nobody
# 1024以下の場合はrootユーザー必要
Port 8080
Listen 0.0.0.0
# 60秒でタイムアウト
Timeout 60
# yesの場合普通のプロキシが使えなくなる。リバースプロキシの場合はyes推奨(公式)
ReverseOnly Yes
# example.com
ReversePath "/example/" "http://www.example.com/"
# webコンテナ
# NOTE: docker-composeはコンテナ名をホストとして名前解決可能
ReversePath "/web/" "http://web:8080/"
参考
結果
# localhost:8080/example/ -> example.com
$ curl localhost:8080/example/
<!doctype html>
<html>
<head>
<title>Example Domain</title>
...
# localhost:8080/web/ -> web:8080/ (webコンテナへコンテナ間通信)
$ curl localhost:8080/web/names
{"names":["Taro"]}
レスポンスヘッダには Via
が追加されています。
$ curl -i localhost:8080/web/names
HTTP/1.1 200 OK
Via: 1.1 e8667db7b85d (tinyproxy/1.11.0)
Content-Length: 18
Content-Type: application/json
Date: Sat, 04 Sep 2021 12:57:38 GMT
{"names":["Taro"]}
また、X-Tinyproxy
オプションを有効にすると、サーバー側にリクエスト元のIPアドレスを伝えることができます。
tinyproxy/reverseproxy.conf
# リクエストに "X-Tinyproxy" ヘッダ追加
XTinyproxy Yes
docker-compose.yml
# webアプリ: リクエストヘッダ X-Tinyproxy をログだし
entrypoint: ./webawk.sh 'GET("/names") { print("X-Tinyproxy ", REQUEST_HEADERS["X-Tinyproxy"]); b["names"][1]="Taro"; res(200, b) }'
$ docker-compose logs web
Attaching to tinyproxy-sample_web_1
web_1 | X-Tinyproxy 172.21.0.1
おわりに
ほぼパスの設定だけで使えるので、デモアプリ作成に重宝しそうです。(フォワード)プロキシの機能もあるので、機会があったらそちらも使ってみたいと思います。