What the Raspberry Pi time-server guides get wrong on a Pi 4, with the measurements. The headline artifact is a four-line pps-gpio patch: PREEMPT_RT force-threads IRQ handlers, and pps-gpio takes its timestamp inside its handler, so the realtime kernel puts a scheduler between the electrical edge and the clock. IRQF_NO_THREAD takes RMS offset from 2468 ns to 199 ns. - kernel/ the patch - dashboard/ live status page (position hidden by default) - docs-site/ the write-up (Astro/Starlight, brass, no tutorial section)
48 lines
1.6 KiB
Docker
48 lines
1.6 KiB
Docker
# Multi-stage build for the cuckoo-escapement docs site.
|
|
#
|
|
# Stages:
|
|
# - base : Node, pnpm/npm tooling, deps installed
|
|
# - dev : runs `astro dev` with HMR for local development
|
|
# - builder : produces the static `dist/`
|
|
# - prod : caddy:alpine that serves `dist/` (no Node at runtime)
|
|
#
|
|
# `docker compose --profile dev up` → dev target
|
|
# `docker compose up` (no profile) → prod target
|
|
|
|
# Pinned through the mirror.gcr.io pass-through to dodge intermittent
|
|
# Docker Hub TLS hiccups during builds. Same content, more reliable
|
|
# fetch path. The `docker pull` resolves identically against either.
|
|
FROM mirror.gcr.io/library/node:22-alpine AS base
|
|
WORKDIR /app
|
|
COPY package.json ./
|
|
RUN --mount=type=cache,target=/root/.npm \
|
|
npm install --no-audit --no-fund
|
|
|
|
|
|
# ----- dev: astro dev server with HMR -----
|
|
FROM base AS dev
|
|
# Astro's binary is in node_modules/.bin — package.json's `dev` script
|
|
# already binds to 0.0.0.0 for HMR-behind-Caddy.
|
|
COPY . .
|
|
ENV ASTRO_TELEMETRY_DISABLED=1
|
|
EXPOSE 4321
|
|
CMD ["npm", "run", "dev"]
|
|
|
|
|
|
# ----- builder: produce dist/ -----
|
|
FROM base AS builder
|
|
COPY . .
|
|
ENV ASTRO_TELEMETRY_DISABLED=1
|
|
RUN npm run build
|
|
|
|
|
|
# ----- prod: caddy serves the static build -----
|
|
FROM mirror.gcr.io/library/caddy:2-alpine AS prod
|
|
# Caddyfile is intentionally minimal — caddy-docker-proxy on the host
|
|
# handles TLS, routing, and the public-facing reverse proxy. This
|
|
# container just serves files locally; the proxy points at it.
|
|
RUN mkdir -p /srv/docs
|
|
COPY --from=builder /app/dist /srv/docs
|
|
RUN printf ':80 {\n\troot * /srv/docs\n\tfile_server\n\ttry_files {path} {path}/ /404.html\n\tencode zstd gzip\n}\n' > /etc/caddy/Caddyfile
|
|
EXPOSE 80
|