Шаблонизация конфигурационных файлов nginx
Предисловие
Писать особо не о чем, а хочется, поэтому приходится вот такие тупые темы рассматривать. Но вдруг кому-то пригодится.
Зачем?
- Несколько стендов приложения. Тестовый, боевой, ещё какой-нибудь… Много их. И для всех нужен немного разный конфиг nginx.
- Я хочу держать конфиг nginx в git, потому что в 2k18 этот конфиг уже давно стал частью кода приложения, а не какой-то инфраструктурщиной. То есть нужен контроль версий, code-review и прочие практики.
- В то же время я не хочу держать по конфигу на каждый стенд, потому что нет совершенно никакого желания каждый раз при разворачивании стенда писать новый конфиг.
- Nginx сам (почти) не умеет в динамическую конфигурацию. Даже значения из ENV жрать не может.
Что делаем?
Пытаемся конфигурировать nginx динамически (ну, почти) с использованием ENV-переменных. Почему ENV? Потому что мне приходится работать с Openshift, в котором конфигурация через ENV является если не единственно возможной (есть ещё всякие config-map’ы), то одной из самых удобных и предсказуемых.
Как?
Очень просто. Шаблонизация.
Какая шаблонизация?
Я знаком с двумя более-менее подходящими шаблонизаторами: ERB и Jinja2. Есть ещё всякие EEX и куча других шаблонизаторов, но с ними было бы не так удобно.
Так как в python я понимаю примерно ничего, то от Jinja2 я отказался. Остался ERB.
Как это всё используем?
Идея простая: при старте nginx генерируем конфиг из шаблона.
Для этого нужно два скрипта: один умеет генерить конфиг из шаблона, второй — запускать первый скрипт перед nginx.
Генерим конфиг
С первой задачей справляется вот этот ruby-скрипт, хотя я уверен, что есть готовые и более элегантные решения. Мне было лень гуглить, поэтому я быстренько накатал своё.
Для примера конфиг с опциональной базовой аутентификацией:
server {
listen 80 default_server;
server_name <%= env['SERVER_NAME'] %>;
<% if env['BASIC_AUTH_ENABLED'] %>
auth_basic "Restricted Content";
auth_basic_user_file /etc/nginx/auth/htpasswd;
<% end %>
root /public;
location / {
try_files $uri $uri/index.html;
}
}
Стартуем nginx
Со второй задачей всё ещё проще — там справляется обычный bash в пару строк (ну или что там у вас используется для shell-скриптов):
#/bin/bash
/usr/bin/render-template /configs/default.conf.erb /etc/nginx/conf.d/default.conf
nginx -g "daemon off;"
Готово!
Вы восхитительны!
В результате
- Конфиг nginx находится в git (что позволяет хотя бы сделать git blame в случае полного провала).
- Этот конфиг полностью отвязан от стендов. Я, например, тот же конфиг даже при разработке использую.