Normalizes market names for dedup matching: lowercase, umlaut expansion,
punctuation stripping, whitespace collapse, and leading/trailing filler
word removal. Guards stripping so edge fillers are preserved when the
remaining content is purely numeric (e.g. 'Markt 2026' stays 'markt 2026').
The home page dropped `plz` server-side, so /markets was called with
radius but no center (unfiltered) and the PLZ input rendered empty
after reload. +page.server.ts now reads plz, geocodes via /geocode,
and echoes plz back in searchParams for form rehydration.
Relaxes /geocode DTO + guard to accept PLZ without city — Nominatim
already supports postal-only lookups. URL lat/lon (GPS flow) take
priority over plz on tie-break; geocode failures fall through to no
geo-filter so the page always renders.
Post-process adapter-node output into a single self-contained
build/bundle.mjs (614 KB) via esbuild, then ship it on a fresh
alpine:3.21 base with just the node binary copied in. Drops the
node_modules + package manager baggage that comes with node:25-alpine.
- Add esbuild devDep + `bundle` script (scripts/bundle.mjs)
- Dockerfile: drop `deps` stage; final stage is alpine + node binary +
bundle + static client assets
- Uncompressed image: 177 MB -> 149 MB (-16%)
- Verified: /, /healthz, static assets all respond identically;
outbound TLS to api.marktvogt.de works via node's built-in CA bundle
- CLAUDE.md: correct stale Woodpecker/submodules claims; note
registry.itsh.dev's attestation requirement and the docker-container
driver prerequisite so future contributors don't rediscover the issue.
- .gitlab-ci.yml: export SOURCE_DATE_EPOCH from commit time so the
rewrite-timestamp=true buildx flag produces genuinely reproducible
images (layer digests stable across rebuilds of the same commit).
The alpine/helm:4.1 image has 'helm' as ENTRYPOINT. GitLab CI wraps
step_script in sh, which the container resolves to 'helm sh ...',
failing with 'unknown command sh for helm'. Setting entrypoint: [""]
lets GitLab's sh wrapper execute normally before invoking helm.
buildx create --driver docker-container cannot inherit TLS env vars
from docker:dind directly; it needs a named context. Create 'tls-env'
from the ambient DOCKER_HOST/DOCKER_CERT_PATH, then point buildx at it.
The default buildx driver inside docker:29-dind is 'docker' (host daemon),
which cannot produce attestations. Even with default provenance enabled,
the docker driver silently drops attestation-related flags and emits a
bare single-image manifest. registry.itsh.dev (Zot with strict attestation
policy) rejects these with 'manifest invalid'.
Creating a 'docker-container' driver builder before each build gives
buildkit full export capabilities, matching both the Woodpecker plugin's
behavior and what works from local development machines.
Empirical finding: registry.itsh.dev rejects pushes that contain zero
attestations ("manifest invalid"). Attestations cause buildx to emit
an OCI image index; without any, it emits a bare single-image manifest
which this Zot instance refuses in this namespace.
Remove --provenance=false --sbom=false, switch to the explicit output
form matching woodpeckerci/plugin-docker-buildx (proven working against
the same registry for the infinity-tales project).
Root cause of the original 610ca91 regression: that commit added
--provenance=false, which stripped the last required attestation once
SBOM generation was disabled in a later buildkit default change.
The woodpeckerci/plugin-docker-buildx image that successfully pushes to
this same registry uses docker:29.4.0-dind with buildx 0.33.0. Version
skew between docker:27's bundled buildkit and the registry is the next
hypothesis after ground-truth manifest inspection ruled out OCI format
and attestations as the cause.
Previously only backend/** or web/** file changes would trigger the
respective docker+deploy jobs. CI config changes now also trigger
rebuilds of both services, ensuring any pipeline-definition changes
are verified end-to-end on the same commit that introduces them.
Matches woodpeckerci/plugin-docker-buildx defaults. Without --sbom=false
buildkit emits an OCI image index with SBOM attestation that the itsh.dev
registry rejects with 'manifest invalid'. Provenance was already disabled.
- Replace bun with pnpm (v10.33.0) via corepack
- Upgrade all Docker images from node:22/bun to node:25-alpine
- Update CI pipeline, pre-commit hooks, and prettierignore
- Add packageManager field to package.json for version pinning
- Upgrade CI deploy to Helm 4.1 with --rollback-on-failure --wait=watcher
- Replace initialDelaySeconds with startup probe (15x2s=30s window)
- Set resources req=limit (100m/128Mi) for Guaranteed QoS class
- Add ConfigMap checksum annotation to trigger rollouts on config changes
- Set resources req=limit (100m/128Mi) for Guaranteed QoS class
- Add ConfigMap checksum annotation to trigger rollouts on config changes
- Add retry limit (60 attempts) to migration init container
- Use TARGETARCH in Dockerfile for multi-arch build support
- Set GOMAXPROCS and GOMEMLIMIT from cgroup limits to prevent
thread oversubscription and unbounded GC memory growth
- Add startup probe (60s budget) to gate liveness/readiness during
connection pool initialization
- Increase liveness failureThreshold to 5 to avoid restarts on
transient issues
- Remove initialDelaySeconds (startup probe replaces this)
- Upgrade CI from alpine/helm:3.17 to alpine/helm:4.1
- Replace deprecated --atomic with --rollback-on-failure + --wait=watcher
BusyBox 1.37 nc -z is broken (outputs "punt!" and never exits),
causing the wait-for-cache init container to loop indefinitely.
The cache is healthy — the backend should handle reconnects itself.