From 5e0159047cd2c9a9987d08d54443ef02cb0f9410 Mon Sep 17 00:00:00 2001 From: Wolfgang Hottgenroth Date: Mon, 1 Dec 2025 14:00:48 +0100 Subject: [PATCH] separation of ui and static --- .woodpecker/build.yml | 1 + .woodpecker/deploy.yml | 1 + apps/static/Dockerfile | 15 +++++ apps/{ui => static}/static/README.md | 0 apps/{ui => static}/static/api-client.js | 0 .../static/apple-touch-icon-114x114.png | Bin .../static/apple-touch-icon-120x120.png | Bin .../static/apple-touch-icon-144x144.png | Bin .../static/apple-touch-icon-152x152.png | Bin .../static/apple-touch-icon-16x16.png | Bin .../static/apple-touch-icon-180x180.png | Bin .../static/apple-touch-icon-32x32.png | Bin .../static/apple-touch-icon-57x57.png | Bin .../static/apple-touch-icon-60x60.png | Bin .../static/apple-touch-icon-72x72.png | Bin .../static/apple-touch-icon-76x76.png | Bin .../static/apple-touch-icon.png | Bin .../static/apple-touch-icon.svg | 0 apps/{ui => static}/static/favicon.svg | 0 .../static/garage-icon-114x114.png | Bin .../static/garage-icon-120x120.png | Bin .../static/garage-icon-144x144.png | Bin .../static/garage-icon-152x152.png | Bin .../static/garage-icon-16x16.png | Bin .../static/garage-icon-180x180.png | Bin .../static/garage-icon-32x32.png | Bin .../static/garage-icon-57x57.png | Bin .../static/garage-icon-60x60.png | Bin .../static/garage-icon-72x72.png | Bin .../static/garage-icon-76x76.png | Bin apps/{ui => static}/static/garage-icon.png | Bin apps/{ui => static}/static/garage-icon.svg | 0 apps/{ui => static}/static/manifest.json | 0 apps/{ui => static}/static/style.css | 0 apps/{ui => static}/static/types.js | 0 apps/ui/Dockerfile | 24 +++---- apps/ui/main.py | 12 +++- apps/ui/templates/dashboard.html | 14 ++-- apps/ui/templates/device.html | 16 ++--- apps/ui/templates/garage.html | 18 +++--- apps/ui/templates/index.html | 14 ++-- apps/ui/templates/room.html | 16 ++--- apps/ui/templates/rooms.html | 18 +++--- deployment/configmap.yaml | 3 +- deployment/ingress.yaml | 17 +++++ deployment/static-deployment.yaml | 61 ++++++++++++++++++ 46 files changed, 162 insertions(+), 68 deletions(-) create mode 100644 apps/static/Dockerfile rename apps/{ui => static}/static/README.md (100%) rename apps/{ui => static}/static/api-client.js (100%) rename apps/{ui => static}/static/apple-touch-icon-114x114.png (100%) rename apps/{ui => static}/static/apple-touch-icon-120x120.png (100%) rename apps/{ui => static}/static/apple-touch-icon-144x144.png (100%) rename apps/{ui => static}/static/apple-touch-icon-152x152.png (100%) rename apps/{ui => static}/static/apple-touch-icon-16x16.png (100%) rename apps/{ui => static}/static/apple-touch-icon-180x180.png (100%) rename apps/{ui => static}/static/apple-touch-icon-32x32.png (100%) rename apps/{ui => static}/static/apple-touch-icon-57x57.png (100%) rename apps/{ui => static}/static/apple-touch-icon-60x60.png (100%) rename apps/{ui => static}/static/apple-touch-icon-72x72.png (100%) rename apps/{ui => static}/static/apple-touch-icon-76x76.png (100%) rename apps/{ui => static}/static/apple-touch-icon.png (100%) rename apps/{ui => static}/static/apple-touch-icon.svg (100%) rename apps/{ui => static}/static/favicon.svg (100%) rename apps/{ui => static}/static/garage-icon-114x114.png (100%) rename apps/{ui => static}/static/garage-icon-120x120.png (100%) rename apps/{ui => static}/static/garage-icon-144x144.png (100%) rename apps/{ui => static}/static/garage-icon-152x152.png (100%) rename apps/{ui => static}/static/garage-icon-16x16.png (100%) rename apps/{ui => static}/static/garage-icon-180x180.png (100%) rename apps/{ui => static}/static/garage-icon-32x32.png (100%) rename apps/{ui => static}/static/garage-icon-57x57.png (100%) rename apps/{ui => static}/static/garage-icon-60x60.png (100%) rename apps/{ui => static}/static/garage-icon-72x72.png (100%) rename apps/{ui => static}/static/garage-icon-76x76.png (100%) rename apps/{ui => static}/static/garage-icon.png (100%) rename apps/{ui => static}/static/garage-icon.svg (100%) rename apps/{ui => static}/static/manifest.json (100%) rename apps/{ui => static}/static/style.css (100%) rename apps/{ui => static}/static/types.js (100%) create mode 100644 deployment/static-deployment.yaml diff --git a/.woodpecker/build.yml b/.woodpecker/build.yml index 5b07a14..690151c 100644 --- a/.woodpecker/build.yml +++ b/.woodpecker/build.yml @@ -7,6 +7,7 @@ matrix: - api - abstraction - rules + - static steps: build-${APP}: diff --git a/.woodpecker/deploy.yml b/.woodpecker/deploy.yml index b74bda9..d98aae1 100644 --- a/.woodpecker/deploy.yml +++ b/.woodpecker/deploy.yml @@ -11,6 +11,7 @@ matrix: - api - abstraction - rules + - static steps: deploy-${APP}: diff --git a/apps/static/Dockerfile b/apps/static/Dockerfile new file mode 100644 index 0000000..bf63572 --- /dev/null +++ b/apps/static/Dockerfile @@ -0,0 +1,15 @@ +# Static assets Dockerfile (minimal webserver for /static only) + +FROM nginx:1.27-alpine + +WORKDIR /usr/share/nginx/html + +# Remove default nginx content +RUN rm -rf ./* + +# Copy only static assets from the UI project +COPY apps/ui/static/ ./ + +EXPOSE 80 + +# Use default nginx config; caller can mount custom config if needed diff --git a/apps/ui/static/README.md b/apps/static/static/README.md similarity index 100% rename from apps/ui/static/README.md rename to apps/static/static/README.md diff --git a/apps/ui/static/api-client.js b/apps/static/static/api-client.js similarity index 100% rename from apps/ui/static/api-client.js rename to apps/static/static/api-client.js diff --git a/apps/ui/static/apple-touch-icon-114x114.png b/apps/static/static/apple-touch-icon-114x114.png similarity index 100% rename from apps/ui/static/apple-touch-icon-114x114.png rename to apps/static/static/apple-touch-icon-114x114.png diff --git a/apps/ui/static/apple-touch-icon-120x120.png b/apps/static/static/apple-touch-icon-120x120.png similarity index 100% rename from apps/ui/static/apple-touch-icon-120x120.png rename to apps/static/static/apple-touch-icon-120x120.png diff --git a/apps/ui/static/apple-touch-icon-144x144.png b/apps/static/static/apple-touch-icon-144x144.png similarity index 100% rename from apps/ui/static/apple-touch-icon-144x144.png rename to apps/static/static/apple-touch-icon-144x144.png diff --git a/apps/ui/static/apple-touch-icon-152x152.png b/apps/static/static/apple-touch-icon-152x152.png similarity index 100% rename from apps/ui/static/apple-touch-icon-152x152.png rename to apps/static/static/apple-touch-icon-152x152.png diff --git a/apps/ui/static/apple-touch-icon-16x16.png b/apps/static/static/apple-touch-icon-16x16.png similarity index 100% rename from apps/ui/static/apple-touch-icon-16x16.png rename to apps/static/static/apple-touch-icon-16x16.png diff --git a/apps/ui/static/apple-touch-icon-180x180.png b/apps/static/static/apple-touch-icon-180x180.png similarity index 100% rename from apps/ui/static/apple-touch-icon-180x180.png rename to apps/static/static/apple-touch-icon-180x180.png diff --git a/apps/ui/static/apple-touch-icon-32x32.png b/apps/static/static/apple-touch-icon-32x32.png similarity index 100% rename from apps/ui/static/apple-touch-icon-32x32.png rename to apps/static/static/apple-touch-icon-32x32.png diff --git a/apps/ui/static/apple-touch-icon-57x57.png b/apps/static/static/apple-touch-icon-57x57.png similarity index 100% rename from apps/ui/static/apple-touch-icon-57x57.png rename to apps/static/static/apple-touch-icon-57x57.png diff --git a/apps/ui/static/apple-touch-icon-60x60.png b/apps/static/static/apple-touch-icon-60x60.png similarity index 100% rename from apps/ui/static/apple-touch-icon-60x60.png rename to apps/static/static/apple-touch-icon-60x60.png diff --git a/apps/ui/static/apple-touch-icon-72x72.png b/apps/static/static/apple-touch-icon-72x72.png similarity index 100% rename from apps/ui/static/apple-touch-icon-72x72.png rename to apps/static/static/apple-touch-icon-72x72.png diff --git a/apps/ui/static/apple-touch-icon-76x76.png b/apps/static/static/apple-touch-icon-76x76.png similarity index 100% rename from apps/ui/static/apple-touch-icon-76x76.png rename to apps/static/static/apple-touch-icon-76x76.png diff --git a/apps/ui/static/apple-touch-icon.png b/apps/static/static/apple-touch-icon.png similarity index 100% rename from apps/ui/static/apple-touch-icon.png rename to apps/static/static/apple-touch-icon.png diff --git a/apps/ui/static/apple-touch-icon.svg b/apps/static/static/apple-touch-icon.svg similarity index 100% rename from apps/ui/static/apple-touch-icon.svg rename to apps/static/static/apple-touch-icon.svg diff --git a/apps/ui/static/favicon.svg b/apps/static/static/favicon.svg similarity index 100% rename from apps/ui/static/favicon.svg rename to apps/static/static/favicon.svg diff --git a/apps/ui/static/garage-icon-114x114.png b/apps/static/static/garage-icon-114x114.png similarity index 100% rename from apps/ui/static/garage-icon-114x114.png rename to apps/static/static/garage-icon-114x114.png diff --git a/apps/ui/static/garage-icon-120x120.png b/apps/static/static/garage-icon-120x120.png similarity index 100% rename from apps/ui/static/garage-icon-120x120.png rename to apps/static/static/garage-icon-120x120.png diff --git a/apps/ui/static/garage-icon-144x144.png b/apps/static/static/garage-icon-144x144.png similarity index 100% rename from apps/ui/static/garage-icon-144x144.png rename to apps/static/static/garage-icon-144x144.png diff --git a/apps/ui/static/garage-icon-152x152.png b/apps/static/static/garage-icon-152x152.png similarity index 100% rename from apps/ui/static/garage-icon-152x152.png rename to apps/static/static/garage-icon-152x152.png diff --git a/apps/ui/static/garage-icon-16x16.png b/apps/static/static/garage-icon-16x16.png similarity index 100% rename from apps/ui/static/garage-icon-16x16.png rename to apps/static/static/garage-icon-16x16.png diff --git a/apps/ui/static/garage-icon-180x180.png b/apps/static/static/garage-icon-180x180.png similarity index 100% rename from apps/ui/static/garage-icon-180x180.png rename to apps/static/static/garage-icon-180x180.png diff --git a/apps/ui/static/garage-icon-32x32.png b/apps/static/static/garage-icon-32x32.png similarity index 100% rename from apps/ui/static/garage-icon-32x32.png rename to apps/static/static/garage-icon-32x32.png diff --git a/apps/ui/static/garage-icon-57x57.png b/apps/static/static/garage-icon-57x57.png similarity index 100% rename from apps/ui/static/garage-icon-57x57.png rename to apps/static/static/garage-icon-57x57.png diff --git a/apps/ui/static/garage-icon-60x60.png b/apps/static/static/garage-icon-60x60.png similarity index 100% rename from apps/ui/static/garage-icon-60x60.png rename to apps/static/static/garage-icon-60x60.png diff --git a/apps/ui/static/garage-icon-72x72.png b/apps/static/static/garage-icon-72x72.png similarity index 100% rename from apps/ui/static/garage-icon-72x72.png rename to apps/static/static/garage-icon-72x72.png diff --git a/apps/ui/static/garage-icon-76x76.png b/apps/static/static/garage-icon-76x76.png similarity index 100% rename from apps/ui/static/garage-icon-76x76.png rename to apps/static/static/garage-icon-76x76.png diff --git a/apps/ui/static/garage-icon.png b/apps/static/static/garage-icon.png similarity index 100% rename from apps/ui/static/garage-icon.png rename to apps/static/static/garage-icon.png diff --git a/apps/ui/static/garage-icon.svg b/apps/static/static/garage-icon.svg similarity index 100% rename from apps/ui/static/garage-icon.svg rename to apps/static/static/garage-icon.svg diff --git a/apps/ui/static/manifest.json b/apps/static/static/manifest.json similarity index 100% rename from apps/ui/static/manifest.json rename to apps/static/static/manifest.json diff --git a/apps/ui/static/style.css b/apps/static/static/style.css similarity index 100% rename from apps/ui/static/style.css rename to apps/static/static/style.css diff --git a/apps/ui/static/types.js b/apps/static/static/types.js similarity index 100% rename from apps/ui/static/types.js rename to apps/static/static/types.js diff --git a/apps/ui/Dockerfile b/apps/ui/Dockerfile index 2e4867e..22e7794 100644 --- a/apps/ui/Dockerfile +++ b/apps/ui/Dockerfile @@ -1,49 +1,41 @@ -# UI Service Dockerfile -# FastAPI + Jinja2 + HTMX Dashboard +# UI Service Dockerfile (Application only, without static files) FROM python:3.14-alpine -# Prevent Python from writing .pyc files and enable unbuffered output ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ UI_PORT=8002 \ API_BASE=http://api:8001 \ - BASE_PATH="" + BASE_PATH="" \ + STATIC_BASE=http://static:8080 -# Create non-root user RUN addgroup -g 10001 -S app && \ adduser -u 10001 -S app -G app -# Set working directory WORKDIR /app -# Install system dependencies RUN apk add --no-cache \ curl \ gcc \ musl-dev \ linux-headers -# Install Python dependencies COPY apps/ui/requirements.txt /app/requirements.txt RUN pip install --no-cache-dir -r requirements.txt -# Copy application code +# Copy only Python code and templates, but exclude static assets COPY apps/__init__.py /app/apps/__init__.py -COPY apps/ui/ /app/apps/ui/ +COPY apps/ui/__init__.py /app/apps/ui/__init__.py +COPY apps/ui/main.py /app/apps/ui/main.py +COPY apps/ui/api_client.py /app/apps/ui/api_client.py +COPY apps/ui/templates/ /app/apps/ui/templates/ -# Change ownership to app user RUN chown -R app:app /app - -# Switch to non-root user USER app -# Health check HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ CMD curl -f http://localhost:${UI_PORT}/health || exit 1 -# Expose port EXPOSE 8002 -# Run application CMD ["python", "-m", "uvicorn", "apps.ui.main:app", "--host", "0.0.0.0", "--port", "8002"] diff --git a/apps/ui/main.py b/apps/ui/main.py index 5d19fc1..ace8174 100644 --- a/apps/ui/main.py +++ b/apps/ui/main.py @@ -16,9 +16,11 @@ logger = logging.getLogger(__name__) # Read configuration from environment variables API_BASE = os.getenv("API_BASE", "http://localhost:8001") BASE_PATH = os.getenv("BASE_PATH", "") # e.g., "/ui" for reverse proxy +STATIC_BASE = os.getenv("STATIC_BASE", "/static") print(f"UI using API_BASE: {API_BASE}") print(f"UI using BASE_PATH: {BASE_PATH}") +print(f"UI using STATIC_BASE: {STATIC_BASE}") def api_url(path: str) -> str: """Helper function to construct API URLs. @@ -43,6 +45,9 @@ app = FastAPI( templates_dir = Path(__file__).parent / "templates" templates = Jinja2Templates(directory=str(templates_dir)) +# Make STATIC_BASE available in all templates +templates.env.globals["STATIC_BASE"] = STATIC_BASE + # Setup static files static_dir = Path(__file__).parent / "static" static_dir.mkdir(exist_ok=True) @@ -98,7 +103,8 @@ async def health() -> JSONResponse: "status": "ok", "service": "ui", "api_base": API_BASE, - "base_path": BASE_PATH + "base_path": BASE_PATH, + "static_base": STATIC_BASE, }) @@ -127,7 +133,7 @@ async def rooms(request: Request) -> HTMLResponse: """ return templates.TemplateResponse("rooms.html", { "request": request, - "api_base": API_BASE + "api_base": API_BASE, }) @@ -145,7 +151,7 @@ async def room_detail(request: Request, room_name: str) -> HTMLResponse: return templates.TemplateResponse("room.html", { "request": request, "api_base": API_BASE, - "room_name": room_name + "room_name": room_name, }) diff --git a/apps/ui/templates/dashboard.html b/apps/ui/templates/dashboard.html index 033d4a5..82ff8c1 100644 --- a/apps/ui/templates/dashboard.html +++ b/apps/ui/templates/dashboard.html @@ -6,17 +6,17 @@ Home Automation - - - - - - + + + + + + - +