Заменить переменные окружения в конфигурации NGINX из docker-compose - PullRequest
2 голосов
/ 18 июня 2019

Я пытаюсь запустить сервер NGINX в Docker-контейнере, настроенном с помощью Docker-compose. Однако подвох заключается в том, что я хотел бы заменить переменную окружения внутри раздела http, в частности, в блоке «upstream».

Было бы замечательно, если бы это работало, потому что у меня есть несколько других контейнеров, которые все настроены с помощью переменных среды, и у меня есть около 5 сред, которые должны быть запущены в любой момент времени. Я попытался использовать "envsubst" (как это предлагается в официальных документах NGINX), perl_set и set_by_lua, однако ни один из них не работает.

Ниже приведен конфиг NGINX, как и после моей последней пробной версии

user  nginx;
worker_processes  1;
env NGINXPROXY;

load_module modules/ngx_http_perl_module.so;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    perl_set $nginxproxy 'sub { return $ENV{"NGINXPROXY"}; }';

    upstream api-upstream {
        server ${nginxproxy};
    }

    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        off;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

Ниже приведен файл Docker NGINX

# build stage
FROM node:latest
WORKDIR /app
COPY ./ /app
RUN npm install
RUN npm run build

# production stage
FROM nginx:1.17.0-perl
COPY --from=0 /app/dist /usr/share/nginx/html
RUN apt-get update && apt-get install -y gettext-base
RUN rm /etc/nginx/conf.d/default.conf
RUN rm /etc/nginx/nginx.conf
COPY default.conf /etc/nginx/conf.d
COPY nginx.conf /etc/nginx
RUN mkdir /certs
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]

Ниже приведен раздел docker-compose.yml для сервера NGINX (с измененными именами и IP-адресами). Команда envsubst намеренно закомментирована на этом этапе моего устранения неполадок.

front-end:
        environment:
            - NGINXPROXY=172.31.67.100:9300
        build: http://gitaccount:password@gitserver.com/group/front-end.git#develop
        container_name: qa_front_end
        image: qa-front-end
        restart: always
        networks:
            qa_network:
                ipv4_address: 172.28.0.215
        ports:
            - "9080:80"
        # command: /bin/bash -c "envsubst '$$NGINXPROXY' < /etc/nginx/nginx.conf > /etc/nginx/nginx.conf && nginx -g 'daemon off;'"

Похоже, что когда я ссылаюсь на переменную $ nginxproxy в вышестоящем блоке (сразу после «server»), я получаю вывод, который выглядит так, будто он ссылается на строковый литерал «$ nginxproxy», а не подставляет значение переменной.

qa3_front_end       | 2019/06/18 12:35:36 [emerg] 1#1: host not found in upstream "${nginx_upstream}" in /etc/nginx/nginx.conf:19
qa3_front_end       | nginx: [emerg] host not found in upstream "${nginx_upstream}" in /etc/nginx/nginx.conf:19
qa3_front_end exited with code 1

Когда я пытаюсь использовать envsubst, я получаю сообщение об ошибке, напоминающее команду, перепутанную с форматом файла nginx.conf

qa3_front_end       | 2019/06/18 12:49:02 [emerg] 1#1: no "events" section in configuration
qa3_front_end       | nginx: [emerg] no "events" section in configuration
qa3_front_end exited with code 1

Я довольно застрял, поэтому заранее спасибо за вашу помощь.

Ответы [ 2 ]

2 голосов
/ 18 июня 2019

Вы можете избежать некоторых неприятностей с помощью интерпретации переменных среды Compose, определив собственную точку входа.Посмотрите на этот простой пример:

  • entrypoint.sh (убедитесь, что этот файл исполняемый)
#!/bin/sh

export NGINXPROXY

envsubst '${NGINXPROXY}' < /config.template > /etc/nginx/nginx.conf

exec "$@"
  • docker-compose.yml
version: "3.7"

services:
    front-end:
        image: nginx
        environment:
            - NGINXPROXY=172.31.67.100:9300
        ports:
            - 80:80
        volumes:
            - ./config:/config.template
            - ./entrypoint.sh:/entrypoint.sh
        entrypoint: ["/entrypoint.sh"]
        command: ["nginx", "-g", "daemon off;"]

Мой файл config имеет то же содержимое, что и ваш nginx.conf, за исключением того, что мне пришлось комментировать строки с помощью модуля Perl.

