No description
  • Dockerfile 40%
  • Go Template 27%
  • Python 17.6%
  • Shell 15.4%
Find a file
statevault f9530043bc docs: capture EOD state + flag signup-wizard collision under SSO
docs/STATE.md — what's deployed where, what works, the four known
gaps, day-to-day ops (restart, re-seed, cert reissue, end-to-end
test recipe).

docs/oidc-integration.md — update status header with the three
relevant upstreams/tapir commits and call out the post-SSO
onboarding gap (wizard INSERTs duplicate TapirUser, shows misleading
'Ungültige IBAN'). Diagnosis lives in aienv memory; this doc points
at it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 21:55:25 +02:00
.woodpecker chore(ci): pin kaniko to v1.20.0-debug for sm-zot cache compatibility 2026-05-12 21:17:32 +02:00
base chore(upstream): bump loco-main — post-SSO redirect for non-Members 2026-05-12 20:55:44 +02:00
docs docs: capture EOD state + flag signup-wizard collision under SSO 2026-05-12 21:55:25 +02:00
helm/tapir fix(chart): collectstatic initContainer on tapir-web 2026-05-12 21:30:28 +02:00
.gitignore feat(base): vendor upstream Tapir as submodule at base/upstream 2026-05-12 15:13:13 +02:00
.gitmodules feat(base): repoint upstream submodule to upstreams/tapir (loco-main) 2026-05-12 16:33:48 +02:00
bao.yml feat: initial scaffolding for Tapir on the cluster 2026-05-12 15:12:07 +02:00
CHANGELOG.md feat: initial scaffolding for Tapir on the cluster 2026-05-12 15:12:07 +02:00
README.md feat: initial scaffolding for Tapir on the cluster 2026-05-12 15:12:07 +02:00

workloads-tapir

Helm chart + image build for Tapir — a Django/Celery member-management platform for community-supported agriculture (Solawi/CSA).

Upstream is github.com/FoodCoopX/wirgarten-tapir (AGPL-3, by FoodCoopX/WirGarten). We deploy a customized image:

  • swaps Tapir's standalone Postgres for shared-pg (CNPG)
  • swaps Tapir's standalone Redis for the cluster Valkey
  • drops Tapir's bundled Keycloak (auth strategy is phased — see docs/oidc-integration.md)
  • drops Tapir's vite dev server (frontend built at image time, served via whitenoise)

Status

Phase 0 — scaffolding only. Nothing is deployed. The plan lives in docs/ARCHITECTURE.md; the chart skeleton is in helm/tapir/. Image build pipeline is in .woodpecker/release-base.yml.

Layout

.
├── README.md                       # you are here
├── bao.yml                         # OpenBao scope manifest
├── CHANGELOG.md                    # release notes (managed by bump.sh)
├── base/
│   ├── Containerfile               # multi-stage build of our customized Tapir image
│   ├── entrypoint.sh               # runs migrate, then gunicorn / celery / beat depending on $TAPIR_ROLE
│   ├── settings-overrides.py       # tapir.settings.overrides — DATABASES/CACHES/AUTH delta
│   ├── patches/                    # quilt-style patches applied during the image build
│   │   └── 0001-defer-keycloak-admin-calls.patch   # phase-2 OIDC swap (see docs)
│   └── requirements-overrides.txt  # any pin deltas we need
├── docs/
│   ├── ARCHITECTURE.md             # the big plan — read first
│   ├── oidc-integration.md         # phase-2 SSO plan (Keycloak vs patched)
│   └── runbook-bootstrap.md        # first-deploy bootstrap steps
├── helm/tapir/
│   ├── Chart.yaml
│   ├── values.yaml                 # production-safe defaults
│   ├── values-dev.yaml             # local/dev overrides (no OIDC, no public ingress)
│   ├── values-prod.yaml            # *.dev.loop-coop.net + public domain
│   └── templates/
│       ├── _helpers.tpl
│       ├── configmap.yaml          # non-secret env (SITE_URL, ALLOWED_HOSTS, log level…)
│       ├── secretstore.yaml        # ESO → openbao
│       ├── externalsecret.yaml     # vault path → k8s Secret (DSN, secret_key, OIDC client)
│       ├── deployment-web.yaml     # gunicorn (replicas, HPA-target)
│       ├── deployment-celery.yaml  # celery worker
│       ├── deployment-celery-beat.yaml  # celery beat
│       ├── job-migrate.yaml        # pre-upgrade `manage.py migrate`
│       ├── job-bootstrap.yaml      # one-shot `manage.py parameter_definitions` on first install
│       ├── service-web.yaml
│       ├── ingress-mesh.yaml       # tapir.dev.loop-coop.net (mTLS)
│       ├── ingress-public.yaml     # off by default — flip for public Solawi sign-up
│       ├── networkpolicy.yaml
│       └── pdb.yaml
└── .woodpecker/
    ├── release-base.yml            # kaniko → loco/workloads-tapir/tapir-base
    └── release.yml                 # helm chart packaging on bump

Quick start (when chart is ready)

helm install tapir helm/tapir \
  --namespace tapir --create-namespace \
  -f helm/tapir/values-dev.yaml

Bootstrap (one-shot, after first deploy):

kubectl -n tapir wait --for=condition=complete job/tapir-migrate
kubectl -n tapir wait --for=condition=complete job/tapir-bootstrap
# then access https://tapir.dev.loop-coop.net/

Image build

# tag-triggered: push base-v<series>.<patch> → builds image
git tag base-v1.0.0
git push origin base-v1.0.0
# → kaniko builds + pushes to git.loop-coop.net/loco/workloads-tapir/tapir-base
# → cache layers go to sm-zot (10.90.0.2:5000/workloads-tapir/tapir-base/cache)

Cross-references