Der laufende Stack läuft unter Compose-Projekt `pageta`; ohne `-p` leitet Compose den Namen aus infrastructure/ ab und kollidiert beim Postgres-Container. --no-deps ersetzt nur pageta-web ohne Postgres anzufassen, kein --remove-orphans wegen pageta-landing aus anderem Compose-File. Beobachtet beim Deploy 2026-06-01. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
156 lines
6.2 KiB
Markdown
156 lines
6.2 KiB
Markdown
# Pageta — Deploy
|
|
|
|
Pageta läuft als Docker-Compose-Stack auf dem **mana-server** (Mac Mini,
|
|
SSH-Alias `mana-server`). Es gibt **kein Auto-Deploy** auf `git push` —
|
|
Deploy ist heute ein expliziter zwei-Schritt-Vorgang (Pull + Compose-Up).
|
|
|
|
> **Status 2026-05-22:** Workflow funktioniert, Auto-Deploy ist offener
|
|
> Punkt (siehe Memory `project_nutriphi_memoro_deploy_gap`). Aufsetzen
|
|
> als Forgejo-Actions-Workflow ist eigene Arbeit.
|
|
|
|
## Stack-Überblick
|
|
|
|
| Service | Container | Port (host) | Domain |
|
|
|---|---|---|---|
|
|
| Postgres | `pageta-postgres` | 5447 | — |
|
|
| API (Hono+Bun) | `pageta-api` | 3099 | `pageta-api.mana.how` |
|
|
| Web (SvelteKit) | `pageta-web` | 3100 | `pageta.mana.how`, `pageta.com` |
|
|
| Landing (Astro) | `pageta-landing` | (siehe `docker-compose.yml` root) | `pageta.com/`-Apex |
|
|
|
|
Daten-Volume: `/Volumes/ManaData/pageta/postgres/`.
|
|
|
|
Pageta joint via `manacore-monorepo_default`-Netzwerk die Plattform-
|
|
Services (mana-auth, mana-credits, mana-news-pool, mana-sync etc.).
|
|
|
|
## Voraussetzungen auf dem Server
|
|
|
|
```
|
|
~/projects/pageta/ # Forgejo-Klon, branch main
|
|
├── infrastructure/
|
|
│ ├── docker-compose.production.yml # SOT für Stack
|
|
│ └── .env.production # gitignored, enthält Secrets
|
|
├── .npmrc # gitignored, Verdaccio-Token
|
|
└── ...
|
|
```
|
|
|
|
`.env.production` enthält:
|
|
- `NPM_AUTH_TOKEN` (Verdaccio claudebot — Build-only, siehe Memory
|
|
`secret_npm_auth_token_macmini`)
|
|
- `PAGETA_DB_PASSWORD`
|
|
- `MANA_SERVICE_KEY`
|
|
- `PAGETA_APP_SERVICE_KEY`
|
|
- App-URL-Overrides falls nötig
|
|
|
|
## Deploy — Standard-Workflow
|
|
|
|
```bash
|
|
# 1. Lokal: committen + pushen
|
|
git add -A && git commit -m "..."
|
|
git push
|
|
|
|
# 2. Auf den Server, pullen + bauen + restarten
|
|
ssh mana-server # von außerhalb: ssh mana-server-remote
|
|
cd projects/pageta
|
|
git pull --ff-only
|
|
export PATH=/opt/homebrew/bin:$PATH # SSH non-login PATH hat docker nicht
|
|
docker compose -p pageta \
|
|
-f infrastructure/docker-compose.production.yml \
|
|
--env-file infrastructure/.env.production \
|
|
up -d --no-deps --build pageta-web # oder pageta-api, oder beide ohne Service-Argument
|
|
```
|
|
|
|
> **`-p pageta` ist Pflicht.** Der laufende Stack wurde unter dem
|
|
> Compose-Projekt `pageta` gestartet (Netzwerk `pageta_default`). Ohne
|
|
> `-p` leitet Compose den Projektnamen aus dem `infrastructure/`-Ordner
|
|
> ab (`infrastructure`) und legt einen **zweiten** Stack an → Postgres-
|
|
> Container-Namenskonflikt (`"/pageta-postgres" is already in use`), der
|
|
> Web-Container wird nicht ersetzt. Beobachtet 2026-06-01.
|
|
>
|
|
> **`--no-deps` beim selektiven Rebuild**: ersetzt nur `pageta-web`, ohne
|
|
> `pageta-postgres` anzufassen (das läuft mit den Daten weiter). Ohne
|
|
> `--no-deps` versucht Compose die Dependency-Kette mitzuziehen.
|
|
>
|
|
> **Kein `--remove-orphans`**: `pageta-landing` kommt aus einem anderen
|
|
> Compose-File (root) und gilt sonst als Orphan → würde gelöscht.
|
|
|
|
Smoke-Test:
|
|
```bash
|
|
curl -sI https://pageta.com/lese-liste | head -3
|
|
curl -sI https://pageta-api.mana.how/healthz | head -3
|
|
```
|
|
|
|
## Falls Server-Working-Tree dirty ist
|
|
|
|
Beobachtet 2026-05-22 (commit `e9a03e8`): Server hatte ~3000 Zeilen
|
|
uncommitted Edits aus historischen `rsync`-Pushes, die aber alle
|
|
inzwischen in `origin/main` lagen. Sauber zurücksetzen:
|
|
|
|
```bash
|
|
ssh mana-server
|
|
cd projects/pageta
|
|
|
|
# Backup (inkl. untracked, weil .env.production untracked)
|
|
git stash push -u -m "rsync-pre-deploy-$(date +%F)"
|
|
|
|
# Pull
|
|
git pull --ff-only
|
|
|
|
# Stash zurückspielen (nur .env.production drin)
|
|
git stash pop
|
|
# → Konflikte auf bereits-in-origin-Files? Mit HEAD-Version auflösen:
|
|
git restore --source=HEAD <konflikt-files>
|
|
|
|
# Wenn Working-Tree clean + .env.production wieder da: stash droppen
|
|
git stash drop
|
|
```
|
|
|
|
**Achtung:** `git stash -u` packt **untracked** Files mit ein. Wenn
|
|
`.env.production` untracked ist (sollte sein — Secrets gehören nicht in
|
|
git), wird sie gestasht. Bei stash pop kommt sie zurück, aber die Re-
|
|
Hydration via Conflict-Resolution braucht Sorgfalt.
|
|
|
|
## Was beim Deploy passiert
|
|
|
|
1. `git pull` → bringt aktuelles `origin/main` rein
|
|
2. `docker compose ... up -d --build pageta-web` →
|
|
- liest aktuelles `apps/web/`-Source
|
|
- baut Image `pageta-web:local` aus `apps/web/Dockerfile`
|
|
- tauscht Container atomisch (`up -d` mit existing service)
|
|
3. Healthcheck via `wget http://localhost:3100/`
|
|
4. Cloudflare-Tunnel (`cloudflared` auf dem Server, Config in
|
|
`managarten/cloudflared-config.yml`) leitet `pageta.mana.how` und
|
|
`pageta.com` auf `localhost:3100` weiter
|
|
|
|
## Selektiver Rebuild
|
|
|
|
Alle mit `-p pageta -f infrastructure/docker-compose.production.yml
|
|
--env-file infrastructure/.env.production` davor (oben weggelassen für
|
|
Lesbarkeit).
|
|
|
|
| Worauf | Was bauen |
|
|
|---|---|
|
|
| Nur Web-/UI-Änderung | `up -d --no-deps --build pageta-web` |
|
|
| Nur API-Änderung | `up -d --no-deps --build pageta-api` |
|
|
| Beide | `up -d --build` (ohne Service-Argument, ohne `--no-deps`) |
|
|
| DB-Migration | Containers neu starten — Auto-Apply via `PAGETA_RUN_MIGRATIONS=true` |
|
|
| Landing | aus `docker-compose.yml` (root) — `up -d --build pageta-landing` |
|
|
|
|
## Falls Build fehlschlägt
|
|
|
|
| Symptom | Ursache | Fix |
|
|
|---|---|---|
|
|
| `NPM_AUTH_TOKEN` undefined | `.env.production` fehlt oder Variable nicht drin | nachtragen, siehe Memory `secret_npm_auth_token_macmini` |
|
|
| `.npmrc` not found | Im Container nicht gefunden | sicherstellen dass `apps/web/Dockerfile` `.npmrc` per `COPY` einbindet ODER über Build-Arg + Inline-Write |
|
|
| `pageta-postgres unhealthy` | Volume-Permission oder Schema-Reset | siehe Memory `project_nutriphi_db_password.md` |
|
|
| Network `manacore-monorepo_default` not found | Plattform-Stack down | erst `cd ~/projects/mana && docker compose up -d` (oder wo immer mana-platform läuft) |
|
|
| `colima` egress timeout / Docker-Hub-Pulls broken | bekannter Bug | `colima restart` via ssh, siehe Memory `feedback_colima_egress_workaround.md` |
|
|
|
|
## Offene Punkte
|
|
|
|
- **Auto-Deploy via Forgejo Actions** auf `push` zu `main` mit
|
|
`workflow_dispatch`-Fallback. Würde den `ssh + pull + build`-Loop
|
|
ersetzen.
|
|
- **Healthcheck-basiertes Rollback:** wenn neuer Build unhealthy startet,
|
|
alten Container behalten statt blind zu ersetzen.
|
|
- **Build-Cache:** Layer-Cache via Buildx-Cache-Mount für schnellere
|
|
Re-Builds (heute jeder Build downloaded pnpm-store frisch).
|