Files
Claude aa8ef8519c Add Docker support: separate backend and frontend containers
Multi-stage Dockerfiles for both (build stage with devDependencies,
slim production runtime), a root docker-compose.yml wiring them
together, and a root .env.example documenting the compose-level vars.

The frontend container runs with network_mode: service:backend rather
than its own network — VITE_BACKEND_URL is baked into the frontend
bundle at build time and used by both the visitor's browser and this
container's own server-rendered (SSR) fetches on a page's first load;
sharing the backend's network namespace is what lets a single
http://localhost:4000 value correctly resolve for both, since no
Compose-internal service-name hostname is reachable from a browser and
no host-only address is reachable from inside a separate container.

Backend gets a healthcheck (plain node -e fetch, no extra deps) so
depends_on: condition: service_healthy actually waits for it to be
ready rather than just started. backend-data volume persists the
SQLite DB, downloaded media, and uploaded widgets across restarts.
Added a root README "Docker" section and a root .gitignore for the
compose .env file.
2026-08-04 02:54:39 +00:00

36 lines
1.1 KiB
Docker

# syntax=docker/dockerfile:1
# --- build stage ---
FROM node:22-slim AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
# Baked into both the client and server bundles at build time (Vite convention —
# see src/lib/config.ts's getBackendUrl()), not read fresh at container start.
# Must resolve to the backend from every context that calls it: the visitor's
# browser, AND this container's own Node process for the server-rendered (SSR)
# fetches +layout.ts makes on a page's very first load. See docker-compose.yml,
# which runs this container sharing the backend container's network namespace so
# a single http://localhost:<port> value is genuinely correct for both.
ARG VITE_BACKEND_URL=http://localhost:4000
ENV VITE_BACKEND_URL=$VITE_BACKEND_URL
RUN npm run build
# --- runtime stage ---
FROM node:22-slim AS runtime
WORKDIR /app
ENV NODE_ENV=production
# adapter-node bundles every server-side dependency into build/ — no node_modules
# needed at runtime (frontend/package.json has no runtime "dependencies" at all).
COPY --from=build /app/build ./build
EXPOSE 3000
CMD ["node", "build/index.js"]