Saltar al contenido

Sustituya las variables de entorno en la configuración de NGINX desde docker-compose

Te recomendamos que revises esta respuesta en un ambiente controlado antes de enviarlo a producción, saludos.

Solución:

Desde nginx 1.19, ahora puede usar variables de entorno en su configuración con docker-compose. Usé la siguiente configuración:

# file: docker/nginx/templates/default.conf.conf
upstream api-upstream 
    server $API_HOST;



# file: docker-compose.yml
services:
    nginx:
        image: nginx:1.19-alpine
        volumes:
            - "./docker/nginx/templates:/etc/nginx/templates/"
        environment:
            NGINX_ENVSUBST_TEMPLATE_SUFFIX: ".conf"
            API_HOST: api.example.com
        

Me salgo un poco del guión del ejemplo de la documentación. Tenga en cuenta el extra .conf extensión en el archivo de plantilla – esto no es un error tipográfico. En los documentos de la imagen nginx, se sugiere nombrar el archivo, por ejemplo, default.conf.template. Al iniciarse, un script tomará ese archivo, sustituirá las variables de entorno y luego enviará el archivo a /etc/nginx/conf.d/ con el nombre del archivo original, soltando el .template sufijo.

Por defecto, ese sufijo es .template, pero esto rompe el resaltado de sintaxis a menos que configure su editor. En cambio, especifiqué .conf como sufijo de la plantilla. Si solo nombra su archivo default.conf el resultado será un archivo llamado /etc/nginx/conf.d/default y su sitio no se servirá como se esperaba.

Puede evitar algunas de las molestias con Compose interpretando variables de entorno definiendo su propio punto de entrada. Vea este simple ejemplo:

  • entrypoint.sh (asegúrese de que este archivo sea ejecutable)
#!/bin/sh

export NGINXPROXY

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

exec "[email protected]"
  • 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;"]

Mi config archivo tiene el mismo contenido que su nginx.conf, aparte del hecho de que tuve que comentar las líneas usando el módulo Perl.

Tenga en cuenta que tuve que montar mi archivo de configuración en otra ubicación antes de poder envsubst eso. Encontré un comportamiento extraño en la forma en que el archivo termina vacío después de la sustitución, lo que puede evitarse con este enfoque. No debería ser un problema en su caso específico, porque ya lo incrustó en su imagen en el momento de la compilación.


EDITAR

Para completar, para cambiar su configuración lo menos posible, solo debe asegurarse de que export su variable de entorno. Adapte su comando de esta manera:

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

… y deberías estar listo para empezar. Sin embargo, siempre recomendaría la forma “más limpia” de definir su propio punto de entrada.

Entonces, después de luchar un poco con este problema, logré que funcionara de manera similar a la respuesta proporcionada por bellackn. Voy a publicar mi solución exacta aquí, en caso de que alguien más necesite hacer referencia a una solución completa.

Paso 1: escriba su nginx.conf o default.conf como lo escribiría normalmente. Guarde el archivo como “nginx.conf.template” o “default.conf.template” dependiendo de en qué está intentando sustituir las variables.

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;


Paso 2: sustituya una variable en el formato $ VARNAME por cualquier valor que desee reemplazar con una variable de entorno:

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;

Paso 3: En su archivo docker, copie sus archivos de configuración de nginx (su nginx.conf.template o default.conf.template) en su contenedor en la ubicación apropiada:

# 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;"]

Paso 4: Configura tu variable de entorno en tu archivo docker-compos.yml usando la etiqueta de la sección “entorno”. Asegúrese de que el nombre de la variable de entorno coincida con el nombre de la variable que eligió dentro de su archivo de configuración nginx. Utilice el comando “envsubt” dentro de su contenedor de ventana acoplable para sustituir sus valores de variable por sus variables dentro de su nginx.conf.template, y escriba la salida en un archivo llamado nginx.conf en la ubicación correcta. Esto se puede hacer dentro del archivo docker-compose.yml usando la etiqueta de la sección “comando”:

version: '2.0'
services:
    front-end:
        environment:
            - SERVER_NAME=172.31.67.100:9100
        build: http://git-account:[email protected]/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;'"

Paso 5: Ejecute su pila con docker-compose up (con los conmutadores adicionales que necesite) y su servidor nginx ahora debería comenzar con el valor que proporcionó en la sección “entorno” de su docker-compose.yml

Como se mencionó en la solución anterior, también puede definir su propio punto de entrada, sin embargo, esta solución también ha demostrado funcionar bastante bien y mantiene todo contenido en un solo archivo de configuración, lo que me brinda la capacidad de ejecutar una pila de servicios directamente desde git con nada más que un archivo docker-compose.yml.

Un gran agradecimiento a todos los que se tomaron el tiempo para prepararse para esto, y bellackn por tomarse el tiempo para ayudarme a resolver el problema.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *