From 5999bc591c4c23be050db908bab65f80c9544136 Mon Sep 17 00:00:00 2001 From: s8613 Date: Sun, 15 Jun 2025 16:50:09 +0200 Subject: [PATCH 1/2] Added dynamic changing host logic. --- project/docker-compose.yml | 3 +++ project/frontend/Dockerfile | 13 +++++++++++ project/frontend/docker/docker-entrypoint.sh | 23 +++++++++++++++++++ .../frontend/src/components/ConfigTable.tsx | 5 ++-- .../frontend/src/components/UploadPage.tsx | 3 ++- project/frontend/src/components/pdfViewer.tsx | 3 ++- project/frontend/src/routes/config-add.tsx | 5 ++-- .../src/routes/config-detail.$kpiId.tsx | 5 ++-- project/frontend/src/socket.ts | 3 ++- project/frontend/src/util/api.ts | 10 +++++--- 10 files changed, 61 insertions(+), 12 deletions(-) create mode 100644 project/frontend/docker/docker-entrypoint.sh diff --git a/project/docker-compose.yml b/project/docker-compose.yml index 3cfe028..703914a 100644 --- a/project/docker-compose.yml +++ b/project/docker-compose.yml @@ -4,6 +4,9 @@ services: context: frontend ports: - 8080:80 + environment: + - API_HOST=http://coordinator:5000 + db: image: postgres:17-alpine env_file: diff --git a/project/frontend/Dockerfile b/project/frontend/Dockerfile index 617e964..69ae868 100644 --- a/project/frontend/Dockerfile +++ b/project/frontend/Dockerfile @@ -8,8 +8,21 @@ RUN bun install --frozen-lockfile COPY . . +# dummy environment variable for build - DONT CHANGE!!! +ENV VITE_API_HOST=SECRET_HOST + RUN bun run build FROM nginx:1.28.0-alpine3.21 + +# default environment variable that will be replaced at runtime +ENV API_HOST=http://localhost:5050 + COPY docker/nginx.conf /etc/nginx/conf.d/default.conf COPY --from=base /usr/src/app/dist /usr/share/nginx/html + +# entrypoint script +COPY docker/docker-entrypoint.sh /docker-entrypoint.sh +RUN chmod +x /docker-entrypoint.sh + +CMD ["/docker-entrypoint.sh"] \ No newline at end of file diff --git a/project/frontend/docker/docker-entrypoint.sh b/project/frontend/docker/docker-entrypoint.sh new file mode 100644 index 0000000..fc1b6be --- /dev/null +++ b/project/frontend/docker/docker-entrypoint.sh @@ -0,0 +1,23 @@ +#!/bin/sh + +# Replace API host in built JavaScript files +echo "Replacing SECRET_HOST with ${API_HOST}" + +# Replace in main JS files +for i in /usr/share/nginx/html/*.js; do + if [ -f "$i" ]; then + sed -i "s|SECRET_HOST|${API_HOST}|g" "$i" + fi +done + +# Replace in assets folder JS files +for i in /usr/share/nginx/html/assets/*.js; do + if [ -f "$i" ]; then + sed -i "s|SECRET_HOST|${API_HOST}|g" "$i" + fi +done + +echo "Replacement completed. Starting nginx..." + +# Start nginx and replace the shell process +exec nginx -g 'daemon off;' \ No newline at end of file diff --git a/project/frontend/src/components/ConfigTable.tsx b/project/frontend/src/components/ConfigTable.tsx index 74675d7..3b7b6d4 100644 --- a/project/frontend/src/components/ConfigTable.tsx +++ b/project/frontend/src/components/ConfigTable.tsx @@ -5,6 +5,7 @@ import { useEffect, useState } from "react"; import type { Kennzahl } from "../types/kpi"; import { getDisplayType } from "../types/kpi"; import { fetchKennzahlen as fetchK } from "../util/api"; +import { API_HOST } from "../util/api"; export function ConfigTable() { const navigate = useNavigate(); @@ -42,7 +43,7 @@ export function ConfigTable() { try { const response = await fetch( - `http://localhost:5050/api/kpi_setting/${id}`, + `${API_HOST}/api/kpi_setting/${id}`, { method: "PUT", headers: { @@ -79,7 +80,7 @@ export function ConfigTable() { })); const response = await fetch( - `http://localhost:5050/api/kpi_setting/update-kpi-positions`, + `${API_HOST}/api/kpi_setting/update-kpi-positions`, { method: "PUT", headers: { diff --git a/project/frontend/src/components/UploadPage.tsx b/project/frontend/src/components/UploadPage.tsx index 66fe220..20d6f7b 100644 --- a/project/frontend/src/components/UploadPage.tsx +++ b/project/frontend/src/components/UploadPage.tsx @@ -5,6 +5,7 @@ import { useCallback, useEffect, useState } from "react"; import FileUpload from "react-material-file-upload"; import { socket } from "../socket"; import { CircularProgressWithLabel } from "./CircularProgressWithLabel"; +import { API_HOST } from "../util/api"; const PROGRESS = true; @@ -18,7 +19,7 @@ export default function UploadPage() { const uploadFile = useCallback(async () => { const formData = new FormData(); formData.append("file", files[0]); - const response = await fetch("http://localhost:5050/api/pitch_book", { + const response = await fetch(`${API_HOST}/api/pitch_book`, { method: "POST", body: formData, }); diff --git a/project/frontend/src/components/pdfViewer.tsx b/project/frontend/src/components/pdfViewer.tsx index b39421d..972f5f5 100644 --- a/project/frontend/src/components/pdfViewer.tsx +++ b/project/frontend/src/components/pdfViewer.tsx @@ -11,6 +11,7 @@ import type { } from "node_modules/react-pdf/dist/esm/shared/types"; import { socket } from "../socket"; import { highlightPattern } from "../util/highlighting"; +import { API_HOST } from "../util/api"; interface PDFViewerProps { pitchBookId: string; @@ -172,7 +173,7 @@ export default function PDFViewer({ > console.error("Es gab ein Fehler beim Laden des PDFs:", error) diff --git a/project/frontend/src/routes/config-add.tsx b/project/frontend/src/routes/config-add.tsx index b90d7b1..5d536bd 100644 --- a/project/frontend/src/routes/config-add.tsx +++ b/project/frontend/src/routes/config-add.tsx @@ -3,6 +3,7 @@ import { Box, Typography, IconButton } from "@mui/material"; import ArrowBackIcon from "@mui/icons-material/ArrowBack"; import { KPIForm } from "../components/KPIForm"; import type { Kennzahl } from "../types/kpi"; +import { API_HOST } from "../util/api"; export const Route = createFileRoute("/config-add")({ component: ConfigAddPage, @@ -13,7 +14,7 @@ function ConfigAddPage() { const handleSave = async (formData: Partial) => { try { - const existingKPIsResponse = await fetch('http://localhost:5050/api/kpi_setting/'); + const existingKPIsResponse = await fetch(`${API_HOST}/api/kpi_setting/`); const existingKPIs = await existingKPIsResponse.json(); const maxPosition = existingKPIs.length > 0 ? Math.max(...existingKPIs.map((kpi: Kennzahl) => kpi.position)) @@ -25,7 +26,7 @@ function ConfigAddPage() { active: formData.active !== false }; - const response = await fetch('http://localhost:5050/api/kpi_setting/', { + const response = await fetch(`${API_HOST}/api/kpi_setting/`, { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/project/frontend/src/routes/config-detail.$kpiId.tsx b/project/frontend/src/routes/config-detail.$kpiId.tsx index 16ddce9..92a647f 100644 --- a/project/frontend/src/routes/config-detail.$kpiId.tsx +++ b/project/frontend/src/routes/config-detail.$kpiId.tsx @@ -6,6 +6,7 @@ import { useEffect, useState } from "react"; import type { Kennzahl } from "../types/kpi"; import { KPIForm } from "../components/KPIForm"; import { typeDisplayMapping } from "../types/kpi"; +import { API_HOST } from "../util/api"; export const Route = createFileRoute("/config-detail/$kpiId")({ component: KPIDetailPage, @@ -23,7 +24,7 @@ function KPIDetailPage() { const fetchKennzahl = async () => { try { setLoading(true); - const response = await fetch(`http://localhost:5050/api/kpi_setting/${kpiId}`); + const response = await fetch(`${API_HOST}/api/kpi_setting/${kpiId}`); if (!response.ok) { if (response.status === 404) { setError('KPI not found'); @@ -47,7 +48,7 @@ function KPIDetailPage() { const handleSave = async (formData: Partial) => { try { - const response = await fetch(`http://localhost:5050/api/kpi_setting/${kpiId}`, { + const response = await fetch(`${API_HOST}/api/kpi_setting/${kpiId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json', diff --git a/project/frontend/src/socket.ts b/project/frontend/src/socket.ts index 763c173..563ef27 100644 --- a/project/frontend/src/socket.ts +++ b/project/frontend/src/socket.ts @@ -1,6 +1,7 @@ import { io } from "socket.io-client"; +import { API_HOST } from "./util/api"; // "undefined" means the URL will be computed from the `window.location` object // const URL = process.env.NODE_ENV === 'production' ? undefined : 'http://localhost:4000'; -export const socket = io("http://localhost:5050"); +export const socket = io(`${API_HOST}`); diff --git a/project/frontend/src/util/api.ts b/project/frontend/src/util/api.ts index 5a8c3c6..6ba0d6e 100644 --- a/project/frontend/src/util/api.ts +++ b/project/frontend/src/util/api.ts @@ -1,5 +1,9 @@ import type { Kennzahl } from "@/types/kpi"; +const API_HOST = import.meta.env.VITE_API_HOST || 'http://localhost:5050'; + +export { API_HOST }; + export const fetchKPI = async ( pitchBookId: string, ): Promise<{ @@ -12,7 +16,7 @@ export const fetchKPI = async ( }[]; }> => { const response = await fetch( - `http://localhost:5050/api/pitch_book/${pitchBookId}`, + `${API_HOST}/api/pitch_book/${pitchBookId}`, ); const data = await response.json(); @@ -43,7 +47,7 @@ export const fetchPutKPI = async ( formData.append("kpi", JSON.stringify(flattenKPIArray(kpi))); const response = await fetch( - `http://localhost:5050/api/pitch_book/${pitchBookId}`, + `${API_HOST}/api/pitch_book/${pitchBookId}`, { method: "PUT", body: formData, @@ -99,7 +103,7 @@ export const flattenKPIArray = (kpi: { }; export const fetchKennzahlen = async (): Promise => { - const response = await fetch("http://localhost:5050/api/kpi_setting/"); + const response = await fetch(`${API_HOST}/api/kpi_setting/`); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } From 4b48419622d48e50c1b820c89364de34792bd3c3 Mon Sep 17 00:00:00 2001 From: Jaronim Pracht Date: Sun, 15 Jun 2025 18:08:47 +0200 Subject: [PATCH 2/2] Fix host in docker-compose to localhost --- project/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/docker-compose.yml b/project/docker-compose.yml index 703914a..6c2544d 100644 --- a/project/docker-compose.yml +++ b/project/docker-compose.yml @@ -5,7 +5,7 @@ services: ports: - 8080:80 environment: - - API_HOST=http://coordinator:5000 + - API_HOST=http://localhost:5050 db: image: postgres:17-alpine