From 29f2127317a513965f2f6a3f775fa884042c6415 Mon Sep 17 00:00:00 2001 From: shahdlala66 Date: Wed, 6 May 2026 11:32:26 +0200 Subject: [PATCH] feat: docker enterypoint, dockerfile and dynamic var for buid Co-authored-by: Copilot --- Dockerfile | 25 +++++++++++++++++++++++++ angular.json | 11 +++++++++++ docker-entrypoint.sh | 18 ++++++++++++++++++ nginx.conf | 22 ++++++++++++++++++++++ package.json | 3 ++- public/env.template.js | 4 ++++ src/app/core/config.loader.ts | 11 +++++++++++ src/environments/environment.staging.ts | 11 +++++++++++ src/environments/environment.ts | 12 ++++++++---- src/index.html | 1 + 10 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-entrypoint.sh create mode 100644 nginx.conf create mode 100644 public/env.template.js create mode 100644 src/app/core/config.loader.ts create mode 100644 src/environments/environment.staging.ts diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..0aafc7a --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM --platform=$BUILDPLATFORM node:lts-alpine3.23 AS builder + +WORKDIR /app + +COPY package*.json ./ + +RUN npm install +COPY . . +RUN npm run build + +FROM --platform=$TARGETPLATFORM nginx:stable-alpine AS production + +RUN apk add --no-cache gettext + +RUN rm -rf /usr/share/nginx/html/* +COPY --from=builder /app/dist/nowchess-frontend/browser /usr/share/nginx/html + +COPY nginx.conf /etc/nginx/conf.d/default.conf + +COPY public/env.template.js /usr/share/nginx/html/env.template.js +COPY docker-entrypoint.sh /docker-entrypoint.sh +RUN chmod +x /docker-entrypoint.sh + +EXPOSE 80 +ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/angular.json b/angular.json index aafdf64..0077510 100644 --- a/angular.json +++ b/angular.json @@ -58,6 +58,14 @@ ], "outputHashing": "all" }, + "staging": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.staging.ts" + } + ] + }, "development": { "fileReplacements": [ { @@ -83,6 +91,9 @@ "production": { "buildTarget": "nowchess-frontend:build:production" }, + "staging": { + "buildTarget": "nowchess-frontend:build:staging" + }, "development": { "buildTarget": "nowchess-frontend:build:development" } diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..dab211f --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +# Replace placeholders in env.template.js with environment variables and write env.js +TEMPLATE_PATH="/usr/share/nginx/html/env.template.js" +TARGET_PATH="/usr/share/nginx/html/env.js" + +if [ -f "$TEMPLATE_PATH" ]; then + echo "Rendering runtime config from $TEMPLATE_PATH" + echo "Using environment variables:" + printenv + echo "----" + envsubst < "$TEMPLATE_PATH" > "$TARGET_PATH" +else + echo "No runtime template found at $TEMPLATE_PATH, skipping" +fi + +exec nginx -g 'daemon off;' diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..ff4e939 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,22 @@ +server { + listen 80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html; + } + + location /env.js { + root /usr/share/nginx/html; + default_type application/javascript; + expires -1; + add_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/package.json b/package.json index 0882715..37a84ae 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "scripts": { "ng": "ng", "start": "ng serve", - "build": "ng build", + "build": "ng build --configuration production", + "build:staging": "ng build --configuration staging", "watch": "ng build --watch --configuration development", "test": "ng test" }, diff --git a/public/env.template.js b/public/env.template.js new file mode 100644 index 0000000..72477ac --- /dev/null +++ b/public/env.template.js @@ -0,0 +1,4 @@ +window.__RUNTIME_CONFIG__ = { + API_URL: "${API_URL}", + WEBSOCKET_URL: "${WEBSOCKET_URL}" +}; diff --git a/src/app/core/config.loader.ts b/src/app/core/config.loader.ts new file mode 100644 index 0000000..2d10fd5 --- /dev/null +++ b/src/app/core/config.loader.ts @@ -0,0 +1,11 @@ +/** + * Load runtime configuration from window.__RUNTIME_CONFIG__ + * This is injected by docker-entrypoint.sh at container startup + */ +export function loadRuntimeConfig() { + const config = (window as any).__RUNTIME_CONFIG__ || {}; + return { + apiUrl: config.API_URL || '', + wsUrl: config.WEBSOCKET_URL || 'ws://localhost:8080' + }; +} diff --git a/src/environments/environment.staging.ts b/src/environments/environment.staging.ts new file mode 100644 index 0000000..a2f73b6 --- /dev/null +++ b/src/environments/environment.staging.ts @@ -0,0 +1,11 @@ +import { loadRuntimeConfig } from '../app/core/config.loader'; + +const runtimeConfig = loadRuntimeConfig(); + +export const environment = { + production: true, + apiBaseUrl: runtimeConfig.apiUrl || 'https://st.nowchess.janis-eccarius.de', + accountServiceUrl: runtimeConfig.apiUrl || 'https://st.nowchess.janis-eccarius.de', + wsBaseUrl: runtimeConfig.wsUrl || 'wss://st.nowchess.janis-eccarius.de', + apiPath: '/api/board/game' +}; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 8c38733..2478e38 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -1,7 +1,11 @@ +import { loadRuntimeConfig } from '../app/core/config.loader'; + +const runtimeConfig = loadRuntimeConfig(); + export const environment = { - production: true, - apiBaseUrl: '', - accountServiceUrl: '', - wsBaseUrl: 'ws://localhost:8080', + production: false, + apiBaseUrl: runtimeConfig.apiUrl || '', + accountServiceUrl: runtimeConfig.apiUrl || '', + wsBaseUrl: runtimeConfig.wsUrl, apiPath: '/api/board/game' }; diff --git a/src/index.html b/src/index.html index 5f83c38..1d5f35e 100644 --- a/src/index.html +++ b/src/index.html @@ -6,6 +6,7 @@ + -- 2.52.0