Docker Deployment
The generated project uses a single Docker image that contains both Nginx and the backend, exposing just one port.
Architecture
Section titled “Architecture”Browser ──▶ :5173 (Nginx) ├─ / Frontend static files (/usr/share/nginx/html) ├─ /api/ Reverse proxy to 127.0.0.1:8088 (backend in the same container) └─ /docs Proxy to the backend API docs (Python)- The frontend is built into static files by the Node stage, served by Nginx, with the SPA fallback
try_files ... /index.html. - The backend listens on
127.0.0.1:8088inside the container and is exposed externally only through Nginx. - The image has
EXPOSE 5173, anddocker-compose.ymlmaps5173:5173. - Nginx allows 1 GB uploads, disables proxy request/response buffering, and raises read/write timeouts to one hour for full-data import/export.
Multi-Stage Build
Section titled “Multi-Stage Build”node:22-alpine: build the frontend.python:3.12-slim: install Nginx and the backend dependencies (uv pip install --system -e .), and copy the frontend build output andnginx.conf.
node:22-alpine: build the frontend.maven:3.9-eclipse-temurin-21:mvn package -DskipTests.eclipse-temurin:21-jre-alpine: install Nginx and copy the JAR and frontend build output.
Build and Run
Section titled “Build and Run”# Build the imagedocker build -t my-project .
# Run (a strong random JWT_SECRET_KEY is required)docker run -d -p 5173:5173 \ -e JWT_SECRET_KEY="$(openssl rand -base64 48)" \ my-project
# Or use docker composeJWT_SECRET_KEY="$(openssl rand -base64 48)" docker compose up -dVisit http://localhost:5173.
Data Persistence
Section titled “Data Persistence”- The database file lives at
/app/datain the container, mounted from the named volumeapp-data. - Temporary import/export files live under
/app/data/tmp, also on the persistent data volume. docker compose downpreserves the data; runningup -dagain does not lose it.- To clear the data, run:
docker compose down -v # deletes the data volume; data is unrecoverableData management may keep a database snapshot, upload, and export archive at the same time. Reserve at least roughly three times the database size in the data volume.
The full export archive contains password hashes, AI API keys, SMTP passwords, and other sensitive data. Move it to controlled storage immediately and do not distribute it through chat tools.
Health Check
Section titled “Health Check”The image has a built-in health check (interval 30s, timeout 5s, startup grace 15s, 3 retries) that accesses http://127.0.0.1:5173/api/public/config. The Python image uses the built-in urllib, and the Java image uses wget.
Environment Variables
Section titled “Environment Variables”| Variable | Description |
|---|---|
JWT_SECRET_KEY |
Required (Python backend), strong random |
TZ |
Time zone, defaults to Asia/Shanghai |
DATABASE_URL |
Already set to sqlite+aiosqlite:////app/data/app.db inside the Python image |
PYTHONUNBUFFERED |
Already set to 1 inside the Python image |