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.