やりたいこと
-
blog.abcang.net
とabcang.net
宛のリクエストをweb
コンテナに転送 -
blog.abcang.net
とabcang.net
でそれぞれ別のページが表示される -
app.abcang.net
宛のリクエストをapp
コンテナに転送 - 登録されていないサブドメインでのアクセスは
abcang.net
に転送 - コンテナを増やすたびに設定ファイルを追加したくない
やったこと
以下のように設定ファイルを編集する。
各コンテナは普段通りの設定をすればいい。
/etc/nginx/conf.d/default.conf
map $http_host $cname {
hostnames;
abcang.net web;
blog.abcang.net web;
app.abcang.net app;
default 0;
}
server {
listen 80 default_server;
server_name abcang.net;
# 登録されていないホストはリダイレクト
if ($cname = 0) {
rewrite ^ http://abcang.net$request_uri? last;
}
# 内部DNSで名前解決して転送
location / {
resolver dns.abcang.net valid=3600s;
proxy_pass http://$cname;
# 接続元情報を維持
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_max_temp_file_size 0;
# Websocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
}
}
説明
ドメインからコンテナを指定
map $http_host $cname {
hostnames;
abcang.net web;
blog.abcang.net web;
app.abcang.net app;
default 0;
}
左にアクセス元のドメインを、右にコンテナの名前を書いていく。
新しくコンテナを追加した場合はこの部分を増やせば良い。
default
は一致しなかったものがマッチして、0
が設定されるようにしている。
登録されていないホストはリダイレクト
# 登録されていないホストはリダイレクト
if ($cname = 0) {
rewrite ^ http://abcang.net$request_uri? last;
}
先のmapでの設定で、登録されていない場合は$cname
が0
になることがわかる。
それを検知したらrewrite
でリダイレクトするようにしている。
last
をつけるとそこで処理を停止してくれるらしい。
各コンテナに転送
# 内部DNSで名前解決して転送
location / {
resolver dns.abcang.net valid=3600s;
proxy_pass http://$cname;
# 接続元情報を維持
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_max_temp_file_size 0;
# Websocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_http_version 1.1;
}
resolver
の部分で内部DNS(LXCで使用されているもの)を指定する。
valid
をつけると再度DNSに問い合わせる時間を指定できるみたい。
proxy_pass
で転送先を指定しているが、ドメイン部分を変数にしておかないとnginx起動時以降名前解決してくれないらしい。
後は接続元の情報をヘッダに付けてあげたり、WebSocketも使えるようにしてあげたり。