Make the image build from a clean clone and actually serve the interface

The Dockerfile copied PRD.md, which is not in the repository, so a clean
clone could not build at all. It also installed node and npm from Ubuntu 24
(node 18) to build a Vite 8 front end that needs node 20.19 or newer, and it
built the interface into a directory nothing served.

The build is now two stages: node:22 builds the interface, the CUDA runtime
image installs the package and carries the built files. The API serves them
when ELY_EYE_UI_DIR points at a directory that exists, and refuses to start
when it is set but empty, naming the build command. The front end already
calls /api/... on its own origin, so same-origin serving needs no client
change.
This commit is contained in:
ZacharyZhang-NY committed 2026-10-08 01:40:06 -04:00
1 parent 908157f82e
commit 6f8764099a
4 files changed
+68 -8

No files matched your search

+10
View File
@@ -7,6 +7,7 @@ from typing import Annotated
from fastapi import Depends, FastAPI, File, HTTPException, UploadFile
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel
from . import __version__
@@ -339,6 +340,15 @@ def create_app() -> FastAPI:
"cartridges": CartridgeService(settings, db).list_manifests(),
}
mounted_ui = get_settings().ui_dir
if mounted_ui is not None:
if not mounted_ui.is_dir():
raise SystemExit(
f"ui_dir {mounted_ui} is set but holds no built interface; "
"run `npm run build` in frontend/ or unset ELY_EYE_UI_DIR"
)
app.mount("/", StaticFiles(directory=mounted_ui, html=True), name="ui")
return app