Как можно добавить параметр 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` будет необходим после изменения конфигурации, чтобы применить эти изменения.
Это можно реализовать с помощью скрипта по типу такого питонвского скрипта: 

Здесь осталось понять как находить PID nginx и как определять адреса редиректа для версий.

ИМХО: я считаю что такие вещи должны обрабатываться самим приложением, т.к.
1. Некоторые разницы в версиях должны обрабатываться на стороне приложения, например, при миграции нужно использовать новую таблицу, а создавать триггеры и поддерживать их до конца плохая затея, либо генерация событий в очередь сообщений
2. Тебе придется запускать постоянно новые процессы или держать каждый инстанс на отдельной машине, что немного ресурсоемко
3. На мой взгзляд, версионирование API должно быть по типу v1, v2, v3, а не такая гарнулярная как сематическое версионирование. Это не гит и новые версии, которые ты публикуешь надо поддерживать долго
Похожие вопросы