Обратите внимание, что мне пришлось смонтироватьмой файл конфигурации в другое место, прежде чем я мог envsubst его.Я столкнулся с некоторым странным поведением в форме, когда файл заканчивается пустым после замены, чего можно избежать с помощью этого подхода.Это не должно быть проблемой в вашем конкретном случае, потому что вы уже внедрили его в свой образ во время сборки.


РЕДАКТИРОВАТЬ

Для полноты, чтобыизмените настройку как можно меньше, вам просто нужно убедиться, что вы export переменную среды.Адаптируй свою команду следующим образом:

command: ["/bin/bash", "-c", "export NGINXPROXY && envsubst '$$NGINXPROXY' < /etc/nginx/nginx.conf > /etc/nginx/nginx.conf && nginx -g 'daemon off;'"]

... и все будет хорошо.Я всегда рекомендовал бы «более чистый» способ определения собственной точки входа.

0 голосов
/ 19 июня 2019

Так что после некоторой борьбы с этим вопросом мне удалось заставить его работать аналогично ответу, предоставленному беллакном.Я опубликую свое точное решение здесь, на случай, если кому-то еще понадобится ссылка на полное решение.

Шаг 1: Напишите свой nginx.conf или default.conf, как вы обычно это пишете.Сохраните файл как «nginx.conf.template» или «default.conf.template» в зависимости от того, в какую переменную вы пытаетесь подставить переменные.

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    upstream api-upstream {
        server 192.168.25.254;
    }

    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        off;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

Шаг 2: подставьте переменную в формате $ {VARNAME} для любых значений, которые вы хотите заменить на переменную окружения:

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}

http {
    upstream api-upstream {
        server ${SERVER_NAME};
    }

    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        off;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}

Шаг 3: Скопируйте ваши файлы конфигурации nginx (ваш nginx.conf.template или значение по умолчанию).conf.template) в ваш контейнер в соответствующем месте:

# build stage
FROM node:latest
WORKDIR /app
COPY ./ /app
RUN npm install
RUN npm run build

# production stage
FROM nginx:1.17.0-perl
COPY --from=0 /app/dist /usr/share/nginx/html
RUN apt-get update && apt-get install -y gettext-base
RUN rm /etc/nginx/conf.d/default.conf
RUN rm /etc/nginx/nginx.conf
#-----------------------------------#
|COPY default.conf /etc/nginx/conf.d|
|COPY nginx.conf.template /etc/nginx|
#-----------------------------------#
RUN mkdir /certs
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]

Шаг 4. Установите переменную окружения в файле docker-compos.yml, используя метку раздела «environment».Убедитесь, что имя вашей переменной окружения совпадает с тем, которое вы выбрали в конфигурационном файле nginx.Используйте команду "envsubt" в вашем контейнере Docker, чтобы подставить значения переменных в ваши переменные в вашем nginx.conf.template, и записать вывод в файл с именем nginx.conf в правильном месте.Это можно сделать в файле docker-compose.yml, используя метку раздела «command»:

version: '2.0'
services:
    front-end:
        environment:
            - SERVER_NAME=172.31.67.100:9100
        build: http://git-account:git-password@git-server.com/project-group/repository-name.git#branch-ame
        container_name: qa_front_end
        image: qa-front-end-vue
        restart: always
        networks:
            qa_network:
                ipv4_address: 172.28.0.215
        ports:
            - "9080:80"
        command: >
            /bin/sh -c
            "envsubst '
            $${SERVER_NAME}
            '< /etc/nginx/nginx.conf.template
            > /etc/nginx/nginx.conf
            && nginx -g 'daemon off;'"

Шаг 5. Запустите свой стек с помощью docker-compose up (с любыми дополнительными переключателями, которые вам нужны) иТеперь ваш сервер nginx должен начинаться с любого значения, которое вы указали в разделе «environment» вашего docker-compose.yml

Как упоминалось в приведенном выше решении, вы также можете определить собственную точку входа, однако это решение имееттакже хорошо работает и хранит все содержимое в одном файле конфигурации, что дает мне возможность запускать стек сервисов напрямую из git без единого файла docker-compose.yml.

Большое спасибоВы всем, кто нашел время, чтобы подготовиться к этому, и беллак, что нашли время помочь мне решить проблему.

...