danjo0193
@danjo0193

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

Dockerでリバースプロキシ 不定なサブドメインでのアクセスを有効にしたい

前提

Dockerで複数のWebサーバコンテナを、リバースプロキシを使用してサブディレクトリやサブドメインに当てる設定で試行錯誤しています。
apacheコンテナを3つ(web1,web2,web3)と、リバースプロキシ用のnginxコンテナ一つ(reverse_proxy)を定義しています。
それぞれ、
web1には
http://example.com/
web2には
http://example.com/web2
web3には
http://web3.example.com/
というURLでアクセスできるようにしたいです。
(このexample.comは、実際には私が所有しているドメインに置き換えます。)
(AWS側のDNS設定で、example.comと*.example.comが同じインスタンスの同一IPに当てています。)
以下の設定で"docker-compose up -d"を実行すれば、ディレクトリweb1,web2,web3に入れたコンテンツをwebブラウザから表示することには成功しています。

うまく行っている設定ファイルの中身

docker-compose.ymlの内容
version: '3'
services:
  web1:
    image: httpd:latest
    ports:
     - "8001:80"
    volumes:
      - ./web1:/usr/local/apache2/htdocs/

  web2:
    image: httpd:latest
    ports:
     - "8002:80"
    volumes:
      - ./web2/:/usr/local/apache2/htdocs/
      
  web3:
    image: httpd:latest
    ports:
     - "8003:80"
    volumes:
      - ./web3/:/usr/local/apache2/htdocs/
      
  reverse_proxy:
    image: nginx:latest
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./default:/var/www/
    ports:
      - "80:80"
    depends_on:
      - web1
      - web2
      - web3
      
      
リバースプロキシとして使うnginx.conf
worker_processes 1;
events {
    worker_connections 1024;
}

http {
    server {
        listen 80;
        server_name example.com;
        
        location / {
            proxy_pass http://web1:80/;
        }

        location /web2/ {
            proxy_pass http://web2:80/;
        }
    }
    server {
        listen 80;
        server_name web3.example.com;
        location / {
            proxy_pass http://web3:80/;
        }
    }
}

やりたいこと

ここから少し変更して、サブドメインを正規表現で抽象表現し、web3でもweb4でもhogeでも、任意の名前のサービスに当てられるようにしたいです。
たとえば
http://hoge.example.com/
にアクセスがあったら、
proxy_pass http://hoge:80/;
というサービスが表示されるというようなことがしたいです。
ChatGPTに教えてもらった設定、nginx.confのweb3を定義している箇所を以下に書き換えました。

nginx.conf 書き換えた箇所

    server {
        listen 80;
        server_name ~^(?<subdomain>.+)\.example\.com$;
        location / {
            proxy_pass http://$subdomain:80/;
        }
    }

結果と問題点

これで
http://web3.example.com/
にアクセスすると、所定ディレクトリに置いたindex.htmlは正しく表示されます。
しかしindex.html以外の全てのコンテンツが表示されません。
たとえば
http://hoge.example.com/test.jpg
というURLにアクセスすると、ファイルは存在するのに実際にはindex.htmlが表示されます。
サブディレクトリも同様で
http://hoge.example.com/subdir/test.html
にアクセスしても、出てくるのはルートのindex.htmlです。
存在しないファイルやサブディレクトリを指定した場合も同様です。
http://web3.example.com/
以下にどんなパスを指定してもルートのindex.htmlを返すようになっているみたいです。

正しくアクセスできるようにする設定を教えてください。

1

2Answer

 nginxはホスト側で運用することを推奨します。同時に、dockerはnat変換ではなくhost指定を推奨します。

web2:
    image: httpd:latest
    ports:
     - "8002:80"
    volumes:
      - ./web2/:/usr/local/apache2/htdocs/web2/

rootは /usr/local/apache2/htdocs/

http {
    server {
        listen 80;
        server_name example.com;    
        location ~/(web2)·* {
            proxy_pass http://web2:80/;
        }
        location ~/·* {
            proxy_pass http://web1:80/;
        }
    }
    server {
        listen 80;
        server_name web3.example.com;
        location ~/·* {
            proxy_pass http://web3:80/;
        }
    }
}

但し、
wget -SO- http://web2:80/web2/
wget -SO- http://web1:80/
wget -SO- http://web3:80/

で目的のコンテンツを返すこと

rewriteで一方的に仮想urlに変更できますが、cgi,wsgi,rack等とインタラクティブに応答できません。よって、/web2/の様に実urlを返すことが妥当です。

因みに、私は
wget -SO- http://web1:8001/web1/
wget -SO- http://web2:8002/web2/
wget -SO- http://web3:8003/web3/

https://example.com/web■/ に統合してます。

0Like

Comments

  1. @danjo0193

    Questioner

    ご回答ありがとうございます。
    実は別途質問しようと思っていたことが図らずも解決しました。
    このweb2のようにサブディレクトリに当てるサービスで、apacheコンテナの代わりにwordpressコンテナに置き換えた場合、webアプリケーションとして正常に動作しないと思って悩んでいました。
    ご教示いただいた通り、実URLで階層を合わせてしまうと上手く動くようになりました。

  2. おめでとうございます。

Comments

  1. @danjo0193

    Questioner

    ありがとうございます。
    私のスキルでは理解できない箇所も多い資料ですが、調べながら頑張って読んでみます。

Your answer might help someone💌