# docker/Dockerfile — single container: caddy (front) + node (back). # Build context = repo root. # ---- build stage: frontend + install backend deps ---- FROM node:18-alpine AS build WORKDIR /app COPY package*.json ./ COPY shared/package.json ./shared/ COPY server/package.json ./server/ RUN npm install --include-workspace-root COPY shared/ ./shared/ COPY server/ ./server/ COPY src/ ./src/ COPY public/ ./public/ COPY tailwind.config.js postcss.config.js ./ # better-sqlite3 native build (alpine musl) RUN cd server && npm rebuild better-sqlite3 # build frontend (ws storage, same-origin via caddy) 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 # prune backend dev deps for runtime RUN npm prune --omit=dev # ---- runtime stage: caddy + node ---- FROM node:18-alpine RUN apk add --no-cache caddy WORKDIR /app COPY --from=build /app/node_modules ./node_modules COPY --from=build /app/shared/node_modules ./shared/node_modules COPY --from=build /app/server/node_modules ./server/node_modules COPY --from=build /app/package*.json ./ COPY --from=build /app/shared/package.json ./shared/ COPY --from=build /app/server/package.json ./server/ COPY shared/ ./shared/ COPY server/ ./server/ # built frontend served by caddy COPY --from=build /app/build /srv COPY docker/Caddyfile /etc/caddy/Caddyfile COPY docker/entrypoint.sh /entrypoint.sh ENV NODE_ENV=production ENV PORT=4001 ENV DB_PATH=/data/tracker.sqlite EXPOSE 80 WORKDIR /app CMD ["/entrypoint.sh"]