Как можно добавить параметр location в сервер из командной строки или сгенерировать конфигурацию динамически?

Как настроить NGINX конфигурацию для реализации версионирования API через поддомен, где требуется заменять как URL, так и порты в directive proxy_pass для location? Например:

```
server {
    server_name api.domain.com;
    listen 80;
    
    location /project_name/v2.2.2-0 {
        proxy_pass http://0.0.0.0:6666;
    }
}
```
  • 21 января 2024 г. 12:28
Ответы на вопрос 2
Чтобы динамически добавить параметр location в NGINX сервер или сгенерировать конфигурацию динамически, можно использовать несколько подходов, включая шаблонизацию или скрипты, которые генерируют файлы конфигурации.

1. **Шаблонизаторы**: Конфигурацию можно создать как шаблон, где переменные, такие как версия API или порт, будут заменены с помощью шаблонизатора (например, Jinja2 в Python, ERB в Ruby, или даже `sed` в UNIX).

2. **Скрипты**: Написать скрипт на Bash, Python, Ruby и т.д., который будет генерировать или модифицировать конфигурационные файлы NGINX перед их загрузкой. Такой скрипт может принимать параметры из командной строки.

Например, скрипт на Bash, который принимает версию API и порт как аргументы и добавляет соответствующую location директиву в NGINX конфигурацию:

```bash
#!/bin/bash

PROJECT_NAME="project_name"
API_VERSION=$1    # Первый аргумент командной строки - версия API.
API_PORT=$2       # Второй аргумент командной строки - порт.

cat <<EOT > /etc/nginx/conf.d/my_api.conf
server {
    server_name api.domain.com;
    listen 80;

    location /${PROJECT_NAME}/${API_VERSION}/ {
        proxy_pass http://0.0.0.0:${API_PORT};
    }
}
EOT

# Перезагружаем NGINX, чтобы применить изменения
nginx -s reload
```

Чтобы работать с поддоменами и версионированием API через NGINX конфигурацию, можно использовать переменные и регулярные выражения для динамической обработки запросов, например:

```nginx
server {
    server_name ~^(?<api_version>v\d+\.\d+\.\d+-\d+)\.api\.domain\.com$;

    listen 80;

    location / {
        # Используйте переменную $api_version для определения нужного порта.
        # Это можно сделать с помощью map-директивы вне серверных блоков.
        proxy_pass http://0.0.0.0:${api_port};
    }
}
```

В этом примере используется именованная группа захвата `(?<api_version>)` для извлечения версии API из поддомена. Вам нужно будет дополнительно настроить `map` директиву (вне конфигурации сервера) для соответствия определенной версии API к определенному порту:

```nginx
map $api_version $api_port {
    default       6666;  # сюда можно добавить логику для сопоставления портов с версиями
    v2.2.2-0      7777;  # Например, для v2.2.2-0 используем порт 7777
    # ... другие версии и порты ...
}
```

После настройки этого `map` директивы, `proxy_pass` будет динамически использовать правильный порт в зависимости от поддомена, который, как предполагается, содержит версию API. Вызов `nginx -s reload` будет необходим после изменения конфигурации, чтобы применить эти изменения.
Это можно реализовать с помощью скрипта по типу такого питонвского скрипта: <br/> <br/> Здесь осталось понять как находить PID nginx и как определять адреса редиректа для версий. <br/> <br/> ИМХО: я считаю что такие вещи должны обрабатываться самим приложением, т.к. <br/> 1. Некоторые разницы в версиях должны обрабатываться на стороне приложения, например, при миграции нужно использовать новую таблицу, а создавать триггеры и поддерживать их до конца плохая затея, либо генерация событий в очередь сообщений <br/> 2. Тебе придется запускать постоянно новые процессы или держать каждый инстанс на отдельной машине, что немного ресурсоемко <br/> 3. На мой взгзляд, версионирование API должно быть по типу v1, v2, v3, а не такая гарнулярная как сематическое версионирование. Это не гит и новые версии, которые ты публикуешь надо поддерживать долго
Похожие вопросы