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

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

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

Однако, похоже, это также меняет обработку 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;
    }
4
задан 14 July 2019 в 18:42
1 ответ

В документации указано, что если вы используете переменные в директивах 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;
}
4
ответ дан 3 December 2019 в 03:26

Теги

Похожие вопросы