nginx docker alpine envsubst не работает, когда в docker есть команда-составить

#docker #nginx #docker-compose

Вопрос:

Я хотел бы использовать envsubst с nginx docker alpine. Документация:

Использование переменных среды в конфигурации nginx (новое в 1.19)

Из коробки nginx не поддерживает переменные среды внутри большинства конфигурационных блоков. Но у этого изображения есть функция, которая извлекает переменные среды до запуска nginx.

Вот пример использования docker-compose.yml:

веб: изображение: тома nginx:

  • ./шаблоны:/etc/nginx/порты шаблонов:
  • «8080:80» окружающая среда:
  • NGINX_HOST=foobar.com
  • NGINX_PORT=80

По умолчанию эта функция считывает файлы шаблонов в /etc/nginx/templates/*.template и выводит результат выполнения envsubst в /etc/nginx/conf.d.

У меня есть контейнерный сервис nginx в форме:

 version: '3'

services:
  nginx:
    image: nginx:alpine
    restart: unless-stopped
    volumes:
      #- ./data/nginx:/etc/nginx/conf.d
      - ./templates:/etc/nginx/templates
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - "80:80"
      - "443:443"
    env_file: .env
    command: "/bin/sh -c 'while :; do sleep 6h amp; wait ${!}; nginx -s reload; done amp; nginx -g "daemon off;"'"
 

Когда я запускаю эту службу, envsubst не работает. Однако, если я удалю command: в docker-compose, это сработает.

Я попытался скопировать команду в файл .sh и переместить ее внутрь контейнера по адресу /docker-entrypoint.d/mycommand.sh . По умолчанию здесь есть несколько других файлов .sh, которые запускаются до загрузки nginx:

 ls -l docker-entrypoint.d
total 16
-rwxrwxr-x    1 root     root          1961 May 25 15:44 10-listen-on-ipv6-by-default.sh
-rwxrwxr-x    1 root     root          1037 May 25 15:44 20-envsubst-on-templates.sh
-rwxrwxr-x    1 root     root          4613 May 25 15:44 30-tune-worker-processes.sh
 

Я тоже добавил mycommand.sh туда, используя громкость. Вот что mycommand.sh похоже на:

 #! /bin/bash

# reload nginx config every 60 seconds in case certs get updated
while :; do
  sleep 60
  echo reloading
  nginx -s reload
done
 

Однако, когда я добавляю этот скрипт в /docker-entrypoint.d каталог, nginx, похоже, никогда не запускается.

Как я могу запустить свою команду И использовать envsubst с помощью nginx alpine в соответствии с документацией?

Я бы предпочел пойти по этому пути, а не, например, использовать новый контейнер nginx с общим томом, чтобы получить тот же результат. Добавление сценария .sh в docker-entrypoint.d «кажется «»правильным» способом и приведет к более минималистичному составлению докера.

Ответ №1:

Изменение команды не работает, потому /docker-entrypoint.sh что содержит:

 if [ "$1" = "nginx" -o "$1" = "nginx-debug" ]; then
...
 

И когда вы меняете команду, $1 становится /bin/sh .

Сценарии /docker-entrypoint.d , которые необходимо запустить, должны завершиться до docker-entrypoint.sh того, как программа дойдет до конца, где она выполнит команду (по умолчанию, запуск nginx). Вы можете поместить этот цикл в фоновом режиме, чтобы достичь этого, просто добавив a amp; после завершения:

 #! /bin/bash

# reload nginx config every 60 seconds in case certs get updated
while :; do
  sleep 60
  echo reloading
  nginx -s reload
done amp;
 

Обратите внимание, что это очень похоже на анти-шаблон с контейнерами, который обычно имеет смысл только в среде разработки. В рабочей среде вы бы повторно развернули новый контейнер с новой конфигурацией.