# syntax=docker/dockerfile:1.7 # --- build stage: install production dependencies only --- FROM node:20-alpine AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci --omit=dev --no-audit --no-fund # --- runtime stage: minimal image with just what's needed to run --- FROM node:20-alpine AS runtime ENV NODE_ENV=production WORKDIR /app # Bring in dependencies (owned by the built-in `node` user). COPY --from=deps --chown=node:node /app/node_modules ./node_modules # Application code. COPY --chown=node:node package.json package-lock.json ./ COPY --chown=node:node src ./src COPY --chown=node:node greetings ./greetings # Directory the token-refresh cron writes to. Mount a volume here in prod. RUN mkdir -p /app/config && chown node:node /app/config # Daily store phone export baseline + archives. Mount a volume at /app/data # in prod so diffs survive container restarts. RUN mkdir -p /app/data && chown node:node /app/data # WebSocket port the on-prem SIW agent connects back to. Override at runtime # via -e WS_PORT and -p host:container. EXPOSE 8080 USER node CMD ["node", "src/index.js"]