The storefront showed no inventory after deploying the categories/tags release. No data was lost: the code queried categories/item_tags/ items.category_id against a database where the migration had not been run, and that failure was invisible at every layer. Three changes, each addressing one layer: Migrations now run at container start, so deployed code cannot be ahead of the schema and the easily-forgotten manual `docker exec migrate.js up` step disappears. migrate.js waits for Postgres to accept connections first, since the NAS brings the DB container up slower than the app, and still exits non-zero so a bad migration stops the container rather than serving a half-migrated schema. Express 4 does not forward a rejected async handler, and no error middleware was mounted, so a failing query never responded at all. Async routes are now wrapped and an error middleware guarantees a 500. A hung request is indistinguishable from an empty result in the UI, which is how a schema mismatch came to read as "the store has no items". The storefront now separates "request failed" from "no items" and offers a retry. fetchItems/fetchFilterOptions throw on a non-OK response rather than returning the parsed error body, which would have been set as the item list and crashed the grid on .map. Also restores the project-context update from 7fb5764, which was left out of PR #24 and ended up dangling. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
33 lines
1.2 KiB
Docker
Executable File
33 lines
1.2 KiB
Docker
Executable File
FROM node:20-bookworm-slim AS frontend-build
|
|
WORKDIR /app/frontend
|
|
COPY frontend/package.json ./
|
|
RUN npm install
|
|
COPY frontend/ ./
|
|
RUN npm run build
|
|
|
|
FROM node:20-bookworm-slim AS backend-build
|
|
WORKDIR /app/backend
|
|
COPY backend/package.json ./
|
|
RUN npm install
|
|
COPY backend/ ./
|
|
RUN npm run build
|
|
|
|
FROM node:20-bookworm-slim
|
|
WORKDIR /app
|
|
COPY --from=backend-build /app/backend/package.json ./
|
|
RUN npm install --omit=dev
|
|
COPY --from=backend-build /app/backend/dist ./dist
|
|
COPY --from=backend-build /app/backend/migrate.js ./migrate.js
|
|
COPY --from=backend-build /app/backend/migrations ./migrations
|
|
COPY --from=frontend-build /app/frontend/dist ./public
|
|
ENV NODE_ENV=production
|
|
EXPOSE 3000
|
|
# Migrations run before the app serves, so deployed code can never be ahead of
|
|
# the database schema. Previously this was a separate, manual
|
|
# `docker exec ... node migrate.js up` that was easy to forget — and forgetting
|
|
# it meant every item query referenced tables that did not exist yet, which
|
|
# surfaced as an empty storefront rather than an error.
|
|
#
|
|
# `&&` matters: migrate.js exits non-zero on failure, so a bad migration stops
|
|
# the container instead of letting it serve against a half-migrated schema.
|
|
CMD ["sh", "-c", "node migrate.js up && node dist/server.js"] |