Dockerfile
Rama main · réplica de lectura del repositorio original.
# Writers Guild Docker Image
#
# The image mirrors the repository layout (/app/server, /app/shared,
# /app/defaults) so every path the code resolves relative to its own file —
# shared/ imports, the defaults/ character cards — lands where it does in a
# checkout.
#
# Debian slim (glibc) rather than alpine (musl), so better-sqlite3 and sharp
# install from their published linux-x64 / linux-arm64 prebuilds instead of
# compiling from source, which is glacial under QEMU when the arm64 image is
# built on an amd64 runner.
#
# Track the current LTS line explicitly (24) rather than the `lts` tag, so the
# Node major only moves when we move it. The digest is refreshed by dependabot;
# see .github/dependabot.yml.
# Stage 1: Build Vue client
FROM node:24-slim@sha256:d6aa754f16b3197301076f047b5def2f02ea1dbbc2ca920407d46d7ec7f87b20 AS client-builder
WORKDIR /app/vue_client
COPY vue_client/package*.json ./
RUN npm ci
COPY shared/ /app/shared/
COPY vue_client/ ./
RUN npm run build
# Stage 2: Install server production dependencies
FROM node:24-slim@sha256:d6aa754f16b3197301076f047b5def2f02ea1dbbc2ca920407d46d7ec7f87b20 AS server-deps
WORKDIR /app/server
COPY server/package*.json ./
RUN npm ci --omit=dev
# Stage 3: Runtime image
FROM node:24-slim@sha256:d6aa754f16b3197301076f047b5def2f02ea1dbbc2ca920407d46d7ec7f87b20
RUN apt-get update \
&& apt-get install -y --no-install-recommends tini \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
COPY --from=server-deps /app/server/node_modules ./server/node_modules
COPY server/ ./server/
COPY shared/ ./shared/
COPY defaults/ ./defaults/
COPY --from=client-builder /app/vue_client/dist ./server/public/
# All persistent state lives in /data; mount a volume there.
ENV NODE_ENV=production
ENV DATA_DIR=/data
RUN mkdir -p /data
WORKDIR /app/server
EXPOSE 8000
# Use tini for proper signal handling
ENTRYPOINT ["/usr/bin/tini", "--"]
CMD ["node", "server.js"]