конфигурация nginx proxy_pass для двух служб, работающих на разных портах

#docker #nginx #docker-compose

#docker #nginx #docker-составить

Вопрос:

Мне нужно перенаправить или проксировать следующее:

Каждый запрос, начинающийся с /api/v1/ to: @server все остальное / на @client

У меня есть @server запущенный на порту 8080 и @client на порту 8081
@client and @server запущенный как контейнеры docker.

Примечание. Все должно использовать https. Следующая конфигурация — это то, что у меня есть, но ее idkw не работает

 server {
  server_name example.com;

  listen 80;
  listen [::]:80 ipv6only=on;

  return 301 https://example.com$request_uri;
}

server {
    server_name example.com;

    listen 443 ssl;

    ssl_certificate     /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    ...

    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;

    location /api/v1/ {
        try_files $uri @server;
    }

    location / {
        try_files $uri @client;
    }

    location @client {
        proxy_pass http://client:8081;
    }

    location @server {
        proxy_pass http://server:8080/api/v1/;
    }

}
  

Комментарии:

1. В чем ваш вопрос? Не могли бы вы уточнить, что работает неправильно в вашей настройке?

2. @AlexanderAzarov Моя настройка не работает. Что я делаю не так, был бы вопрос

Ответ №1:

Если вам необходимо использовать именованные местоположения, вы можете использовать error_page подход, описанный ниже.

return Вводя неиспользуемые коды состояния HTTP и error_page для этих кодов устанавливая именованные местоположения, мы можем пересылать запросы в эти именованные местоположения:

 server {
  server_name example.com;

  listen 80;
  listen [::]:80 ipv6only=on;

  return 301 https://example.com$request_uri;
}

server {
    server_name example.com;

    listen 443 ssl;

    ssl_certificate     /etc/nginx/ssl/example.com.crt;
    ssl_certificate_key /etc/nginx/ssl/example.com.key;

    ...

    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;

    error_page 350 = @client;
    error_page 351 = @server;

    location /api/v1/ {
        return 351;
    }

    location / {
        return 350;
    }

    location @client {
        proxy_pass http://client:8081;
    }

    location @server {
        proxy_pass http://server:8080/api/v1/;
    }

}
  

Комментарии:

1. Данила, спасибо за твой ответ, но, вероятно, есть лучшие подходы для исправления этого. На самом деле, @client и @server являются известными хостами, поэтому нет необходимости перенаправлять на них как на страницы ошибок.

2. Я думаю, что мое решение является единственно возможным, если вам требуется использовать эти именованные местоположения. Если нет, то, очевидно, вы можете просто поместить proxy_pass -ы непосредственно в / и /api/v1/ (полностью удалив именованные местоположения). В противном случае вы можете использовать сторонний модуль echo (взгляните на echo_exec директиву). И, наконец, фактических ошибок с error_page нет. Фактически, это всего лишь имя директивы для обработки определенных кодов состояния HTTP.