0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

コンテナ内のdocker-genからホスト環境のNginxを設定したい

Posted at

DockerコンテナとしてWebアプリケーションを動かしてNginxをリバースプロキシとして利用する場合, docker-gennginx-proxy で設定を自動化していることが多いと思います.

バーチャルホストの設定を自動的に生成できて便利ですが,Nginxがコンテナではなくホスト環境で動作していると設定の更新が煩雑になりがちで悩ましいです.Nginxもコンテナ化してしまうのも手ですが,歴史的経緯や外的要因で既に動いているNginxをそのまま使いたい場合もあります.

暫定の解決方法

コンテナとして起動したdocker-genでNginxの設定ファイルを生成して,ホストのNginxに読み込ませます.

Docker と Nginx と docker-gen の使い方についてはこの文書では触れません.

docker-genでコンテナを監視し,設定をファイルを生成して,NginxのプロセスにSIGHUPを送るだけで良さそうです.(Nginxのドキュメントを見る限り nginx -s reloadkill -HUP 相当です)

dokcer-genに渡す必要があるもの:

  • /var/run/docker.sock (ReadOnly)
  • /var/run/nginx.pid (ReadOnly)
  • /etc/nginx/conf.d/ (Read/Write)

NginxにSIGHUPを送るために,ホストのPIDと/var/run/nginx.pidにアクセスする必要があるので,--pid=host必須な上,nginx.pidはファイルが再作成される可能性があるので,ファイル自体ではなく /var/run をコンテナに渡す必要があります.nginx.pidを別のディレクトリ移動すればマシになりますが,ホストのNginxはあまり触らない方針.

そもそも論から言えば,docker.sockを渡すのも嫌な感じがしますが,これはdocker-genを使う以上仕方なさそうです.

docker-gen用のテンプレートとdocker image

nginx.tmplは SynologyのNASを買ったら最初からインストールされてたNginxに80番と443番ポートが握られてて困って書いたやつですが,他の環境でも使えるはずです.

docker run -d --restart=always --name nginx-conf-gen \
   --pid=host \
   -v /var/run:/tmp/run:ro \
   -v /etc/nginx/conf.d:/tmp/dst \
   binzume/nginx-conf-gen

使い方はnginx-proxyに入ってるテンプレートと似た感じですが,HTTP_PATH, HTTP_PROXY_PATH環境変数で同じバーチャルホストで複数アプリケーションを動かせます.

サンプル出力

docker run -d --name app01_instance01 -p :8080 -e VIRTUAL_HOST=example.com -e HTTP_PATH=/app01/ -e HTTP_PROXY_PATH=/ mendhak/http-https-echo
docker run -d --name app01_instance02 -p :8080 -e VIRTUAL_HOST=example.com -e HTTP_PATH=/app01/ -e HTTP_PROXY_PATH=/ mendhak/http-https-echo
docker run -d --name app02 -p :8080 -e VIRTUAL_HOST=example.com -e HTTP_PATH=/app02/ -e HTTP_PROXY_PATH=/ mendhak/http-https-echo

こんな感じで色々起動すると,以下のようなconfが生成されます.-pで指定するホスト側のポートは省略して自動的に割り当てて大丈夫です.

upstream example.com.app02. {
        server 0.0.0.0:32780; # app02
}
upstream example.com.app01. {
        server 0.0.0.0:32779; # app01_instance02
        server 0.0.0.0:32778; # app01_instance01
}
server {
        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
        proxy_buffering off;
        server_name example.com;
        listen 80;
        listen [::]:80;
        listen 443 ssl;
        listen [::]:443 ssl;
        include /etc/nginx/default.d/*.conf;
        include /etc/nginx/sites-customizations/example.com.*.conf;
        location /app02/ {
                proxy_pass http://example.com.app02./;
                proxy_http_version 1.1;
                proxy_read_timeout 3600s;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Connection "";
        }
        location /app01/ {
                proxy_pass http://example.com.app01./;
                proxy_http_version 1.1;
                proxy_read_timeout 3600s;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header X-Forwarded-Proto $scheme;
                proxy_set_header Connection "";
        }
}

default.dsites-customizations下のconfも存在すればincludeするようにして追加の設定を置いたりしています.nginx-conf-gen起動時に -e HTTP_MODE=redirect を付けるとHTTPをHTTPSにリダイレクトしたりします.

最後に

色々悩ましいので,ベストプラクティス的なものがあれば知りたいです.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?