# ── Stage 1: Build ───────────────────────────────────────── FROM node:18-alpine AS builder WORKDIR /app # native build deps (better-sqlite3 etc) RUN apk add --no-cache python3 make g++ # install ALL deps (vite needs dev deps) COPY package*.json ./ RUN npm ci # copy full project COPY . . # build frontend RUN npm run build # ── Stage 2: Runtime ─────────────────────────────────────── FROM node:18-alpine WORKDIR /app # minimal tools for debugging inside container + privilege drop in entrypoint RUN apk add --no-cache bash nano su-exec # create non-root user RUN addgroup -S bill && adduser -S bill -G bill # copy EVERYTHING from builder (no missing files) COPY --from=builder /app ./ COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh # setup persistent data dirs and a writable fallback backup dir RUN mkdir -p /data/db /data/backups /app/backups \ && chown -R bill:bill /data /app/backups \ && chmod 700 /data/db /data/backups /app/backups \ && chmod +x /usr/local/bin/docker-entrypoint.sh ENV NODE_ENV=production \ PORT=3000 \ DB_PATH=/data/db/bills.db \ BACKUP_PATH=/data/backups EXPOSE 3000 VOLUME ["/data"] ENTRYPOINT ["docker-entrypoint.sh"] CMD ["node", "server.js"]