From 0fda6d0a2caebb243ff3ce3ce3f5a1cbc82c001d Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 18:01:32 +0100 Subject: [PATCH 01/15] feat(frontend): Updated Environment injectino method to support dynamic env variables in frontend --- .env | 8 +++--- .github/workflows/Bump App Version.yml | 13 +++------- .github/workflows/Tag and Release.yml | 7 +----- README.md | 35 +++++++++++--------------- docker-compose.yml | 14 +++++------ frontend/Dockerfile | 14 +++++------ frontend/components/Settings.tsx | 4 +-- frontend/components/Sidebar.tsx | 14 +++++------ frontend/components/Viewer3D.tsx | 2 +- frontend/env.sh | 15 +++++++++++ frontend/services/api.ts | 24 ++++++++++-------- frontend/types.ts | 19 +++++++------- frontend/vite.config.ts | 12 ++++++--- 13 files changed, 93 insertions(+), 88 deletions(-) create mode 100644 frontend/env.sh diff --git a/.env b/.env index 6f74106..731ef8e 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -BASE_URL=http://192.168.0.17 -WWW_PORT=8989 -API_PORT=8988 -SEMVER=0.4.4 +APP_URL=http://192.168.0.17:8999 +API_URL=http://192.168.0.17:8998 +APP_PORT=8999 +API_PORT=8998 diff --git a/.github/workflows/Bump App Version.yml b/.github/workflows/Bump App Version.yml index c77994c..6c78fe2 100644 --- a/.github/workflows/Bump App Version.yml +++ b/.github/workflows/Bump App Version.yml @@ -1,6 +1,9 @@ name: Bump App Semver on: + push: + branches: + - "main" pull_request: types: - closed @@ -27,14 +30,6 @@ jobs: with: scheme: conventional_commits - - name: Find and Replace in env - uses: thiagodnf/string-replacer@v1.0.2 - with: - find: "SEMVER=.+" - replace: "SEMVER=${{ steps.version.outputs.version }}" - include: | - .env - - name: Find and Replace in package uses: thiagodnf/string-replacer@v1.0.2 with: @@ -47,4 +42,4 @@ jobs: uses: EndBug/add-and-commit@v9 with: message: ${{ github.event.pull_request.title }} - add: '[".env", "frontend/package.json"]' + add: '["frontend/package.json"]' diff --git a/.github/workflows/Tag and Release.yml b/.github/workflows/Tag and Release.yml index 8e35e18..cd32f93 100644 --- a/.github/workflows/Tag and Release.yml +++ b/.github/workflows/Tag and Release.yml @@ -1,11 +1,6 @@ name: Tag and Release on: - push: - branches: - - 'main' - paths: - - '.env' workflow_dispatch: jobs: @@ -22,7 +17,7 @@ jobs: id: version with: scheme: conventional_commits - + - name: Tag and Release uses: BrandonStudio/tag-and-release@v1 with: diff --git a/README.md b/README.md index 5c56216..ad75d14 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,6 @@ [![Docker Frontend CI](https://img.shields.io/github/actions/workflow/status/moddroid94/STLVault/Docker%20Backend%20CI.yml?style=for-the-badge&logo=docker&label=Backend)](https://github.com/moddroid94/STLVault/actions/workflows/Docker%20Backend%20CI.yml) [![Docker Pulls](https://img.shields.io/docker/pulls/moddroid94/stlvault-frontend?style=for-the-badge&logo=docker)](https://hub.docker.com/u/moddroid94) - ![License](https://img.shields.io/badge/License-MIT-green?style=for-the-badge) **STLVault** is a containerized 3D Model library manager and organizer, designed specifically for 3D printing enthusiasts. It provides a clean, modern web interface to manage your growing collection of STL, STEP, and 3MF files. @@ -49,7 +48,6 @@ ![Model Viewer/Info Preview](https://github.com/user-attachments/assets/db0c4141-51f6-408d-a6c5-9b3df20a3fc7)![ModelViewer2](https://github.com/user-attachments/assets/dc470ef9-0cf3-4f08-b60d-3985d2461576) ![Setting Page](https://github.com/user-attachments/assets/23c703ce-73b0-43bb-9ff4-f4a64c5f7147) - --- ## 🚀 Deployment @@ -64,9 +62,9 @@ services: image: moddroid94/stlvault-backend:latest pull_policy: build environment: - - FILE_STORAGE=/app/uploads - - DB_PATH=/app/data/data.db - - WEBUI_URL=http://192.168.178.21:8999 + - FILE_STORAGE: "/app/uploads" #DO NOT CHANGE, MODIFY THE BINDS + - DB_PATH: "/app/data/data.db" #DO NOT CHANGE, MODIFY THE BINDS + - WEBUI_URL: "${APP_URL}" ports: - '8998:8080' volumes: @@ -76,6 +74,9 @@ services: stlvfrontend: image: moddroid94/stlvault-frontend:latest pull_policy: build + environment: + - TERA_API_URL: "${API_URL}" + - TERA_APP_URL: "${APP_URL}" volumes: - node_modules:/app/node_modules ports: @@ -97,14 +98,14 @@ volumes: ``` 2. **Configure Environment:** - Review the `stack.env` file. You can modify the ports or URL if necessary, don't change the SEMVER tag. + Review the `stack.env` file. You can modify the ports/URL if necessary. ```bash # stack.env example - BASE_URL=http://0.0.0.0 - WWW_PORT=8989 - API_PORT=8988 - SEMVER=x.x.x + APP_URL=http://192.168.0.17:8999 + API_URL=http://192.168.0.17:8998 + APP_PORT=8999 + API_PORT=8998 ``` 3. **Start the Stack:** @@ -114,22 +115,16 @@ volumes: ``` 4. **Access the App:** - Open your browser and navigate to `http://localhost:8989` (or the port you configured). + Open your browser and navigate to `http://localhost:8999` (or the port you configured). -### Portainer +### GitOps (Deploy from Repo) -You can deploy STLVault directly from Portainer using the repository as a stack source. +You can deploy STLVault directly from any git deploy compatible docker manager using the repository as a stack source. 1. Create a new **Stack**. 2. Select **Repository** as the build method. 3. Enter the repository URL: `https://github.com/moddroid94/STLVault`. -4. **Environment Variables:** Define the variables below in the Portainer UI (variable substitution will automatically update `stack.env`). - - | Variable | Default | Description | - | :--------- | :--------------- | :-------------------------------- | - | `BASE_URL` | `http://0.0.0.0` | The base URL for the application. | - | `WWW_PORT` | `8989` | Port for the Frontend Web UI. | - | `API_PORT` | `8988` | Port for the Backend API. | +4. **Environment Variables:** Define the environment variables in the Docker Manager UI. --- diff --git a/docker-compose.yml b/docker-compose.yml index 99d36bf..27ab79b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,9 +4,9 @@ services: context: ./backend pull_policy: build environment: - - FILE_STORAGE=/app/uploads - - DB_PATH=/app/data/data.db - - WEBUI_URL=${BASE_URL}:${WWW_PORT} + - FILE_STORAGE: "/app/uploads" #DO NOT CHANGE, MODIFY THE BINDS + - DB_PATH: "/app/data/data.db" #DO NOT CHANGE, MODIFY THE BINDS + - WEBUI_URL: "${APP_URL}" ports: - "${API_PORT}:8080" volumes: @@ -16,14 +16,14 @@ services: frontend: build: context: ./frontend - args: - - VITE_APP_API=${BASE_URL}:${API_PORT} - - VITE_APP_TAG=${SEMVER} + environment: + - TERA_API_URL: "${API_URL}" + - TERA_APP_URL: "${APP_URL}" pull_policy: build volumes: - node_modules:/app/node_modules ports: - - "${WWW_PORT}:5173" + - "${APP_PORT}:5173" depends_on: - backend restart: always diff --git a/frontend/Dockerfile b/frontend/Dockerfile index bd9cc35..a2094bf 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,12 +1,5 @@ FROM node:22-alpine -# Set env variable -ARG VITE_APP_API -ENV VITE_APP_API=$VITE_APP_API - -ARG VITE_APP_TAG -ENV VITE_APP_TAG=$VITE_APP_TAG - WORKDIR /app COPY package.json . @@ -19,4 +12,11 @@ RUN npm run build EXPOSE 5173 +# Copy the runtime injection script into the container +COPY env.sh /docker-entrypoint.d/env.sh +RUN dos2unix /docker-entrypoint.d/env.sh +RUN chmod +x /docker-entrypoint.d/env.sh + +# Let Docker run your script before starting Nginx +ENTRYPOINT ["/docker-entrypoint.sh"] CMD [ "npm", "run", "preview" ] diff --git a/frontend/components/Settings.tsx b/frontend/components/Settings.tsx index c9d3e3f..e089260 100644 --- a/frontend/components/Settings.tsx +++ b/frontend/components/Settings.tsx @@ -37,7 +37,7 @@ const Settings: React.FC = ({ onBack }) => { }); const [selectedApiPort, setSelectedApiPort] = useState(() => { - const envport = import.meta.env.VITE_APP_API; + const envport = import.meta.env.VITE_API_URL; const port = localStorage.getItem("api-port-override"); if (port) { setApiPortStatus(true); @@ -184,8 +184,6 @@ const Settings: React.FC = ({ onBack }) => { - - diff --git a/frontend/components/Sidebar.tsx b/frontend/components/Sidebar.tsx index c9ba9c1..33d4596 100644 --- a/frontend/components/Sidebar.tsx +++ b/frontend/components/Sidebar.tsx @@ -36,7 +36,7 @@ import Button from "@mui/material/Button"; import OutlinedInput from "@mui/material/OutlinedInput"; import Badge from "@mui/material/Badge"; -const APP_TAG = import.meta.env.VITE_APP_TAG || __APP_VERSION__ || "dev"; +const APP_TAG = import.meta.env.VITE_APP_TAG || "dev"; interface SidebarProps { folders: Folder[]; @@ -75,7 +75,7 @@ const Sidebar: React.FC = ({ const [expandedIds, setExpandedIds] = useState>(new Set()); const [editingId, setEditingId] = useState(null); const [creatingSubfolderId, setCreatingSubfolderId] = useState( - null + null, ); const [dragTargetId, setDragTargetId] = useState(null); @@ -89,7 +89,7 @@ const Sidebar: React.FC = ({ e.preventDefault(); // Prevent text selection setIsResizing(true); }, - [isDesktopVariant] + [isDesktopVariant], ); // Calculate direct counts only (not recursive, matching file system behavior usually) @@ -297,7 +297,7 @@ const Sidebar: React.FC = ({ onClick={onPlusClick} aria-label="select item" size="small" - sx={{ color: 'grey.300' }} + sx={{ color: "grey.300" }} > @@ -306,7 +306,7 @@ const Sidebar: React.FC = ({ aria-label="select item" size="small" edge="end" - sx={{ color: 'grey.300' }} + sx={{ color: "grey.300" }} > @@ -317,7 +317,7 @@ const Sidebar: React.FC = ({ const CustomTreeItem = React.forwardRef(function CustomTreeItem( props: TreeItemProps, - ref: React.Ref + ref: React.Ref, ) { const { interactions, status } = useTreeItemUtils({ itemId: props.itemId, @@ -325,7 +325,7 @@ const Sidebar: React.FC = ({ }); const handleContentClick: UseTreeItemContentSlotOwnProps["onClick"] = ( - event + event, ) => { onSelectFolder(props.itemId); }; diff --git a/frontend/components/Viewer3D.tsx b/frontend/components/Viewer3D.tsx index 319e9d5..eb23873 100644 --- a/frontend/components/Viewer3D.tsx +++ b/frontend/components/Viewer3D.tsx @@ -36,7 +36,7 @@ let API_BASE_URL = ""; if (localStorage.getItem("api-port-override")) { API_BASE_URL = localStorage.getItem("api-port-override"); } else { - const url = import.meta.env.VITE_APP_API; + const url = import.meta.env.VITE_API_URL; API_BASE_URL = url; } diff --git a/frontend/env.sh b/frontend/env.sh new file mode 100644 index 0000000..37d0670 --- /dev/null +++ b/frontend/env.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env sh + +# Set the exit flag to exit immediately if any command fails +set -e + + +# Iterate through each environment variable that starts with APP_PREFIX +env | grep "^${TERA_}" | while IFS='=' read -r key value; do + # Display the variable being replaced + echo " • Replacing ${key} → ${value}" + + # Use find and sed to replace the variable in all files within the directory + find "/app" -type f -name 'vite.config.ts' \ + -exec sed -i "s|${key}|${value}|g" {} + +done \ No newline at end of file diff --git a/frontend/services/api.ts b/frontend/services/api.ts index d64f1fd..0018284 100644 --- a/frontend/services/api.ts +++ b/frontend/services/api.ts @@ -6,7 +6,7 @@ let API_BASE_URL = ""; if (localStorage.getItem("api-port-override")) { API_BASE_URL = localStorage.getItem("api-port-override") + "/api"; } else { - const url = import.meta.env.VITE_APP_API + "/api"; + const url = import.meta.env.VITE_API_URL + "/api"; API_BASE_URL = url; } @@ -23,7 +23,7 @@ export const api = { // 2. CREATE Folder createFolder: async ( name: string, - parentId: string | null = null + parentId: string | null = null, ): Promise => { const res = await fetch(`${API_BASE_URL}/folders`, { method: "POST", @@ -66,7 +66,7 @@ export const api = { file: File, folderId: string, thumbnail?: string, - tags: string[] = [] + tags: string[] = [], ): Promise => { const formData = new FormData(); formData.append("file", file); @@ -86,7 +86,7 @@ export const api = { // 7. UPDATE Model updateModel: async ( id: string, - updates: Partial + updates: Partial, ): Promise => { const res = await fetch(`${API_BASE_URL}/models/${id}`, { method: "PATCH", @@ -187,7 +187,14 @@ export const api = { const res = await fetch(`${API_BASE_URL}/printables/importid`, { method: "POST", headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ id, name, parentId, previewPath, folderId, typeName }), + body: JSON.stringify({ + id, + name, + parentId, + previewPath, + folderId, + typeName, + }), }); if (!res.ok) throw new Error("Import failed"); return res.json(); @@ -197,7 +204,7 @@ export const api = { replaceModelFile: async ( id: string, file: File, - thumbnail?: string + thumbnail?: string, ): Promise => { const formData = new FormData(); formData.append("file", file); @@ -212,10 +219,7 @@ export const api = { }, // 14a. REPLACE FILE - replaceModelThumbnail: async ( - id: string, - file: File, - ): Promise => { + replaceModelThumbnail: async (id: string, file: File): Promise => { const formData = new FormData(); formData.append("file", file); diff --git a/frontend/types.ts b/frontend/types.ts index 9023097..2b76955 100644 --- a/frontend/types.ts +++ b/frontend/types.ts @@ -1,14 +1,13 @@ - // Vite environment variables type declaration declare global { + interface ImportMetaEnv { + readonly VITE_APP_TAG: string; + readonly VITE_API_URL: string; + } + interface ImportMeta { - env: { - VITE_APP_TAG: string; - [key: string]: any; - }; + readonly env: ImportMetaEnv; } - - const __APP_VERSION__: string; } export interface Folder { @@ -46,8 +45,8 @@ export interface StorageStats { } export enum ViewMode { - GRID = 'GRID', - LIST = 'LIST', + GRID = "GRID", + LIST = "LIST", } export type AppState = { @@ -56,4 +55,4 @@ export type AppState = { currentFolderId: string; selectedModelId: string | null; sidebarOpen: boolean; -}; \ No newline at end of file +}; diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 5ddb6a2..fa315a0 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -6,22 +6,26 @@ import react from "@vitejs/plugin-react"; export default defineConfig(({ mode }) => { const env = loadEnv(mode, ".", ""); const pkgJson = JSON.parse( - fs.readFileSync(new URL("./package.json", import.meta.url), "utf-8") + fs.readFileSync(new URL("./package.json", import.meta.url), "utf-8"), ); - const appVersion = env.VITE_APP_TAG || pkgJson.version || "dev"; + const appVersion = pkgJson.version || "dev"; + const APP_URL = "TERA_APP_URL"; + const API_URL = "TERA_API_URL"; return { base: "/", preview: { port: 5173, + allowedHosts: [JSON.stringify(APP_URL)], }, server: { port: 5173, host: "0.0.0.0", }, - plugins: [react()], define: { - __APP_VERSION__: JSON.stringify(appVersion), + "import.meta.env.VITE_APP_TAG": JSON.stringify(appVersion), + "import.meta.env.VITE_API_URL": JSON.stringify(API_URL), }, + plugins: [react()], resolve: { alias: { "@": path.resolve(__dirname, "."), From db6c5b5eec146dd80f190715f179ca68a52877e8 Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 18:06:48 +0100 Subject: [PATCH 02/15] fix(frontend): fixed string mapping in docker-compose and readme example --- README.md | 4 ++-- docker-compose.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ad75d14..d6e0cbd 100644 --- a/README.md +++ b/README.md @@ -62,8 +62,8 @@ services: image: moddroid94/stlvault-backend:latest pull_policy: build environment: - - FILE_STORAGE: "/app/uploads" #DO NOT CHANGE, MODIFY THE BINDS - - DB_PATH: "/app/data/data.db" #DO NOT CHANGE, MODIFY THE BINDS + - FILE_STORAGE=/app/uploads #DO NOT CHANGE, MODIFY THE BINDS + - DB_PATH=/app/data/data.db #DO NOT CHANGE, MODIFY THE BINDS - WEBUI_URL: "${APP_URL}" ports: - '8998:8080' diff --git a/docker-compose.yml b/docker-compose.yml index 27ab79b..9f21444 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,8 +4,8 @@ services: context: ./backend pull_policy: build environment: - - FILE_STORAGE: "/app/uploads" #DO NOT CHANGE, MODIFY THE BINDS - - DB_PATH: "/app/data/data.db" #DO NOT CHANGE, MODIFY THE BINDS + - FILE_STORAGE=/app/uploads #DO NOT CHANGE, MODIFY THE BINDS + - DB_PATH=/app/data/data.db #DO NOT CHANGE, MODIFY THE BINDS - WEBUI_URL: "${APP_URL}" ports: - "${API_PORT}:8080" From a9da6ca63c523304ffbc46cf6dcff0fd967a5c0a Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 18:08:11 +0100 Subject: [PATCH 03/15] fix(frontend): possible fix to string mapping error --- docker-compose.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 9f21444..c6b295d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,8 +4,8 @@ services: context: ./backend pull_policy: build environment: - - FILE_STORAGE=/app/uploads #DO NOT CHANGE, MODIFY THE BINDS - - DB_PATH=/app/data/data.db #DO NOT CHANGE, MODIFY THE BINDS + - FILE_STORAGE: /app/uploads #DO NOT CHANGE, MODIFY THE BINDS + - DB_PATH: /app/data/data.db #DO NOT CHANGE, MODIFY THE BINDS - WEBUI_URL: "${APP_URL}" ports: - "${API_PORT}:8080" From 3b6afa30495fc7864566873447118a9f16027f76 Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 18:10:45 +0100 Subject: [PATCH 04/15] fix(frontend):fix for docker mapping --- docker-compose.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index c6b295d..93fe8be 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,9 +4,9 @@ services: context: ./backend pull_policy: build environment: - - FILE_STORAGE: /app/uploads #DO NOT CHANGE, MODIFY THE BINDS - - DB_PATH: /app/data/data.db #DO NOT CHANGE, MODIFY THE BINDS - - WEBUI_URL: "${APP_URL}" + - FILE_STORAGE=/app/uploads #DO NOT CHANGE, MODIFY THE BINDS + - DB_PATH=/app/data/data.db #DO NOT CHANGE, MODIFY THE BINDS + - WEBUI_URL=${APP_URL} ports: - "${API_PORT}:8080" volumes: @@ -17,8 +17,8 @@ services: build: context: ./frontend environment: - - TERA_API_URL: "${API_URL}" - - TERA_APP_URL: "${APP_URL}" + - TERA_API_URL=${API_URL} + - TERA_APP_URL=${APP_URL} pull_policy: build volumes: - node_modules:/app/node_modules From 665db51abb32235e8a105deac89ba9776c77ad19 Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 18:19:53 +0100 Subject: [PATCH 05/15] fix(frontend): fixed entrypoint for docker container --- frontend/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/Dockerfile b/frontend/Dockerfile index a2094bf..eb17f4a 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -18,5 +18,5 @@ RUN dos2unix /docker-entrypoint.d/env.sh RUN chmod +x /docker-entrypoint.d/env.sh # Let Docker run your script before starting Nginx -ENTRYPOINT ["/docker-entrypoint.sh"] +ENTRYPOINT ["/docker-entrypoint.d/env.sh"] CMD [ "npm", "run", "preview" ] From 9e8f1d15018f3fc29ca2a21979136faa77456032 Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 18:30:05 +0100 Subject: [PATCH 06/15] fix(frontend): fix for entrypoint command --- frontend/env.sh | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/frontend/env.sh b/frontend/env.sh index 37d0670..8580961 100644 --- a/frontend/env.sh +++ b/frontend/env.sh @@ -1,15 +1,8 @@ -#!/usr/bin/env sh - -# Set the exit flag to exit immediately if any command fails -set -e - - -# Iterate through each environment variable that starts with APP_PREFIX -env | grep "^${TERA_}" | while IFS='=' read -r key value; do - # Display the variable being replaced - echo " • Replacing ${key} → ${value}" - - # Use find and sed to replace the variable in all files within the directory - find "/app" -type f -name 'vite.config.ts' \ - -exec sed -i "s|${key}|${value}|g" {} + -done \ No newline at end of file +#!/bin/sh +# Replace placeholders in JS files with actual env vars +for i in $(env | grep '^TERA_'); do + key=$(echo $i | cut -d '=' -f 1) + value=$(echo $i | cut -d '=' -f 2-) + echo "Replacing $key with $value" + find /app -type f -name 'vite.config.ts' -exec sed -i "s|${key}|${value}|g" '{}' + +done \ No newline at end of file From 98d3eb0da7a63245de4dfb281c8046d5b2ec923e Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 18:36:57 +0100 Subject: [PATCH 07/15] fix(frontend): fixed entrypoint script --- frontend/Dockerfile | 2 -- frontend/env.sh | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/Dockerfile b/frontend/Dockerfile index eb17f4a..fb360f6 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -17,6 +17,4 @@ COPY env.sh /docker-entrypoint.d/env.sh RUN dos2unix /docker-entrypoint.d/env.sh RUN chmod +x /docker-entrypoint.d/env.sh -# Let Docker run your script before starting Nginx ENTRYPOINT ["/docker-entrypoint.d/env.sh"] -CMD [ "npm", "run", "preview" ] diff --git a/frontend/env.sh b/frontend/env.sh index 8580961..cb9ef21 100644 --- a/frontend/env.sh +++ b/frontend/env.sh @@ -5,4 +5,6 @@ for i in $(env | grep '^TERA_'); do value=$(echo $i | cut -d '=' -f 2-) echo "Replacing $key with $value" find /app -type f -name 'vite.config.ts' -exec sed -i "s|${key}|${value}|g" '{}' + -done \ No newline at end of file +done + +exec npm run preview \ No newline at end of file From abcdd574c0590590cd54b4f78ad0cd780da8815e Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 18:44:02 +0100 Subject: [PATCH 08/15] fix(frontend): frontend main app not loading new env var --- frontend/App.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/frontend/App.tsx b/frontend/App.tsx index ac251fe..5446cb1 100644 --- a/frontend/App.tsx +++ b/frontend/App.tsx @@ -73,7 +73,7 @@ const App = () => { ); const [importUrl, setImportUrl] = useState(""); const [importFolderId, setImportFolderId] = useState(""); - + const port = import.meta.env.VITE_API_URL; // Delete Confirmation State const [deleteConfirmState, setDeleteConfirmState] = useState<{ isOpen: boolean; @@ -100,7 +100,6 @@ const App = () => { }; fetchData(); }, []); - const port = localStorage.getItem("api-port-override"); // Refresh storage stats when models change (upload, delete, replace) useEffect(() => { From 8f6ece97af8d0895799b2019061d89d1ca9c57a5 Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 18:53:24 +0100 Subject: [PATCH 09/15] fix(frontend): fixed variables replacement for static build --- frontend/env.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/env.sh b/frontend/env.sh index cb9ef21..df98523 100644 --- a/frontend/env.sh +++ b/frontend/env.sh @@ -4,7 +4,7 @@ for i in $(env | grep '^TERA_'); do key=$(echo $i | cut -d '=' -f 1) value=$(echo $i | cut -d '=' -f 2-) echo "Replacing $key with $value" - find /app -type f -name 'vite.config.ts' -exec sed -i "s|${key}|${value}|g" '{}' + + find /app/dist -type f -name '*.js' -exec sed -i "s|${key}|${value}|g" '{}' + done exec npm run preview \ No newline at end of file From d08d368463197fe2665459f2e67702c5532ad6d6 Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 19:11:18 +0100 Subject: [PATCH 10/15] fix(frontend): fixed updating config.ts to allow for custom host --- frontend/env.sh | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/frontend/env.sh b/frontend/env.sh index df98523..a42c7c8 100644 --- a/frontend/env.sh +++ b/frontend/env.sh @@ -3,8 +3,13 @@ for i in $(env | grep '^TERA_'); do key=$(echo $i | cut -d '=' -f 1) value=$(echo $i | cut -d '=' -f 2-) - echo "Replacing $key with $value" + echo "Replacing static $key with $value" find /app/dist -type f -name '*.js' -exec sed -i "s|${key}|${value}|g" '{}' + done - +for i in $(env | grep '^TERA_'); do + key=$(echo $i | cut -d '=' -f 1) + value=$(echo $i | cut -d '=' -f 2-) + echo "Replacing config $key with $value" + find /app -type f -name 'vite.config.ts' -exec sed -i "s|${key}|${value}|g" '{}' + +done exec npm run preview \ No newline at end of file From f74f4d4bb90bab4d2860b5db835ed5833dc79956 Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 19:19:49 +0100 Subject: [PATCH 11/15] fix(frotend): fixed vite.config.ts placeholder value --- frontend/vite.config.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index fa315a0..462cc57 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -9,13 +9,11 @@ export default defineConfig(({ mode }) => { fs.readFileSync(new URL("./package.json", import.meta.url), "utf-8"), ); const appVersion = pkgJson.version || "dev"; - const APP_URL = "TERA_APP_URL"; - const API_URL = "TERA_API_URL"; return { base: "/", preview: { port: 5173, - allowedHosts: [JSON.stringify(APP_URL)], + allowedHosts: ["TERA_APP_URL"], }, server: { port: 5173, @@ -23,7 +21,7 @@ export default defineConfig(({ mode }) => { }, define: { "import.meta.env.VITE_APP_TAG": JSON.stringify(appVersion), - "import.meta.env.VITE_API_URL": JSON.stringify(API_URL), + "import.meta.env.VITE_API_URL": "TERA_API_URL", }, plugins: [react()], resolve: { From c4eb5d279e832efa0578faa0f04bcc5af533464d Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 19:23:05 +0100 Subject: [PATCH 12/15] fix(frontend): reverted reong replacement for env vars --- frontend/vite.config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 462cc57..2206044 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -9,6 +9,7 @@ export default defineConfig(({ mode }) => { fs.readFileSync(new URL("./package.json", import.meta.url), "utf-8"), ); const appVersion = pkgJson.version || "dev"; + const API_URL = "TERA_API_URL"; return { base: "/", preview: { @@ -21,7 +22,7 @@ export default defineConfig(({ mode }) => { }, define: { "import.meta.env.VITE_APP_TAG": JSON.stringify(appVersion), - "import.meta.env.VITE_API_URL": "TERA_API_URL", + "import.meta.env.VITE_API_URL": JSON.stringify(API_URL), }, plugins: [react()], resolve: { From 503e9fc16ae6c6a30aa0ec8d45cf871ec6c703b6 Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 19:30:52 +0100 Subject: [PATCH 13/15] chore(backend): added env vars for backend folder bindings. as: UPLOAD_PATH DATA_PATH chore(readme):updated gitops deploy guide --- README.md | 2 ++ docker-compose.yml | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d6e0cbd..f786c93 100644 --- a/README.md +++ b/README.md @@ -106,6 +106,8 @@ volumes: API_URL=http://192.168.0.17:8998 APP_PORT=8999 API_PORT=8998 + UPLOAD_PATH=/your/mount/path + DATA_PATH=/your/mount/otherpath ``` 3. **Start the Stack:** diff --git a/docker-compose.yml b/docker-compose.yml index 93fe8be..81f0353 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,8 +10,8 @@ services: ports: - "${API_PORT}:8080" volumes: - - ./backend/uploads:/app/uploads - - ./backend/data:/app/data + - ${UPLOAD_PATH}:/app/uploads + - ${DATA_PATH}:/app/data restart: always frontend: build: From d61952d1d79da9763f204ed9ac952277b9a89860 Mon Sep 17 00:00:00 2001 From: 0x4B1D Date: Thu, 26 Feb 2026 19:34:47 +0100 Subject: [PATCH 14/15] Update README to reference .env instead of stack.env --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f786c93..6fdcc62 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ volumes: ``` 2. **Configure Environment:** - Review the `stack.env` file. You can modify the ports/URL if necessary. + Review the `.env` file. You can modify the ports/URL if necessary. ```bash # stack.env example From 81f1f2df473b793f11a6c884c876aa416aef05a4 Mon Sep 17 00:00:00 2001 From: moddroid94 Date: Thu, 26 Feb 2026 19:38:20 +0100 Subject: [PATCH 15/15] fix(CI): fixed possible recursive call in bump version action --- .github/workflows/Bump App Version.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/Bump App Version.yml b/.github/workflows/Bump App Version.yml index 6c78fe2..d775a62 100644 --- a/.github/workflows/Bump App Version.yml +++ b/.github/workflows/Bump App Version.yml @@ -4,6 +4,8 @@ on: push: branches: - "main" + paths-ignore: + - "frontend/package.json" pull_request: types: - closed