mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
fix(uploads): pre-create journey and places upload dirs
Both were created lazily on the first upload, which needs write permission on the uploads mount point itself at request time. On hosts whose bind-mounted uploads dir is not writable by the runtime user, every feature writing into an already-existing subdir keeps working while journey photo and place image uploads fail with EACCES (#1762). Creating them in the image and at boot turns that into one loud startup failure instead of a stray 500 on upload. Also drop the recursive chown over all of /app from the final layer: it copied up every inode it touched and duplicated node_modules, dist and the client bundle into a 518 MB layer. The chown now rides the layer that installs node_modules, later copies carry --chown=node:node, and the last layer chowns only the paths it creates. Everything under /app stays node-owned; image size 2.36 GB -> 1.68 GB.
This commit is contained in:
+26
-13
@@ -50,6 +50,11 @@ COPY shared/package.json ./shared/
|
||||
COPY nest-mcp/package.json ./nest-mcp/
|
||||
COPY server/package.json ./server/
|
||||
|
||||
# The trailing chown runs in this layer on purpose: it covers the manifests and
|
||||
# the freshly installed node_modules while they are already part of this layer's
|
||||
# changeset, so it costs nothing. Everything copied after this point carries
|
||||
# --chown=node:node for the same reason — a recursive chown in a later layer
|
||||
# would copy up every inode it touches and duplicate the whole tree in the image.
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends tzdata dumb-init wget ca-certificates python3 build-essential \
|
||||
libkitinerary-bin && \
|
||||
@@ -57,7 +62,8 @@ RUN apt-get update && \
|
||||
ln -sf "$(find /usr/lib -name kitinerary-extractor -type f | head -1)" /usr/local/bin/kitinerary-extractor; \
|
||||
apt-get purge -y python3 build-essential && \
|
||||
apt-get autoremove -y && \
|
||||
rm -rf /var/lib/apt/lists/* /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx
|
||||
rm -rf /var/lib/apt/lists/* /usr/local/lib/node_modules/npm /usr/local/bin/npm /usr/local/bin/npx && \
|
||||
chown -R node:node /app
|
||||
|
||||
# gosu rebuilt with a current Go toolchain (stage 0) — used by CMD to drop to node.
|
||||
COPY --from=gosu-build /out/gosu /usr/local/bin/gosu
|
||||
@@ -69,36 +75,43 @@ ENV QT_QPA_PLATFORM=offscreen
|
||||
# Override with KITINERARY_EXTRACTOR_PATH if you install it elsewhere.
|
||||
ENV KITINERARY_EXTRACTOR_PATH=/usr/local/bin/kitinerary-extractor
|
||||
|
||||
COPY --from=server-builder /app/server/dist ./server/dist
|
||||
COPY --chown=node:node --from=server-builder /app/server/dist ./server/dist
|
||||
# Runtime data assets read from server/assets at runtime: airports.json (flight
|
||||
# transport search) and atlas/*.geojson.gz (Atlas country/region map). The build
|
||||
# only emits dist, so these must be copied explicitly or the features silently
|
||||
# degrade to empty in the image.
|
||||
COPY --from=server-builder /app/server/assets ./server/assets
|
||||
COPY --chown=node:node --from=server-builder /app/server/assets ./server/assets
|
||||
# The in-app help pages (/help) read this straight from disk at runtime, so the
|
||||
# docs always match the version running. Without it, wikiService falls back to
|
||||
# fetching the GitHub wiki, which tracks main and needs network access.
|
||||
COPY wiki ./wiki
|
||||
COPY --chown=node:node wiki ./wiki
|
||||
# tsconfig-paths/register reads this at runtime to resolve MCP SDK paths.
|
||||
COPY server/tsconfig.json ./server/
|
||||
COPY --chown=node:node server/tsconfig.json ./server/
|
||||
# Encryption-key rotation is run on demand via tsx (a prod dep) straight from the
|
||||
# raw .ts source — it never enters dist, so it must be copied in explicitly or
|
||||
# `node --import tsx scripts/migrate-encryption.ts` fails with module-not-found.
|
||||
COPY server/scripts/migrate-encryption.ts ./server/scripts/migrate-encryption.ts
|
||||
COPY --chown=node:node server/scripts/migrate-encryption.ts ./server/scripts/migrate-encryption.ts
|
||||
# Admin recovery script (node server/reset-admin.js) for locked-out installs.
|
||||
COPY server/reset-admin.js ./server/reset-admin.js
|
||||
COPY --from=shared-builder /app/shared/dist ./shared/dist
|
||||
COPY --chown=node:node server/reset-admin.js ./server/reset-admin.js
|
||||
COPY --chown=node:node --from=shared-builder /app/shared/dist ./shared/dist
|
||||
# server dist requires @trek/nest-mcp at runtime through the workspace symlink;
|
||||
# its dist's MCP SDK subpath requires ride the same tsconfig-paths/register
|
||||
# hook the server already boots with.
|
||||
COPY --from=server-builder /app/nest-mcp/dist ./nest-mcp/dist
|
||||
COPY --from=client-builder /app/client/dist ./server/public
|
||||
COPY --from=client-builder /app/client/public/fonts ./server/public/fonts
|
||||
COPY --chown=node:node --from=server-builder /app/nest-mcp/dist ./nest-mcp/dist
|
||||
COPY --chown=node:node --from=client-builder /app/client/dist ./server/public
|
||||
COPY --chown=node:node --from=client-builder /app/client/public/fonts ./server/public/fonts
|
||||
|
||||
RUN mkdir -p /app/data/logs /app/uploads/files /app/uploads/covers /app/uploads/avatars /app/uploads/photos && \
|
||||
# journey/ and places/ must be listed here and in server/src/index.ts (#1762) —
|
||||
# a dir created lazily on first upload needs write permission on the uploads
|
||||
# mount point itself, which fails with EACCES when the bind-mounted host dir
|
||||
# isn't writable by node. Only paths this layer creates are chowned; anything
|
||||
# already in the image arrived node-owned via --chown above.
|
||||
RUN mkdir -p /app/data/logs /app/uploads/files /app/uploads/covers /app/uploads/avatars \
|
||||
/app/uploads/photos /app/uploads/journey /app/uploads/places && \
|
||||
ln -s /app/uploads /app/server/uploads && \
|
||||
ln -s /app/data /app/server/data && \
|
||||
chown -R node:node /app
|
||||
chown -R node:node /app/data /app/uploads && \
|
||||
chown -h node:node /app/server/uploads /app/server/data
|
||||
|
||||
ENV NODE_ENV=production
|
||||
ENV PORT=3000
|
||||
|
||||
Reference in New Issue
Block a user