Docker-создание с помощью шаблонов nginx для передачи глобальных переменных. Добавление команды в мое сочинение нарушает эту функцию

#docker #nginx #docker-compose

Вопрос:

(Похоже на вчерашнее сообщение без ответа, но с тех пор я увеличил масштаб причины моей проблемы, поэтому повторно опубликую здесь меньше текста и удалю вчерашнее сообщение)

С помощью изображения nginx можно передавать глобальные переменные env. Документация. По ссылке есть раздел » Использование переменных среды в конфигурации nginx (новое в 1.19)». При запуске этого контейнера функциональность, описанная выше в отношении глобальных переменных, действительно работает должным образом.

Если я войду в запущенный контейнер, я увижу скрипт на корневом уровне системы каталогов docker-entrypoint.sh . Из исследований следует, что метод, который nginx docker использует для передачи глобальных переменных, основан на том, что этот сценарий запускается при запуске контейнера и что это автоматический процесс.

Проблема в том, что у моего докера-сочинителя есть команда command: "/bin/sh -c 'while :; do sleep 6h amp; wait $${!}; nginx -s reload; done amp; nginx -g "daemon off;"'" . Когда я включаю эту команду и запускаю ее, она нарушает функциональность глобальных переменных. От выполнения некоторого поиска добавление команды нарушает любые сценарии точек входа? Похоже, я могу использовать функциональность глобальной переменной только в том случае, если я не добавлю никаких команд в свой docker-compose с момента его остановки docker-entrypoint.sh от того, что им управляли.

Есть ли «правильный» способ обойти это?

Работает — глобальные переменные передаются в nginx:

 version: "3.5"
networks:
  collabora:

services:
  nginx:
    image: nginx
    depends_on:
      - certbot   
      - collabora 
    volumes:
      - ./data/nginx/templates:/etc/nginx/templates
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - "80:80"
      - "443:443"
    env_file: .env
    networks:
      - collabora
 

Не работает, глобальные переменные не передаются, и шаблон default.conf-это все, что я получаю:

 version: "3.5"
networks:
  collabora:

services:
  nginx:
    image: nginx
    depends_on:
      - certbot   
      - collabora 
    volumes:
      - ./data/nginx/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;"'"
    networks:
      - collabora
 

Комментарии:

1. Можете ли вы удалить command: и вручную перезапустить контейнер , когда вам это необходимо? Или используйте задание cron на хосте, чтобы перезапустить его, если ему нужно перезапустить по расписанию?

Ответ №1:

Взгляните на сценарий точки входа внутри контейнера, в частности на if инструкцию, которая защищает большую часть кода:

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

Шаблоны и другие сценарии точек входа будут выполняться только в том случае, если $1 это nginx или nginx-debug . Это не относится к вашему файлу Dockefile, в котором $1 было бы /bin/sh .

Самым простым вариантом было бы заменить сценарий точки входа модифицированной версией, которая запускает сценарии точки входа безоговорочно. Есть несколько способов сделать это, но самый простой, вероятно,:

  • Создайте пользовательский docker-entrypoint.sh сценарий в своем локальном каталоге (убедитесь, что он исполняемый).
  • Установите это поверх стандартной версии в вашем docker-compose.yml :
     version: "3.5"
    networks:
      collabora:
    
    services:
      nginx:
        image: nginx
        depends_on:
          - certbot
          - collabora
        volumes:
          # Here is where we orverride the entrypoint script.
          - ./data/docker-entrypoint.sh:/docker-entrypoint.sh
          - ./data/nginx/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;"'"
        networks:
          - collabora
     

Удаление if заявления о защите дает нам:

 #!/bin/sh
# vim:sw=4:ts=4:et

set -e

if [ -z "${NGINX_ENTRYPOINT_QUIET_LOGS:-}" ]; then
    exec 3>amp;1
else
    exec 3>/dev/null
fi

if /usr/bin/find "/docker-entrypoint.d/" -mindepth 1 -maxdepth 1 -type f -print -quit 2>/dev/null | read v; then
    echo >amp;3 "$0: /docker-entrypoint.d/ is not empty, will attempt to perform configuration"

    echo >amp;3 "$0: Looking for shell scripts in /docker-entrypoint.d/"
    find "/docker-entrypoint.d/" -follow -type f -print | sort -V | while read -r f; do
        case "$f" in
            *.sh)
                if [ -x "$f" ]; then
                    echo >amp;3 "$0: Launching $f";
                    "$f"
                else
                    # warn on shell scripts without exec bit
                    echo >amp;3 "$0: Ignoring $f, not executable";
                fi
                ;;
            *) echo >amp;3 "$0: Ignoring $f";;
        esac
    done

    echo >amp;3 "$0: Configuration complete; ready for start up"
else
    echo >amp;3 "$0: No files found in /docker-entrypoint.d/, skipping configuration"
fi

exec "$@"
 

Комментарии:

1. Я не совсем все здесь понимаю, но вы хотите сказать, что мне просто нужно скопировать существующий docker-entrypoint.sh в свой каталог, а затем создать том с ним как часть моего сочинения? Хорошо, я попробую это сейчас

2. …не забудьте, конечно, изменить его, чтобы удалить это утверждение if. И, пожалуйста, дайте мне знать, если вы хотите, чтобы я что-то прояснил в этом ответе.

3. Что, если утверждение, похоже, в значительной степени соответствует всему сценарию, нет? Я в замешательстве! Не могли бы вы поделиться тем, как именно docker-entrypoint.sh должен выглядеть новый измененный файл?

4. Я обновил ответ, чтобы показать измененный сценарий.

5. Могу я предложить вам другое потенциальное решение? Кто-то предложил добавить скрипт в контейнер, docker-entrypoint.d и тогда мне не пришлось бы вручную корректировать docker-entrypoint.sh приведенный выше сценарий. Я попробовал это, я добавил командную часть моего docker-compose выше ( /bin/sh -c 'while :; do sleep 6h amp; wait... ) в файл test.sh , а затем в раздел тома /test.sh:/docker-entrypoint.d/test.sh . Это «почти» работает. Служба запускается, и в контейнере /etc/nginx/conf.d содержится правильно преобразованный файл app.conf с моими глобальными переменными, замененными на но …