プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2023/03/14

Nginx の proxy_pass で名前解決されない

event_note2023/03/14 9:37

nginx を Docker コンテナとして動かしており、ホスト側へリバースプロキシを行おうとした際にはまってしまいました。

環境

  • docker 20.10.21
  • nginx 1.23.3

問題と対策

Docker コンテナ内からホストにアクセスする際には host.docker.internal を指定します。
これについては以下の記事を参照してください。

その上で、nginx の設定で以下のようにリバースプロキシの設定を行いました。

server {
    listen        80  default_server;
    server_name   _;

    location /hoge {
        resolver           127.0.0.11  valid=30s;
        set                $dummy_var  http://host.docker.internal:5000;
        rewrite            /hoge/(.*)$ /$1 break;
        proxy_pass         $dummy_var;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}

すると、以下のように名前解決できないというエラーが表示されました。

尚、コンテナ内に入って curl などを使ってテストすると、きちんと host.docker.internal の名前解決がされていました。
いろいろ調べてみると、どうやら proxy_pass では /etc/hosts が参照されないそうです。

どのように対応しようか悩んでいたところ、upstream の設定ではきちんと /etc/hosts が参照されるようでしたので、以下のように設定して回避することにしました。

upstream backends {
    server host.docker.internal:5000;
}

server {
    listen        80  default_server;
    server_name   _;

    location /hoge {
        resolver           127.0.0.11  valid=30s;
        set                $dummy_var  http://backends;
        rewrite            /hoge/(.*)$ /$1 break;
        proxy_pass         $dummy_var;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection keep-alive;
        proxy_set_header   Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }
}