# git-pages → Nginx + PV -arkkitehtuuri > Päivitetty: 2026-06-28 ## Ongelma git-pages storage v2 pakottaa kaikki tiedostot yhteen `.index`-protobufiin per site. Raja on 1MB kovakoodattu. Yksi monorepo täytti tämän, eikä uusia raportteja voi julkaista ennen kuin ongelma on ratkaistu. ## Ratkaisu Poista git-pages kokonaan. Korvaa Nginx:llä (static serving) + kevyellä upload-sidecarilla (tar.gz HTTP PUT → extract). Tiedostot suoraan PV:llä ilman `.index`-välikerrosta. ## Lukitut päätökset 1. **git-pages poistuu** — sovellus ei ole mukana luku- eikä kirjoitusketjussa 2. **Nginx palvelee suoraan PV:ltä** — `root /data`, `autoindex on`, `try_files $uri $uri/ $uri/index.html =404` 3. **Upload-sidecar** — busybox httpd + CGI, ottaa vastaan `PUT /path` + tar.gz body ja purkaa PV:lle 4. **URL = FS-polku** — ei Host-header-kikkaa, ei slugia, ei rewritea 5. **Traefik** — PATCH/PUT → upload-sidecar:8081 (BasicAuth), GET/HEAD → nginx:8080 (ForwardAuth myöh.) 6. **CI-julkaisu** — `curl -X PUT --data-binary @report.tar.gz https://{host}/{owner}/{repo}/{branch_raw}/{sha8}/{suite}/` 7. **Branch raakana URL:ssa** — `feature/x` URL:ssa = `feature/x/` FS:ssä. Ei slugitusta 8. **Linkki on aina 1-suuntainen** — gitea → raportti. Raportista ei linkkiä giteaan 9. **GITEA_API_URL poistuu** publish-skriptin pakollisista env-varista (retention käyttää omaansa) ## Ympäristömuuttujat ### GITHUB_REF_NAME Gitea Actions runnerin automaattisesti asettama muuttuja, joka on branchin/tagin nimi ilman `refs/heads/`-etuliitettä. | Tilanne | Arvo | |---------|------| | branch `main` | `main` | | branch `feature/branch` | `feature/branch` | | tag `v1.0.0` | `v1.0.0` | Käytännössä `git rev-parse --abbrev-ref HEAD`. Branchin `/` on sallittu URL-polussa, joten `GITHUB_REF_NAME` voidaan käyttää sellaisenaan rakenteessa `${GITHUB_REF_NAME}/${SHA8}/${SUITE}`. Rinnakkaisissa buildeissa jokainen runner ajaa oman branchinsa kontekstissa → URL pysyy uniikkina. ``` CI → curl -X PUT → Traefik (BasicAuth middleware) → upload-sidecar:8081 (busybox httpd + CGI) → tar -xzf - -C /data/{owner}/{repo}/{branch}/{sha8}/{suite}/ → PV /app/data/ Browser → GET → Traefik → nginx:8080 (root /app/data) → /data/{owner}/{repo}/{branch}/{sha8}/{suite}/index.html ``` ## Tiedostomuutokset ### Poistuu (4 tiedostoa) | Tiedosto | Miksi | |----------|-------| | `templates/init-job.yaml` | Ei enää git-pages API:a alustettavaksi | | `templates/configmap.yaml` (nykyinen) | Korvataan nginx-conf + CGI | | `templates/deployment.yaml` (nykyinen) | Korvataan uudella | | `git-pages-image` (values.yaml) | Ei enää git-pages-konttia | ### Muuttuu (8 tiedostoa) | # | Tiedosto | Muutos | |---|----------|--------| | 1 | `Chart.yaml` | description, poista appVersion | | 2 | `values.yaml` | Poista git-pages-keyt, lisää nginx/sidecar | | 3 | `dev-values.yaml` | Matchaa uusi values-rakenne | | 4 | `templates/configmap.yaml` | `nginx.conf` + `upload.sh` (CGI) | | 5 | `templates/deployment.yaml` | 2 konttia: nginx:alpine (8080) + busybox httpd (8081) | | 6 | `templates/ingressroute.yaml` | Backend: PATCH/PUT → upload:8081, GET/HEAD → nginx:8080 | | 7 | `templates/service.yaml` | 2 porttia: http-read(8080), http-write(8081) | | 8 | `templates/NOTES.txt` | Uusi URL + esimerkit | ### Pysyy ennallaan (8 tiedostoa) | Tiedosto | Huomio | |----------|--------| | `templates/certificate.yaml` | TLS hostille | | `templates/middleware.yaml` | BasicAuth + HTTPS redirect | | `templates/publish-auth-secret.yaml` | Sama BasicAuth-secret | | `templates/pvc.yaml` | Sama PVC | | `templates/retention-configmap.yaml` | Päivitä retention-scriptit | | `templates/retention-cronjob.yaml` | Pieni muutos (ei git-pages API) | | `templates/retention-rbac.yaml` | Ennallaan | | `_helpers.tpl` | Vain label-helpers | ### Chartin ulkopuolella | Tiedosto | Muutos | |----------|--------| | `scripts/publish-git-pages.sh` | Uusi: `curl -X PUT` tar.gz upload-sidecariin | | `scripts/report-status.sh` | Tarkista URL-muoto | | `git-pages/docs/architecture.md` | Uusi arkkitehtuuri | | `docs/design-rationale.md` | Päivitys | | `files/retention-*.sh` | Lue PV:tä suoraan, ei git-pages API:a | ## Nginx-konfiguraatio (ydin) ```nginx server { listen 8080; root /app/data; autoindex on; location / { try_files $uri $uri/ $uri/index.html =404; } } ``` ## Upload CGI (ydin) ```bash #!/bin/sh read -r method uri _ case "$method" in PUT) dest="/app/data${uri%/*}" # strip filename mkdir -p "$dest" cat - | tar -xzf - -C "$dest" echo "Status: 201 Created" echo "" ;; esac ``` ## Deployment (kontit) ```yaml containers: - name: nginx image: nginx:alpine ports: - containerPort: 8080 name: http-read volumeMounts: - name: nginx-conf mountPath: /etc/nginx/conf.d - name: data mountPath: /app/data - name: upload image: alpine:latest command: ["busybox", "httpd", "-f", "-p", "8081", "-h", "/cgi"] ports: - containerPort: 8081 name: http-write volumeMounts: - name: cgi-scripts mountPath: /cgi readOnly: true - name: data mountPath: /app/data ``` ## CI-julkaisu (publish-skripti) ### Muutokset nykyiseen | Kohta | Nykyinen | Uusi | |-------|----------|------| | `GITEA_API_URL` | pakollinen env-var | **poistettu** (retention käyttää omaansa) | | Tar-prefiksi | `{owner}/{repo}/reports/{sha8}/{suite}` | ei prefiksiä — `{suite}` | | Paketti | `tar -cf` | `tar -czf` (gzip) | | Content-Type | `application/x-tar` | `application/tar+gz` | | Headerit | `Atomic: no`, `Create-Parents: yes` | poistettu | | Kohde | `PATCH {GIT_PAGES_URL}/` | `PUT {GIT_PAGES_URL}/{owner}/{repo}/{branch}/{sha8}/{suite}/` | | Branch | vain `.meta` | URL:ssa + `.meta` | ### Uusi skripti (ydin) ```bash #!/usr/bin/env sh set -eu SUITE_PATH="${1:-}" [ -n "$SUITE_PATH" ] || { echo "ERROR: suite_path required" >&2; exit 1; } [ -n "${GIT_PAGES_URL:-}" ] || { echo "ERROR: GIT_PAGES_URL is not set" >&2; exit 1; } [ -n "${GIT_PAGES_PUBLISH_TOKEN:-}" ] || { echo "ERROR: GIT_PAGES_PUBLISH_TOKEN is not set" >&2; exit 1; } [ -n "${GITHUB_REPOSITORY:-}" ] || { echo "ERROR: GITHUB_REPOSITORY is not set" >&2; exit 1; } [ -n "${GITHUB_SHA:-}" ] || { echo "ERROR: GITHUB_SHA is not set" >&2; exit 1; } [ -n "${GITHUB_REF_NAME:-}" ] || { echo "ERROR: GITHUB_REF_NAME is not set" >&2; exit 1; } OWNER="${GITHUB_REPOSITORY%%/*}" REPO="${GITHUB_REPOSITORY##*/}" SHA8=$(echo "$GITHUB_SHA" | cut -c1-8) BRANCH="${GITHUB_REF_NAME}" SUITE="${SUITE_PATH%/}" PAGES_USER="${GIT_PAGES_PUBLISH_USER:-publish}" [ -d "$SUITE" ] || { echo "ERROR: not a directory: $SUITE" >&2; exit 1; } WORK=$(mktemp -d) TAR=$(mktemp) trap 'rm -rf "$WORK" "$TAR"' EXIT # Kopioi raporttitiedostot mkdir -p "$WORK/$SUITE" cp -a "$SUITE/." "$WORK/$SUITE/" # Generoi index.html (sama logiikka kuin nykyään) cd "$WORK" if [ ! -f "$SUITE/index.html" ]; then # identtinen item-listaus kuin nykyisessä skriptissä … fi # .meta tiedosto retentionia varten cat > "$SUITE/.meta" <&2 cat /tmp/git-pages-publish-response.txt >&2 exit 1 ;; esac echo "${PUBLISH_URL}" ``` ## Gitea commit -linkki (report-status.sh) Gitean commit-näkymään tuleva raporttilinkki muodostetaan `scripts/report-status.sh`:ssa. ### Muutos | Kohta | Nykyinen (rivi 21) | Uusi | |-------|-------------------|------| | URL | `${GIT_PAGES_URL}/${GITHUB_REPOSITORY}/reports/${SHA8}/${SUITE}` | `${GIT_PAGES_URL}/${GITHUB_REPOSITORY}/${GITHUB_REF_NAME}/${SHA8}/${SUITE}` | `reports/` → `{GITHUB_REF_NAME}/`. Branchin raaka nimi URL-polussa on sallittu. Muu skripti (Gitea API -kutsu, token, json-body) pysyy identtisenä. Tarkista: `GITHUB_REF_NAME` on oltava asetettu — Gitea Actions asettaa sen automaattisesti. Jos sitä tarvitaan tarkistuksena, lisätään `report-status.sh`:n env-var-tarkistuksiin. ## Gitea Actions step summary (report-summary.yml) `.gitea/workflows/report-summary.yml` luo GITHUB_STEP_SUMMARY -taulukon raporttilinkeillä. ### Muutos | Kohta | Nykyinen (rivi 28) | Uusi | |-------|-------------------|------| | BASE | `${GIT_PAGES_URL}/${GITHUB_REPOSITORY}/reports/${SHA8}` | `${GIT_PAGES_URL}/${GITHUB_REPOSITORY}/${GITHUB_REF_NAME}/${SHA8}` | Sama muuri: `reports/` → `${GITHUB_REF_NAME}/`. Loppuosa identtinen. ## Retention Retention siirtyy lukemaan PV:tä suoraan (find, ls, stat) git-pages API:n sijaan: 1. Listaa kaikki kansiot `/app/data/{owner}/{repo}/{branch}/{sha8}/` 2. Lue `.meta` jokaisesta 3. Tarkista branchin olemassaolo Gitea API:lla 4. Poista vanhat/kuolleet branchit kansiorakenteesta (`rm -rf`) ## Avoimet asiat (ei tässä MVP:ssä) - ForwardAuth GET/HEAD-reitille (OIDC) - 6 rinnakkaisen testin orkestrointi