Можно ли настроить динамический proxy_pass, основываясь на динамическом location в конфигурации?

Как правильно настроить конфигурацию Nginx для проксирования запросов к различным сервисам? Вот ссылки на API, которые нужно проксировать: 
<pre><code class="nginx">https://myhost.ru/api/oneapp/getuser
https://myhost.ru/api/secondapp/getfunction
https://myhost.ru/api/newapp/postdata</code></pre>
и их соответствующие локальные адреса: 
<pre><code class="nginx">http://app-oneapp.local/getuser
http://app-secondapp.local/getfunction
http://app-newapp.local/postdata</code></pre>
Методы могут различаться для каждого приложения. Я уже пробовал разные варианты и пришел к следующему коду: 
<pre><code class="nginx">location ~ ^/api/([a-zA-Z])(/.*)$ {
  proxy_pass http://app-$1.local$2;
  proxy_set_header Host app-$1.local;
  .....
}</code></pre>
Не могли бы вы подсказать, как корректно оформить такую конфигурацию? Заранее спасибо!
  • 6 апреля 2025 г. 22:05
Ответы на вопрос 2
Ваш подход к динамическому `proxy_pass` в Nginx в целом верен, однако стоит внести несколько исправлений для корректной работы конфигурации. Вот пример правильной настройки Nginx для проксирования API-запросов к различным сервисам с учетом динамического использования `proxy_pass`:

```nginx
http {
    ...
    
    server {
        listen 80;
        server_name myhost.ru;

        location ~ ^/api/([a-zA-Z]+)(/.*)$ {
            set $app_name $1;
            set $request_uri $2;

            proxy_pass http://app-$app_name.local$request_uri;
            proxy_set_header Host app-$app_name.local;
            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;

            # Если нужно установить таймауты
            proxy_connect_timeout 30;
            proxy_read_timeout 30;
            proxy_send_timeout 30;
        }
    }
    
    ...
}
```

**Пояснения по конфигурации:**
- `location ~ ^/api/([a-zA-Z]+)(/.*)$ { ... }` — здесь мы используем регулярное выражение для захвата имени приложения (например, `oneapp`, `secondapp`, `newapp`) и оставшейся части URI.
- `set $app_name $1;` — мы сохраняем имя приложения в переменную `$app_name`.
- `set $request_uri $2;` — мы сохраняем оставшуюся часть URI в переменную `$request_uri`.
- `proxy_pass http://app-$app_name.local$request_uri;` — здесь используется комбинация для динамического указания сервера в зависимости от захваченной переменной `$app_name`.
- Также добавлены стандартные заголовки (`X-Real-IP`, `X-Forwarded-For`, `X-Forwarded-Proto`), которые могут быть полезны для получения оригинальной информации о клиенте.

Убедитесь, что DNS-имя `app-oneapp.local`, `app-secondapp.local`, `app-newapp.local` доступно из окружения, где работает Nginx. Если используется локальная среда разработки, возможно, вам потребуется добавить соответствующие записи в файл `/etc/hosts`.

Если у любого из приложений есть специфические заголовки или методы, вы можете дополнительно настроить настройки `proxy_set_header` в зависимости от требований.
В шаблоне после [a-zA-Z] добавить + 
location ~ ^/api/([a-zA-Z]+)(/.*)

Ещё нужно с помощью resolver задать серверы DNS, используемые для преобразования имён app-oneapp.local app-secondapp.local ...
Похожие вопросы