# Mirwal API.
#
# No native addons here (mysql2 is pure JS, and sharp — the only compiled
# dependency in the monorepo — belongs to scripts/optimize-images.mjs at the
# root, not to this workspace), so plain node:alpine is enough; there is no
# case for a build stage that compiles anything.

FROM node:24-alpine AS deps
WORKDIR /app
COPY package.json package-lock.json ./
# --omit=dev: this is the same package.json the test suite runs against, and
# the test runner (node --test) needs nothing from npm — it ships in Node.
RUN npm ci --omit=dev

FROM node:24-alpine
ENV NODE_ENV=production
WORKDIR /app

# Runs as an unprivileged user. Nothing here needs root, and the storage
# directories below are the only paths this process writes to.
RUN addgroup -S mirwal && adduser -S mirwal -G mirwal

COPY --from=deps /app/node_modules ./node_modules
COPY package.json ./
COPY src ./src

# storage/uploads holds seller KYC documents; storage/backups is where a
# scheduled mysqldump lands if you run one from inside this container. Both
# are created here so the image works before any volume is mounted over
# /app/storage — mount one in production so this survives a container
# replacement (see docker-compose.yml).
RUN mkdir -p storage/uploads storage/backups && chown -R mirwal:mirwal storage

USER mirwal
EXPOSE 4000

# src/server.js already refuses to serve traffic until the database is
# reachable and confirmed utf8mb4, so a healthy /health response means the
# database check passed too, not just that the process is alive.
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
  CMD node -e "fetch('http://127.0.0.1:'+(process.env.PORT||4000)+'/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"

# Migrations are run deliberately, not on container start — see
# DEPLOYMENT.md. Starting several replicas of this image must never race
# each other through the migration runner.
CMD ["node", "src/server.js"]
