From e0eb65810a4f9999e2d49e77bba6558ac515dc98 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 26 Jan 2026 17:43:14 +0000 Subject: [PATCH] Fix Docker build for miniPaint frontend - Update main Dockerfile to copy all miniPaint static files: - index.html - dist/ (webpack bundle) - images/ (icons and assets) - src/css/ (stylesheets) - Update backend main.py to conditionally mount static directories - Checks if each directory exists before mounting - Supports both React (assets/) and miniPaint (dist/, images/, src/) structures --- Dockerfile | 11 +++++++---- backend/app/main.py | 21 ++++++++++++++++----- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2e7a629..49ee1e9 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ # ============================================================================== # AI Photo Edit - Unified Container -# Builds React frontend and serves it alongside FastAPI backend +# Builds miniPaint frontend and serves it alongside FastAPI backend # ============================================================================== -# Stage 1: Build React frontend +# Stage 1: Build miniPaint frontend FROM node:20-alpine AS frontend-build WORKDIR /frontend @@ -50,8 +50,11 @@ RUN chmod +x /entrypoint.sh # Copy scripts COPY scripts/ /scripts/ -# Copy built frontend from stage 1 -COPY --from=frontend-build /frontend/dist /app/static +# Copy miniPaint frontend files from stage 1 +COPY --from=frontend-build /frontend/index.html /app/static/ +COPY --from=frontend-build /frontend/dist /app/static/dist +COPY --from=frontend-build /frontend/images /app/static/images +COPY --from=frontend-build /frontend/src/css /app/static/src/css # Create data directories RUN mkdir -p /app/data/projects /app/data/patches /app/data/models diff --git a/backend/app/main.py b/backend/app/main.py index 540f490..bfbb7f2 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -63,14 +63,25 @@ def health(): STATIC_DIR = Path("/app/static") -# Serve static assets (JS, CSS, images) +# Serve static assets - mount subdirectories if they exist if STATIC_DIR.exists(): - app.mount("/assets", StaticFiles(directory=STATIC_DIR / "assets"), name="assets") + # React-style assets folder + if (STATIC_DIR / "assets").exists(): + app.mount("/assets", StaticFiles(directory=STATIC_DIR / "assets"), name="assets") + # miniPaint dist folder (webpack bundle) + if (STATIC_DIR / "dist").exists(): + app.mount("/dist", StaticFiles(directory=STATIC_DIR / "dist"), name="dist") + # miniPaint images folder + if (STATIC_DIR / "images").exists(): + app.mount("/images", StaticFiles(directory=STATIC_DIR / "images"), name="images") + # miniPaint CSS folder + if (STATIC_DIR / "src").exists(): + app.mount("/src", StaticFiles(directory=STATIC_DIR / "src"), name="src") @app.get("/", response_class=HTMLResponse) async def serve_spa(): - """Serve React SPA index.html""" + """Serve miniPaint index.html""" index_path = STATIC_DIR / "index.html" if index_path.exists(): return FileResponse(index_path) @@ -80,7 +91,7 @@ async def serve_spa(): @app.get("/{full_path:path}") async def serve_spa_routes(request: Request, full_path: str): """ - Catch-all route for React Router (SPA). + Catch-all route for serving static files. Serves static files if they exist, otherwise returns index.html. """ # Don't catch API routes @@ -92,7 +103,7 @@ async def serve_spa_routes(request: Request, full_path: str): if static_file.exists() and static_file.is_file(): return FileResponse(static_file) - # Otherwise serve index.html for React Router + # Otherwise serve index.html index_path = STATIC_DIR / "index.html" if index_path.exists(): return FileResponse(index_path)