Wednesday, September 17, 2025

Live API URL injection

Let’s set up live API URL injection so you can change backend URL without rebuilding the Angular frontend. This is super useful for Docker because the container just reads env variables at runtime.


πŸ”Ή Step 1: Use env.js instead of Angular’s static environment.ts

Already we created src/assets/env.js:

(function(window) {
  window["env"] = window["env"] || {};
  window["env"]["API_URL"] = "${API_URL}";
})(this);

This file will get replaced with real env vars when the container starts.


πŸ”Ή Step 2: Modify Angular ApiService

Update src/app/services/api.service.ts:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ApiService {
  private apiUrl = (window as any)["env"]?.API_URL || "http://localhost:8000";

  constructor(private http: HttpClient) {}

  getRecommendation(payload: any): Observable<any> {
    return this.http.post(`${this.apiUrl}/recommend`, payload);
  }

  chat(payload: any): Observable<any> {
    return this.http.post(`${this.apiUrl}/chat`, payload);
  }
}

πŸ”Ή Step 3: Add an Entrypoint Script in Docker

Create frontend/docker-entrypoint.sh:

#!/bin/sh

# Replace placeholder vars in env.js with real env vars
echo "Injecting runtime environment variables..."
sed -i "s|\${API_URL}|${API_URL:-http://localhost:8000}|g" /usr/share/nginx/html/assets/env.js

exec "$@"

Make it executable:

chmod +x frontend/docker-entrypoint.sh

πŸ”Ή Step 4: Update Frontend Dockerfile

Modify frontend/Dockerfile:

# Stage 1: Build Angular app
FROM node:18-slim as build

WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build -- --configuration production

# Stage 2: Serve with Nginx
FROM nginx:alpine

# Copy build output
COPY --from=build /app/dist/frontend /usr/share/nginx/html

# Copy custom entrypoint
COPY docker-entrypoint.sh /docker-entrypoint.sh
RUN chmod +x /docker-entrypoint.sh

# Copy nginx config
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80

ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

πŸ”Ή Step 5: Update docker-compose.yml

version: "3.9"

services:
  backend:
    build: .
    container_name: company-recommender-backend
    ports:
      - "8000:8000"
    environment:
      - OLLAMA_URL=http://ollama:11434
    depends_on:
      - ollama

  ollama:
    image: ollama/ollama:latest
    container_name: ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama

  frontend:
    build: ./frontend
    container_name: company-recommender-frontend
    ports:
      - "3000:80"
    environment:
      - API_URL=http://backend:8000
    depends_on:
      - backend

volumes:
  ollama_data:

✅ Final Behavior

  • At runtime, when you start the container, docker-entrypoint.sh injects API_URL into env.js.

  • Your Angular app reads from window.env.API_URL.

  • You can point the frontend to a different backend without rebuilding the Angular image.

Example:

docker-compose up --build

Frontend → http://localhost:3000
Backend → http://localhost:8000
Ollama → http://localhost:11434


πŸ‘‰ Do you want me to also add an NGINX reverse proxy in front (so that frontend and backend are served under one domain, e.g. /api), or keep them on separate ports (3000 + 8000)?

No comments:

Post a Comment

Document for Docker + nginx + HTTPS setup for Company Recommender

Docker + nginx + HTTPS setup for Company Recommender This document contains a ready-to-use Docker deployment for your FastAPI backend and An...