はじめに
前回の Ver.1 では、各 Docker コンテナから公開したポートを nginx の転送先に指定してリバースプロキシを実現してみたが、本来は nginx のポートだけを公開して nginx から Docker ホスト内のコンテナに転送すべき。
一つの docker-compose から開始したコンテナ間であれば、ホスト名の代わりにサービス名でもコンテナ名でもアクセスできるのだが、別の docker-compose で開始したコンテナは別ネットワークに分離されて名前解決もされない。
どうするのかと調べてみたら、次の投稿とドキュメントから user-defined bridge を利用すればよいことがわかった。
- docker-compose で別の docker-compose.yml で作ったコンテナとリンクする (ネットワークを繋げる)
- Differences between user-defined bridges and the default bridge
ポイントと落とし穴
- user-defined bridge を利用すれば DNS が機能して名前解決もできる。
-
network_mode: bridge
で default bridge のdocker0
に接続しても名前解決ができない。 - nginx のコンフィグでは転送先にコンテナ名とコンテナ側のポート番号を指定。
ex.
proxy_pass: http://<container_name>:<port_no>
- 転送先のコンテナでポートを公開する必要はないが、nginx のコンフィグ中はデバッグ用に開けておき、後から非公開にすれば問題切り分けもやりやすい。
- Web アプリに応じて proxy_set_header ほかの調整が必要。 Mattermost については こちらを参照。
- 共通の proxy_set_header を server ディレクティブに記述できるが、location ディレクティブ内に proxy_set_header を1行でも追加すると、server ディレクティブに記述されている proxy_set_header は無視され、location ディレクティブ内の proxy_set_header だけが有効になる(つまり、共通設定を無効にしてlocationごとに再定義できる)。
設定
構成
- Docker 上で nginx と各種サービスを実行
- docker-compose
- OS: Debian
nginx
- Docker Image - https://hub.docker.com/_/nginx/
-
conf ファイル設定の基本形は次の通り。
server { listen 80; server_name docker.example.com; proxy_set_header Host $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 X-Frame-Options SAMEORIGIN; location /app_name/ { proxy_pass http://<container_name>:<port_no>/; } }
参考:
* http://nginx.org/en/docs/beginners_guide.html#proxy
* http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
* https://docs.docker.com/v17.09/engine/userguide/networking/#default-networks -
proxy_pass 末尾のスラッシュ
/
有無による違いを理解しておく。参考: https://qiita.com/master-of-sugar/items/6dc7c03a1f600c1ec24a
-
location に正規表現を用いる場合、記述順だけでなく優先順位に留意。
参考: https://server-setting.info/centos/nginx-location-check.html
-
proxy_pass Host には \$http_host の代わりに \$host を指定
docker-compose.yml の基本形は次の通り。
version: '2'
services:
app:
image: <container_image[:tag]>
container_name: <container_name>
volumes:
- /path/to/local:/path/to/volume
networks:
- app_bridge # 任意のネットワーク名
restart: always
networks:
app_bridge:
external: true
- user-defined bridge を手動で作成しておく。
docker network create app_bridge
Mattermost
- Docker Image - https://hub.docker.com/r/mattermost/mattermost-preview/
- 次のドキュメントを参考に、proxy_set_header ほかを設定する。
Knowledge
- Docker Image - https://hub.docker.com/r/koda/docker-knowledge/
-
(任意) コンテキストパス(正確にはサーブレットパス)付き URL のとするために、アプリケーションのファイル名を変更。
- /usr/local/tomcat/webapps/ROOT.war -> knowledge.war
参考: https://qiita.com/nk-tamago/items/52932e2106c9f493754c#起動後のカスタマイズ
Joomla!
- Docker Image - https://hub.docker.com/r/bitnami/joomla/
-
(任意) コンテキストパス付き URL とするために、アプリケーション格納先フォルダを変更。
- /opt/bitnami/joomla -> /opt/bitnami/joomla/joomla
参考: https://docs.joomla.org/J3.x:Installing_Joomla/ja#Downloading_and_Uploading_Joomla.21_Package_Files
サンプル: reverseproxy.conf
# ref=http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass
server {
listen 80;
server_name docker.example.com;
proxy_set_header Host $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 X-Frame-Options SAMEORIGIN;
# ref=https://docs.mattermost.com/install/config-proxy-nginx.html
location ~ /mattermost/api/v[0-9]+/(users/)?websocket$ {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
client_max_body_size 50M;
proxy_set_header Host $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 X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
client_body_timeout 60;
send_timeout 300;
lingering_timeout 5;
proxy_connect_timeout 90;
proxy_send_timeout 300;
proxy_read_timeout 90s;
proxy_pass http://mattermost:8065; # V5 でコンテキストパス付き URL 対応の場合
}
location /mattermost/ {
client_max_body_size 50M;
proxy_set_header Connection "";
proxy_set_header Host $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 X-Frame-Options SAMEORIGIN;
proxy_buffers 256 16k;
proxy_buffer_size 16k;
proxy_read_timeout 600s;
proxy_http_version 1.1;
proxy_pass http://mattermost:8065; # V5 でコンテキストパス付き URL 対応の場合
}
location /knowledge/ {
proxy_pass http://knowledge:8080/;
# proxy_pass http://knowledge:8080; # コンテキストパス付き URL 対応の場合
}
location /joomla/ {
proxy_pass http://joomla:8080/;
# proxy_pass http://joomla:8080; # コンテキストパス付き URL 対応の場合
}
# ref=http://nginx.org/en/docs/beginners_guide.html
location / {
root /var/www;
}
}