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

Índice
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