From b03165ce97813562cf5f8a669fbdb83ef9567a15 Mon Sep 17 00:00:00 2001 From: Till JS Date: Thu, 7 May 2026 16:27:45 +0200 Subject: [PATCH] feat(gpu-box): news-ingester migrated, Mini compose drops the service block MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 2f-2. RSS/Atom ingester (15-min tick → mana_platform.news.curated_articles) moved to GPU-Box. Service has zero hot-path coupling, all the writes go cross-LAN to Mini-postgres analog to the Glitchtip pattern. Two implementation gotchas worth recording: 1. cross-arch image transfer doesn't work. Saved news-ingester:local from the Mini (Apple M4 → linux/arm64), tried `docker load` on the GPU-Box (linux/amd64) and got 'exec format error' on every restart. Native build on the GPU-Box was the only path forward. 2. The original services/news-ingester/Dockerfile assumes pnpm-workspace state from prior builds (no COPY for packages/shared-rss in the build context). Fresh builds error with ERR_PNPM_WORKSPACE_PKG_NOT_FOUND. Workaround: a GPU-Box-specific Dockerfile at infrastructure/news-ingester/ that vendors shared-rss into the build via a workspace:* → file:ref sed swap. Build context is the repo root (sparse-clone provides packages/shared-rss + services/news-ingester). The Mini-side Dockerfile stays untouched so existing CD builds aren't disturbed. Mini-side: container stopped + removed from docker-compose.macmini.yml, running container count 44 → 39. Co-Authored-By: Claude Opus 4.7 (1M context) --- docker-compose.macmini.yml | 33 ----------------------- infrastructure/docker-compose.gpu-box.yml | 30 +++++++++++++++++++++ infrastructure/news-ingester/Dockerfile | 21 +++++++++++++++ 3 files changed, 51 insertions(+), 33 deletions(-) create mode 100644 infrastructure/news-ingester/Dockerfile diff --git a/docker-compose.macmini.yml b/docker-compose.macmini.yml index 5a4680b3f..9b811ac97 100644 --- a/docker-compose.macmini.yml +++ b/docker-compose.macmini.yml @@ -1436,39 +1436,6 @@ services: # from the same table to serve /api/v1/news/feed; user reading lists # remain client-side in the unified Mana app's local IndexedDB. - news-ingester: - build: - context: services/news-ingester - dockerfile: Dockerfile - image: news-ingester:local - container_name: news-ingester - restart: always - mem_limit: 256m - depends_on: - postgres: { condition: service_healthy } - environment: - TZ: Europe/Berlin - PORT: 3066 - DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD:-mana123}@postgres:5432/mana_platform - TICK_INTERVAL_MS: "900000" - RUN_ON_STARTUP: "true" - ports: - - "3066:3066" - healthcheck: - test: ["CMD", "bun", "-e", "fetch('http://127.0.0.1:3066/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"] - interval: 120s - timeout: 10s - retries: 3 - start_period: 30s - - # ============================================ - # Games - # ============================================ - # whopixels was removed 2026-04-09 — its core mechanic (LLM-driven - # historical figure guessing) lives now as the `who` module inside - # apps/mana/apps/web. The standalone Phaser/Node container is gone; - # see docs/WHO_MODULE.md for the migration rationale. - volumes: redis_data: name: mana-redis-data diff --git a/infrastructure/docker-compose.gpu-box.yml b/infrastructure/docker-compose.gpu-box.yml index 3f3cfb609..eb46dfe49 100644 --- a/infrastructure/docker-compose.gpu-box.yml +++ b/infrastructure/docker-compose.gpu-box.yml @@ -493,6 +493,36 @@ services: # lebt jetzt in mana-monorepo's infrastructure/verdaccio/config.yaml, # sparse-clone trägt das Verzeichnis auf der GPU-Box ein. # ============================================ + # ============================================ + # Phase 2f-2 — news-ingester (2026-05-07) + # Background article-ingester — Bun-Service mit 15-min-Tick. Schreibt + # in Mini-Postgres mana_platform via LAN. Reine Background-Last, + # null Hot-Path-Coupling. + # ============================================ + news-ingester: + # GPU-Box-spezifischer Build (services/news-ingester/Dockerfile ist + # nicht workspace-aware; der hier vendored shared-rss als file: ref). + # Cross-arch: GPU-Box ist x86_64, Mini ist arm64 — Image-Transfer + # via docker save/load würde "exec format error" werfen. + build: + context: /srv/mana/source + dockerfile: infrastructure/news-ingester/Dockerfile + image: news-ingester:gpu-box + container_name: news-ingester + restart: unless-stopped + environment: + TZ: Europe/Berlin + PORT: 3066 + DATABASE_URL: postgresql://postgres:${POSTGRES_PASSWORD}@192.168.178.131:5432/mana_platform + TICK_INTERVAL_MS: '900000' + RUN_ON_STARTUP: 'true' + healthcheck: + test: ['CMD', 'bun', '-e', "fetch('http://127.0.0.1:3066/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"] + interval: 120s + timeout: 10s + retries: 3 + start_period: 30s + verdaccio: image: verdaccio/verdaccio:6 container_name: mana-verdaccio diff --git a/infrastructure/news-ingester/Dockerfile b/infrastructure/news-ingester/Dockerfile new file mode 100644 index 000000000..6699a5d14 --- /dev/null +++ b/infrastructure/news-ingester/Dockerfile @@ -0,0 +1,21 @@ +# News-ingester for GPU-Box — workspace-aware (vendors shared-rss). +# Context: repo root. Use this Dockerfile when deploying news-ingester +# on the GPU-Box (the one in services/news-ingester/Dockerfile is +# Mini-side and assumes the cached pnpm-workspace state). +FROM oven/bun:1 AS production +WORKDIR /app + +COPY packages/shared-rss ./packages/shared-rss +COPY services/news-ingester/package.json ./services/news-ingester/ +COPY services/news-ingester/src ./services/news-ingester/src +COPY services/news-ingester/tsconfig.json services/news-ingester/drizzle.config.ts ./services/news-ingester/ + +WORKDIR /app/services/news-ingester +RUN sed -i 's|"@mana/shared-rss": "workspace:\*"|"@mana/shared-rss": "file:../../packages/shared-rss"|' package.json && \ + bun install + +EXPOSE 3066 +HEALTHCHECK --interval=60s --timeout=10s --start-period=30s --retries=3 \ + CMD bun -e "fetch('http://localhost:3066/health').then(r => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))" + +CMD ["bun", "run", "src/index.ts"]