Adds the SciMesh coordinator: a durable task-queue server on PostgreSQL that owns all database access, with workers reaching it over HTTP only. Structured as a modular monolith following Clean Architecture: domain entities and their invariants, no I/O usecase business operations + repository/clock ports transport HTTP handlers, DTOs, auth, error mapping storage PostgreSQL repositories, transactions carried in context infra config, pool, clock, server, lease reaper Dependencies point strictly inward; domain imports nothing from the module. Working: layer wiring, routing, shared-token auth, access logging, request IDs, domain-error to status-code mapping, transactional boundaries, graceful shutdown (HTTP drain -> reaper stop -> pool close), migrations, and a Compose stack starting Postgres -> migrations -> coordinator. The domain is complete and covered by unit tests that need no database: lease ownership, stale attempts, idempotent result replay, retry budgets, and lease expiry. Repository methods are stubs returning ErrNotImplemented (HTTP 501). The SQL for atomic claiming (FOR UPDATE SKIP LOCKED) and for lease expiry is written and ready to wire up. See coordinator/ARCHITECTURE.md for the layer map and a request traced through every layer.
48 lines
1.7 KiB
Docker
48 lines
1.7 KiB
Docker
# syntax=docker/dockerfile:1
|
|
#
|
|
# Requires BuildKit (the RUN --mount cache lines below). Docker 23+ enables it
|
|
# by default when the buildx plugin is present; install `docker-buildx` if a
|
|
# build fails with "the --mount option requires BuildKit".
|
|
|
|
# --- build stage ----------------------------------------------------------
|
|
FROM golang:1.24-alpine AS build
|
|
|
|
WORKDIR /src
|
|
|
|
# Copy manifests first: this layer stays cached until dependencies actually
|
|
# change, so editing Go sources does not re-download the module graph.
|
|
COPY go.mod go.sum ./
|
|
RUN --mount=type=cache,target=/go/pkg/mod go mod download
|
|
|
|
COPY . .
|
|
|
|
# The cache mounts persist the module cache and the compiler's build cache
|
|
# *across* builds, so a rebuild after a code edit recompiles only what changed
|
|
# instead of the whole dependency tree.
|
|
#
|
|
# CGO_ENABLED=0 produces a fully static binary, so the runtime image needs no
|
|
# libc. -trimpath strips local paths; -s -w drop the symbol table and DWARF.
|
|
RUN --mount=type=cache,target=/go/pkg/mod \
|
|
--mount=type=cache,target=/root/.cache/go-build \
|
|
CGO_ENABLED=0 GOOS=linux go build \
|
|
-trimpath -ldflags="-s -w" \
|
|
-o /out/coordinator ./cmd/coordinator
|
|
|
|
# --- runtime stage --------------------------------------------------------
|
|
FROM alpine:3.20
|
|
|
|
# ca-certificates for outbound TLS; wget backs the container healthcheck.
|
|
RUN apk add --no-cache ca-certificates wget \
|
|
&& adduser -D -H -u 10001 coordinator
|
|
|
|
COPY --from=build /out/coordinator /usr/local/bin/coordinator
|
|
|
|
# Never run as root: a compromised process should not own the container.
|
|
USER coordinator
|
|
|
|
EXPOSE 8080
|
|
|
|
# Exec form, not shell: the binary becomes PID 1 and receives SIGTERM directly,
|
|
# which is what its graceful shutdown depends on.
|
|
ENTRYPOINT ["/usr/local/bin/coordinator"]
|