Назад | Перейти на главную страницу

Замена URI при использовании динамических хостов в обратном прокси Nginx

К вашему сведению - я подозреваю, что у этого есть очень очевидный / простой ответ (я новичок в nginx)

Я использую динамические восходящие потоки как часть моей конфигурации Nginx. Это означает использование переменных в proxy_pass директива, которая инструктирует nginx использовать resolver вместо сбоя / отсутствия загрузки, если в восходящем потоке возникла проблема (неизвестный хост / подключение невозможно).

Однако, похоже, это также меняет обработку proxy_pass с URI. Вместо того, чтобы заменять URI запроса на URI, указанный в proxy_pass директива, похоже, игнорирует URI запроса. Я ищу способ сохранить (или воспроизвести) исходное поведение, позволяющее продолжать использовать динамические хосты.

Я попытался создать здесь минимальный пример конфигурации:

server {
    listen 80;
    server_name my-server.com;

    # My chosen DNS server (in this case, the Docker DNS)
    resolver 127.0.0.11 valid=30s ipv6=off;

    # This works
    location / {
        set $upstream frontend:8080;
        proxy_pass http://$upstream;
    }

    # This does not work :-( 
    # The original URI (e.g. /api/users/tommy) is ignored, and 
    # all requests to api-server are directly to /api/
    location /api/ {
        set $upstream api-server:8002;
        proxy_pass http://$upstream/api/;
    }
}

Один из способов решения этой проблемы - удалить URI из proxy_pass директиве и попросите вышестоящий сервер прослушивать точный необходимый URI. Это не идеально, поскольку основным преимуществом сервера шлюза является добавление некоторой гибкости для независимого изменения вещей (при необходимости переписывая URI).

Например,

    # This kind of works, but upstream must listen on /api 
    location /api {
        set $upstream api-server:8002;
        proxy_pass http://$upstream;
    }

В документация заявляет, что если вы используете переменные в proxy_pass директива и вы указываете часть URI, она будет передана в восходящем направлении "как есть".

Вам нужно будет захватить часть URI, которую нужно отправить в восходящем направлении. Либо используйте регулярное выражение location блок, например:

location ~ ^/api(.*)$ {
    set $upstream ...;
    proxy_pass http://$upstream$1;
}

Или используйте rewrite...break чтобы изменить текущий URI, например:

location /api {
    set $upstream ...;
    rewrite ^/api(.*)$ $1 break;
    proxy_pass http://$upstream;
}