feat(M5): docker-compose full stack (caddy + node backend + sqlite)
docker-compose.yml: two profiles.
- backend: backend (node+ws+better-sqlite3, /data volume) + frontend
(Caddy static build, STORAGE=ws, same-origin proxy)
- firebase: existing Dockerfile + nginx (upstream path, untouched)
Run: docker compose --profile backend up --build. OrbStack local now,
remote docker context later.
server/Dockerfile: node:18-alpine, workspaces (shared dep), rebuild
better-sqlite3 for musl, DB at /data/tracker.sqlite.
Dockerfile.ws: CRA build STORAGE=ws → caddy:2-alpine serves /srv.
No backend URL baked (same-origin).
Caddyfile: handle /api/* + handle /ws → backend:4001 (path preserved,
mutually-exclusive handles so try_files SPA fallback never shadows proxy).
handle { static try_files } last. HTTP basic auth block optional.
src/storage/ws.js: same-origin defaults. Empty baseUrl = relative fetch
(Caddy proxy). wsUrl derives from window.location (http→ws/https→wss).
Fallback localhost for bare npm start dev.
.dockerignore: add data/ scratch/ tmp/ (never bake into image). Keep
Caddyfile in context (frontend build COPYs it).
Smoke verified via OrbStack:
- GET / → 200 (static SPA)
- PUT/GET /api/doc roundtrip → JSON persists
- WS /ws subscribe + change push → both work through proxy
Firebase profile: pre-existing Dockerfile requires .env.local (hardcoded
COPY on main, not changed here). User must create file. Not a regression.
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
# Dockerfile.ws — frontend build (STORAGE=ws) served by Caddy
|
||||
# Same-origin: Caddy proxies /api + /ws to backend. No backend URL baked at build.
|
||||
|
||||
FROM node:18-alpine AS build
|
||||
WORKDIR /app
|
||||
|
||||
# workspaces root
|
||||
COPY package*.json ./
|
||||
COPY shared/package.json ./shared/
|
||||
COPY server/package.json ./server/
|
||||
RUN npm install --include-workspace-root
|
||||
|
||||
COPY shared/ ./shared/
|
||||
COPY src/ ./src/
|
||||
COPY public/ ./public/
|
||||
|
||||
# Build with ws storage (no backend URL — same-origin via Caddy proxy)
|
||||
ARG REACT_APP_TRACKER_APP_ID=ttrpg-initiative-tracker-default
|
||||
ENV REACT_APP_STORAGE=ws
|
||||
ENV REACT_APP_TRACKER_APP_ID=$REACT_APP_TRACKER_APP_ID
|
||||
RUN NODE_OPTIONS=--openssl-legacy-provider npm run build
|
||||
|
||||
# Stage 2: Caddy serves static + proxies API/WS
|
||||
FROM caddy:2-alpine
|
||||
|
||||
COPY --from=build /app/build /srv
|
||||
COPY Caddyfile /etc/caddy/Caddyfile
|
||||
|
||||
EXPOSE 80
|
||||
Reference in New Issue
Block a user