9.2 KiB
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
- git-pages poistuu — sovellus ei ole mukana luku- eikä kirjoitusketjussa
- Nginx palvelee suoraan PV:ltä —
root /data,autoindex on,try_files $uri $uri/ $uri/index.html =404 - Upload-sidecar — busybox httpd + CGI, ottaa vastaan
PUT /path+ tar.gz body ja purkaa PV:lle - URL = FS-polku — ei Host-header-kikkaa, ei slugia, ei rewritea
- Traefik — PATCH/PUT → upload-sidecar:8081 (BasicAuth), GET/HEAD → nginx:8080 (ForwardAuth myöh.)
- CI-julkaisu —
curl -X PUT --data-binary @report.tar.gz https://{host}/{owner}/{repo}/{branch_raw}/{sha8}/{suite}/ - Branch raakana URL:ssa —
feature/xURL:ssa =feature/x/FS:ssä. Ei slugitusta - Linkki on aina 1-suuntainen — gitea → raportti. Raportista ei linkkiä giteaan
- 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)
server {
listen 8080;
root /app/data;
autoindex on;
location / {
try_files $uri $uri/ $uri/index.html =404;
}
}
Upload CGI (ydin)
#!/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)
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)
#!/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" <<EOF
{"branch":"${BRANCH}","sha":"${GITHUB_SHA}","published_at":"$(date -u +%Y-%m-%dT%H:%M:%SZ)"}
EOF
# Pakkaa
tar czf "$TAR" -C "$WORK" "$SUITE"
# PUT upload-sidecariin
PUBLISH_URL="${GIT_PAGES_URL}/${OWNER}/${REPO}/${BRANCH}/${SHA8}/${SUITE}/"
HTTP_CODE=$(curl -sS -X PUT "$PUBLISH_URL" \
-u "${PAGES_USER}:${GIT_PAGES_PUBLISH_TOKEN}" \
-H "Content-Type: application/tar+gz" \
--data-binary @"$TAR" \
-o /tmp/git-pages-publish-response.txt \
-w "%{http_code}")
case "$HTTP_CODE" in
200|201|204) ;;
*)
echo "ERROR: publish HTTP ${HTTP_CODE}" >&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:
- Listaa kaikki kansiot
/app/data/{owner}/{repo}/{branch}/{sha8}/ - Lue
.metajokaisesta - Tarkista branchin olemassaolo Gitea API:lla
- Poista vanhat/kuolleet branchit kansiorakenteesta (
rm -rf)
Avoimet asiat (ei tässä MVP:ssä)
- ForwardAuth GET/HEAD-reitille (OIDC)
- 6 rinnakkaisen testin orkestrointi