Dockerfile.worker (2388B)
1 # deploy/Dockerfile.worker - the worker 2 # 3 # Build from the repository root: 4 # docker build -f deploy/Dockerfile.worker -t finwo/conductor-worker . 5 # 6 # Alpine rather than the official node image, for the same reason as the 7 # conductor: node is not published for riscv64, and Alpine 3.23 has both 8 # node 24 and a docker client on every architecture we publish for. That 9 # also means the docker client comes from the package manager rather than 10 # a tarball off download.docker.com, which has no riscv64 build at all. 11 # 12 # The worker runs each job in its own container, so it needs a docker 13 # socket. It does not run a daemon of its own: the containers it starts 14 # are siblings on the host, not children. 15 # 16 # It shares nothing else with them. A job's tree is unpacked into its 17 # container over the docker API rather than bind mounted from here, and 18 # the results are read back the same way, so no directory has to mean the 19 # same thing on both sides and this image needs no volumes at all. 20 21 ARG ALPINE_VERSION=3.23 22 23 FROM alpine:${ALPINE_VERSION} AS deps 24 25 RUN apk add --no-cache nodejs npm 26 27 WORKDIR /app 28 29 # The worker source needs no npm packages at all. yaml is installed only so 30 # the configuration file may be YAML as well as JSON; nothing breaks 31 # without it. 32 RUN npm install --omit=dev --no-audit --no-fund yaml \ 33 && npm cache clean --force 34 35 FROM alpine:${ALPINE_VERSION} 36 37 # docker-cli to drive the host daemon, and node to run the agent. No git, 38 # because the worker never touches a repository, and no tar, because 39 # docker does the unpacking on the far side of the socket. 40 RUN apk add --no-cache ca-certificates docker-cli nodejs 41 42 WORKDIR /app 43 44 # The source is ES modules, and node reparses every file with a warning 45 # unless the package says so. 46 RUN printf '{\n "name": "conductor-worker",\n "private": true,\n "type": "module"\n}\n' > package.json 47 48 COPY --from=deps /app/node_modules ./node_modules 49 COPY src/worker/ ./src/worker/ 50 51 # Deliberately no CONDUCTOR_WORKER_CONFIG: the worker is configurable by 52 # environment alone, and naming a file that is not mounted would make it 53 # refuse to start. A config mounted at /etc/conductor/worker.json is picked 54 # up on its own. 55 ENV NODE_ENV=production 56 57 # Runs as root because the docker socket is usually root owned. The jobs 58 # themselves are isolated by being containers, not by this user. 59 ENTRYPOINT ["node", "src/worker/agent.js"]