# agent-dispatch - the only long-lived service in the platform.
#
# Deliberately dependency-free: node:24-alpine plus two source files. The
# dispatcher holds the OpenRouter key, the Gitea token and the Portainer API keys
# in order to hand them to task containers, so its own supply chain is kept as
# small as the task is large: no package.json dependencies, no lockfile, no
# transitive tree.
#
# No user is created here on purpose. node:24-alpine already ships uid/gid 1000
# as `node`, and `addgroup -g 1000` fails with "group in use" - which is how the
# first version of this file broke its own build. Using the shipped account also
# means the ids the volumes are initialised with are ids the image actually knows.
#
# /data and /tasks are created and owned here so Docker initialises the named
# volumes from this ownership rather than as root-owned roots uid 1000 cannot
# write.

FROM docker.io/library/node:24-alpine

WORKDIR /app
COPY --chown=node:node dispatcher/server.js ./server.js
COPY --chown=node:node dispatcher/public ./public
COPY --chown=node:node dispatcher/package.json ./package.json

RUN mkdir -p /data /tasks && chown node:node /data /tasks

USER node
EXPOSE 4180
ENV NODE_ENV=production

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
    CMD wget -qO- http://127.0.0.1:4180/healthz || exit 1

CMD ["node", "server.js"]
