サブドメインを動的に設定してリバースプロキシとして動作させ、LXCコンテナに振りたいなぁという要望が出たのでメモ。
Cybozuだとデータベースファイルを読み込んでやっているらしいが、ここではRedisを使ってみる。

動作イメージとしては以下のような感じ。

redisにはコンテナ名をkeyとして値にコンテナのIPアドレスが入っている。

> get container1
10.16.29.10

Nginxの動作としては以下のような感じ。

  1. container1.example.comにアクセス
  2. Redisにcontainer1というkeyがあればvalueであるIPアドレスに転送
  3. container1というkeyがなければ404を返す

環境

手順

何はともあれopenrestyをインストールする。
hostsではサブドメインのワイルドカードに対応していないので、dnsmasqを利用した。

dnsmasq.confの設定。本番ではちゃんとDNSの設定をしよう。

address=/example.com/127.0.0.1

nginx.confの設定。

server {
    listen 80;
    server_name ~^(?<subdomain>[^\.]+).example.com;

    location / {
        set $upstream "";
        rewrite_by_lua '
            local redis = require "resty.redis"
            local client = redis:new()
            client:connect("127.0.0.1", 6379)
            local result, err = client:get(ngx.var.subdomain)
            if result == ngx.null then
                ngx.exit(404)
            else
                ngx.var.upstream = result
            end
        ';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass http://$upstream;
        proxy_redirect ~^(http://[^:]+):\d+(/.+)$ $1$2;
}

これでOK。

$ curl container1.example.com
this is container1
$ curl container2.example.com
<html>
<head><title>404 Not Found</title></head>
...

参考

nginx