Как настроить Nginx для перенаправления запросов на три разных контейнера Docker?

Здравствуйте! <br/> <br/> У меня на сервере запущены три различных Docker-контейнера, каждый из которых представляет собой отдельное веб-приложение. Они слушают порты 8080, 5678 и 8999, и я могу проверить их работу, заходя по адресам my.site.com:8080, my.site.com:5678 и my.site.com:8999. <br/> <br/> Как правильно настроить Nginx для перенаправления запросов по следующей схеме: <br/> my.site.com/web1 ----> на порт 8080 <br/> my.site.com/web2 ----> на порт 5678 <br/> my.site.com/web3 ----> на порт 8999 <br/> <br/> Я пробовал использовать следующую конфигурацию: <br/> <pre><code>server {
    listen 80;
    server_name my.site.com;

    location /web1 {
        proxy_pass http://localhost:8080;
    }
    location /web2 {
        proxy_pass http://localhost:5678;
    }
    location /web3 {
        proxy_pass http://localhost:8999;
    }
}</code></pre> <br/> <br/> Однако, когда я пытаюсь зайти на my.site.com/web1, приложение перенаправляет меня на страницу авторизации по адресу: <br/> <br/> my.site.com/login <br/> <br/> В результате появляется ошибка: <br/> <br/> 404 Not Found <br/> nginx/1.24.0 (Ubuntu) <br/> <br/> Что следует изменить в конфигурации Nginx, чтобы это исправить? <br/> (Я очищаю кэш и перезапускаю Nginx)
  • 7 января 2025 г. 9:43
Ответы на вопрос 2
Для того чтобы правильно настроить Nginx для проксирования запросов к вашим контейнерам Docker с учетом префиксов в URL (например, `/web1`, `/web2`, `/web3`), вам нужно корректно настраивать ключи `location` и использовать директиву `proxy_pass` с учетом удаления префикса, который вы добавляете в запросах.

Ваш текущий конфигурационный файл Nginx не учитывает необходимость обрезать префикс URL перед перенаправлением на приложение в контейнере. Без этого обрезания ваши приложения могут ожидать, что URL начинается с корневого `/`, и при обращении к `my.site.com/web1` будет пытаться перейти на `my.site.com/web1/login`, что приводит к ошибкам.

Вот корректный вариант конфигурации:

```nginx
server {
    listen 80;
    server_name my.site.com;

    location /web1 {
        proxy_pass http://localhost:8080/; # Обратите внимание на добавленный слэш в конце
        proxy_set_header Host $host; # Передайте оригинальный заголовок Host
        proxy_set_header X-Real-IP $remote_addr; # Передайте IP клиента
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Передайте полный список IP
        proxy_set_header X-Forwarded-Proto $scheme; # Передайте схему протокола
    }
    
    location /web2 {
        proxy_pass http://localhost:5678/; # Обратите внимание на добавленный слэш в конце
        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 /web3 {
        proxy_pass http://localhost:8999/; # Обратите внимание на добавленный слэш в конце
        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;
    }
}
```

### Объяснение изменений:

1. **Слэш в конце `proxy_pass`**: При добавлении слэша `/` в конце адреса после порта в `proxy_pass`, вы сообщаете Nginx о том, что нужно удалить префикс `/web1`, `/web2` и `/web3` из запроса. Это позволяет веб-приложениям в контейнерах правильно интерпретировать маршруты.

2. **Передача заголовков**: Добавлены заголовки, чтобы передавать информацию о клиенте и оригинальном запросе к контейнерам. Это может быть полезно для ведения логов и работы приложений.

После внесения изменений обязательно перезапустите Nginx, чтобы применить новую конфигурацию:

```bash
sudo systemctl restart nginx
```

Теперь при обращении к `my.site.com/web1` вы должны попадать на приложение в контейнере, которое работает на порту 8080, и так далее для других приложений.
Каждое из приложений должно понимать, что оно работает по адресу /webX. Если не понимает, возможны перенаправления на url, которые вы не учли. В целом, для современных сложны приложений, так работать не будет.
Похожие вопросы