Pasar variables de entorno desde Docker a una app en Angular dinámicamente

Pasar variables de entorno desde Docker a una app en Angular dinámicamente

Cuando usamos Angular y Docker, muchas veces se requiere configurar valores, como la URL de la API por ejemplo, de forma dinámica sin la necesidad de cambiar manualmente esto en el código y posteriormente volver a crear la imagen. Por ello, en este articulo se explica como lograr establecer variables de entorno desde Docker y que estas puedan ser obtenidas desde nuestra aplicación web en Angular para utilizarlas.

Paso 1: Configurar los archivos environments.ts en Angular

En estos archivos (alojados en la carpeta “environments”), se van a guardar estas variables de entorno. Sin embargo, por el momento, en este paso solo nos debemos asegurar que se encuentren creados y con valores por defecto (por ejemplo con datos de conexión al localhost):

export const environment = {    
    production: true,
    api_url: 'http://localhost:3000/api'
};

De forma similar para el environment.development.ts.

Paso 2: Creación archivo config.json en Assets

El siguiente paso es crear dentro de la carpeta “assets” de nuestro proyecto en angular, un archivo que le daremos el nombre de “config.json” y tendrá el siguiente contenido:

{
    "api_url": "http://localhost:3000/api"
}  

Puedes darle el contenido por defecto que quieras.

A este archivo modificaremos dinámicamente posteriormente desde un script en bash, con el objetivo de establecer el valor que queramos.

Paso 3: Modificar el main.ts en Angular

Como último paso dentro del código de Angular, debemos tener la siguiente configuración dentro de “main.ts”:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

fetch('/assets/config.json')
  .then((response) => response.json())
  .then((config) => {
    // Inserta las variables de entorno desde el archivo config.json
    environment.api_url = config.api_url || environment.api_url;
    
    platformBrowserDynamic().bootstrapModule(AppModule)
      .catch(err => console.error(err));
  })
  .catch((error) => {
    console.error('Error al cargar el archivo config.json:', error);
    console.warn('Como no se encontro el archivo o hubo un error, se usarán las variables predeterminadas del environment');
    platformBrowserDynamic()
      .bootstrapModule(AppModule)
      .catch((err) => console.error(err));
  });

Básicamente con este código estamos mapeando el contenido que posee “config.json”, en las variables de entorno definidas en angular en el PASO 1 (en los “environments”).

Paso 4: Modificación dinámica de config.json con un script en bash

Para pasar las variables de entorno (que definamos a la hora de realizar la creación del contenedor de Docker), debemos tomarlas y actualizar sus valores en el archivo “config.json” que hemos creado en el PASO 2. Ya no tendría los datos de localhost (como el código de ejemplo del paso 2), sino que se reemplazarían por los que se establecen al realizar el: docker run -e API_URL=’http://ejemplo.com’ …

Debemos crear un archivo, que en este caso llamamos “start.sh”, que va a hacer este proceso:

#!/bin/sh

cat <<EOF > /usr/share/nginx/html/assets/config.json
{
  "api_url": "${API_URL}"
}
EOF

nginx -g 'daemon off;'

En este script de bash, se toma la variable de entorno “API_URL” (que asignamos al ejecutar el comando docker run) y actualiza el contenido del “config.json” ubicado en la carpeta “assets” dentro de nginx. Este último archivo será el que leamos desde Angular en el “main.ts” y allí se asignarán en los “environments.ts” (PASO 3).

Paso 5: Modificación del Dockerfile

Finalmente debemos copiar este nuevo archivo start.sh en la carpeta bin y asignar permisos de ejecución. Que se ejecutará al iniciar el contenedor.

Quedando el Dockerfile de la siguiente manera:

FROM node:22 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build --prod

FROM nginx:stable-alpine
COPY --from=build /app/dist/front-bot /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
COPY start.sh /usr/local/bin/start.sh
RUN chmod +x /usr/local/bin/start.sh

EXPOSE 3000
ENTRYPOINT ["/usr/local/bin/start.sh"]

Pruebas

Para verificar que todo funciona correctamente, puedes crear el contenedor de la siguiente manera:

docker run -p 3000:3000 --name container -e API_URL="http://ejemplo.com/api" imagen

Última actualización el 19-02-2025 por Bruno D’Angelo

Deja un comentario

Tu email no será publicado.