mirror of
https://github.com/Patiun/com.gregkilmer.www.git
synced 2026-11-07 19:58:24 +00:00
Phase 7: Cosmos deployment
- Dockerfile with a check target (typecheck and tests) and one image per service on a pinned Node 22.20 Alpine base, each with only its own production dependencies and a health check. - deploy/compose.yaml: gk-content, gk-admin and gk-site on homelab_network with no host ports, read-only root filesystems, no capabilities, the vault's Site folder mounted into the content service, and backup.dump=sqlite on it. - deploy/deploy.sh builds and checks the commit, restarts the stack, and goes back to the last good tag if it doesn't come up healthy; rollback.sh swaps tags. .gitea/workflows/deploy.yml runs it on a host runner on Cosmos. - docs/deploy.md runbook (settings, runner, mirror, NPM hosts, Turnstile, Healthchecks, backups, cutover) and the stack's inventory note in vault-kit. - Site: trusts X-Forwarded-Host/Proto for gregkilmer.com hosts so form posts pass Astro's origin check behind the proxy; rate limits read CF-Connecting-IP; site URL set for absolute links. - Content service: the held-change webhook carries a Discord-ready message; .env.example lists the core settings. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
This commit is contained in:
+93
@@ -0,0 +1,93 @@
|
||||
# Images for the GregKilmer.com stack on Cosmos. One file, one target per service:
|
||||
#
|
||||
# docker build --target check . runs `npm run check` (typecheck and tests)
|
||||
# docker build --target content . the content service and MCP server
|
||||
# docker build --target admin . the admin page (tailnet only)
|
||||
# docker build --target site . the public site
|
||||
#
|
||||
# The Gitea Actions workflow builds check first, so a red check stops a deploy.
|
||||
# See docs/deploy.md.
|
||||
|
||||
# Pinned by version (Node 22.20, released 2025-09). Override with --build-arg to
|
||||
# pull through a mirror.
|
||||
ARG NODE_IMAGE=node:22.20.0-alpine
|
||||
|
||||
# ---------- package manifests, then every workspace's dependencies ----------
|
||||
FROM ${NODE_IMAGE} AS manifests
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
COPY packages/schema/package.json packages/schema/
|
||||
COPY packages/ui/package.json packages/ui/
|
||||
COPY services/content/package.json services/content/
|
||||
COPY services/admin/package.json services/admin/
|
||||
COPY services/site/package.json services/site/
|
||||
COPY tools/migrate/package.json tools/migrate/
|
||||
|
||||
FROM manifests AS deps
|
||||
RUN npm ci --no-audit --no-fund
|
||||
|
||||
# ---------- typecheck and tests ----------
|
||||
FROM deps AS check
|
||||
COPY . .
|
||||
RUN npm run check
|
||||
|
||||
# ---------- the site's server build ----------
|
||||
FROM deps AS site-build
|
||||
COPY packages packages
|
||||
COPY services/site services/site
|
||||
RUN npm run build -w @gk/site
|
||||
|
||||
# ---------- each service's production dependencies only ----------
|
||||
FROM manifests AS content-deps
|
||||
RUN npm ci --omit=dev --no-audit --no-fund -w @gk/content && npm cache clean --force
|
||||
|
||||
FROM manifests AS admin-deps
|
||||
RUN npm ci --omit=dev --no-audit --no-fund -w @gk/admin && npm cache clean --force
|
||||
|
||||
FROM manifests AS site-deps
|
||||
RUN npm ci --omit=dev --no-audit --no-fund -w @gk/site && npm cache clean --force
|
||||
|
||||
# ---------- shared runtime base ----------
|
||||
FROM ${NODE_IMAGE} AS runtime
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production HOST=0.0.0.0
|
||||
COPY package.json ./
|
||||
COPY packages/schema/package.json packages/schema/
|
||||
COPY packages/schema/src packages/schema/src
|
||||
|
||||
# ---------- content service ----------
|
||||
FROM runtime AS content
|
||||
COPY --from=content-deps /app/node_modules node_modules
|
||||
COPY services/content/package.json services/content/
|
||||
COPY services/content/src services/content/src
|
||||
# The vault's Site folder and the data folder (SQLite and saved form attachments).
|
||||
ENV PORT=4310 SITE_DIR=/vault/Site DATA_DIR=/data
|
||||
EXPOSE 4310
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
||||
CMD wget -qO- http://127.0.0.1:4310/health >/dev/null || exit 1
|
||||
USER node
|
||||
CMD ["node", "--disable-warning=ExperimentalWarning", "--import", "tsx", "services/content/src/main.ts"]
|
||||
|
||||
# ---------- admin page ----------
|
||||
FROM runtime AS admin
|
||||
COPY --from=admin-deps /app/node_modules node_modules
|
||||
COPY services/admin/package.json services/admin/
|
||||
COPY services/admin/src services/admin/src
|
||||
COPY services/admin/public services/admin/public
|
||||
ENV PORT=4320
|
||||
EXPOSE 4320
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
||||
CMD wget -qO- http://127.0.0.1:4320/health >/dev/null || exit 1
|
||||
USER node
|
||||
CMD ["node", "--import", "tsx", "services/admin/src/main.ts"]
|
||||
|
||||
# ---------- public site ----------
|
||||
FROM runtime AS site
|
||||
COPY --from=site-deps /app/node_modules node_modules
|
||||
COPY --from=site-build /app/services/site/dist services/site/dist
|
||||
ENV PORT=4321
|
||||
EXPOSE 4321
|
||||
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
|
||||
CMD wget -qO- http://127.0.0.1:4321/ >/dev/null || exit 1
|
||||
USER node
|
||||
CMD ["node", "services/site/dist/server/entry.mjs"]
|
||||
Reference in New Issue
Block a user