# mesh-catalog's runtime: the tool runtime, carrying the catalogue's compiled graph, its consumer # of what the builder announces, and its tools. # # **Built from this module's own directory and nothing else.** The sdk is in the base image, so # nothing is copied out of a neighbouring checkout — which is what lets the mesh build this from a # repository and a path (novox/hq ADR 0069) rather than only on a workstation with the siblings. # # Two bases, named rather than pinned: the image this is COMPILED in, and the image it RUNS in. # They are different images on purpose — the first carries a compiler and the second must not, or # every running container would carry one it never invokes. The mesh answers both with the copies it # holds, because a fingerprint written here would name one particular copy and no other mesh has it # (novox/hq issue 044). Declared in module.json's `build.on`; deliberately no defaults, so a build # nobody told stops here and says which module to build first. ARG BUILD_BASE ARG RUNTIME_BASE FROM ${BUILD_BASE} AS build # Compiled under /app/modules so `@novox/mesh-sdk` resolves upward into the base's own # node_modules — the module is compiled against exactly the sdk it will run against. WORKDIR /app/modules/mesh-catalog COPY . . # The compiler is invoked by its real path rather than through node_modules/.bin, whose entries are # symlinks to a launcher that requires its library relatively — resolved away when the base image # was assembled. RUN node /app/node_modules/typescript/bin/tsc pg.d.ts store.ts index.ts tools/index.ts prepare/index.ts \ --module NodeNext --moduleResolution NodeNext --target ES2022 --outDir dist # **A module may need something the base image does not carry.** The base holds what every module # needs — the sdk, the broker client — and a postgres driver is not that: the one other module that # reaches a database shells out to psql instead. So the catalogue brings its own. # # Installed into an empty directory rather than into the module's, because the module's package.json # also names `@novox/mesh-sdk`, which is not on any registry — it is in the base image. Asking npm to # resolve this module's dependencies would therefore fail on the one it already has. RUN mkdir -p /deps && cd /deps && \ npm install --omit=dev --no-audit --no-fund --no-package-lock pg@8 FROM ${RUNTIME_BASE} COPY --from=build /app/modules/mesh-catalog/dist /app/modules/mesh-catalog/dist # Beside the compiled code, so `pg` resolves from it while `@novox/mesh-sdk` keeps walking up to the # base image's own node_modules — the module gets its extra dependency without shadowing the sdk it # was compiled against. COPY --from=build /deps/node_modules /app/modules/mesh-catalog/node_modules # Both entrypoints, loaded in serve mode. # # **A consumer cannot be started with `run`.** That mode imports an entrypoint without binding a # broker — it is for a step that does its work offline and exits — and the catalogue's whole job is # to listen for what the builder announces. Serve binds the broker first, then imports these, so # `on()` has something to subscribe to. ENV MESH_TOOL_MODULES=/app/modules/mesh-catalog/dist/index.js,/app/modules/mesh-catalog/dist/tools/index.js # And what prepares this module's state, for the runtime's `prepare` mode (novox/hq ADR 0135). Named # here, beside the entrypoints above, because the module knows which of its files prepares its state # and nothing else could: the mesh asks one word and this says what answers it. ENV MESH_PREPARE=/app/modules/mesh-catalog/dist/prepare/index.js