| name | helm-deploy |
| description | Deploy sparq-server or configure the planned native sparq-lws-core deployment on Kubernetes with the in-repo Helm chart or plain quickstart manifest. Use when installing, configuring, exposing, upgrading, or validating deploy/helm/sparq, including existing-Secret auth, ingress-nginx TLS, selector-dependent images/ports/probes, persistent data, and single-replica safety constraints. |
Deploy sparq with Helm
[GPT-5.6] Verified against deploy/helm/sparq on 2026-07-15. The chart targets
Kubernetes 1.20 or later and does not build images. The sparq-server GHCR image
is published; the LWS selector becomes runnable only after sq-lmz40 publishes its image.
Preserve the security boundary
Treat these as invariants:
- Keep
SPARQ_AUTH_TOKEN in an existing Kubernetes Secret. Never pass a token
through Helm values or commit a Secret manifest.
- Keep the built-in Service as
ClusterIP. Use the optional ingress-nginx
Ingress for public access; it requires a TLS Secret and forces HTTPS redirects.
- Keep the chart's non-root, read-only-root-filesystem, dropped-capability, and
disabled-service-account-token settings.
- Use
/health on port 3030 for sparq-server; use /livez and /readyz on
port 3000 for lws.
- [GPT-5.6] Run exactly one replica of either server.
sparq-server has an
unreplicated writable in-memory store. The planned canonical LWS image lacks
its opt-in Redis replay backend, and Redis alone would not provide a shared blob store.
The sparq-server image is open by default at the image layer because it bakes
SPARQ_ALLOW_REMOTE=1. The chart refuses to render that server without an auth
Secret. Do not remove the token wiring. The token always gates writes; set
auth.requireTokenForReads=true to gate reads too.
Install sparq-server privately
Create the Secret before installing the chart:
kubectl create namespace sparq
kubectl create secret generic sparq-auth-token \
--namespace sparq \
--from-literal=SPARQ_AUTH_TOKEN="$(openssl rand -hex 32)"
helm upgrade --install sparq ./deploy/helm/sparq \
--namespace sparq \
--set auth.existingSecret=sparq-auth-token
This creates only a ClusterIP Service. Test it over a local port-forward:
kubectl port-forward --namespace sparq svc/sparq 3030:3030
curl http://127.0.0.1:3030/health
Expose sparq-server over HTTPS
Use the built-in Ingress only with ingress-nginx and a pre-provisioned or
cert-manager-managed TLS Secret:
helm upgrade --install sparq ./deploy/helm/sparq \
--namespace sparq \
--set auth.existingSecret=sparq-auth-token \
--set auth.requireTokenForReads=true \
--set ingress.enabled=true \
--set ingress.host=sparq.example.com \
--set-string 'ingress.annotations.cert-manager\.io/cluster-issuer=letsencrypt-prod' \
--set ingress.tls.enabled=true \
--set ingress.tls.secretName=sparq-tls
For a different Ingress or Gateway controller, leave ingress.enabled=false
and create a controller-specific HTTPS-only route to the ClusterIP Service.
Install LWS
Use this path only after sq-lmz40 publishes ghcr.io/sparq-org/sparq-lws-core.
Supply HTTPS URLs for the public base URL and trusted OIDC issuer. Selecting
server=lws automatically selects ghcr.io/sparq-org/sparq-lws-core, port
3000, SOLID_SERVER_BIND=0.0.0.0:3000, /livez, and /readyz.
helm upgrade --install sparq-lws ./deploy/helm/sparq \
--namespace sparq-lws \
--create-namespace \
--set server=lws \
--set lws.trustedIssuer=https://idp.example.com \
--set lws.baseUrl=https://pod.example.com \
--set ingress.enabled=true \
--set ingress.host=pod.example.com \
--set ingress.tls.enabled=true \
--set ingress.tls.secretName=lws-tls
Do not scale this release horizontally. A future image and chart revision must
provide both shared replay protection and a shared durable data/blob path before
raising replicaCount.
Use persistence and private images
- Set
persistence.enabled=true to create a PVC mounted at /data, or also set
persistence.existingClaim to use a pre-provisioned PVC.
- Leave
image.repository empty for the selector-dependent canonical image.
Set image.repository, image.tag, and imagePullSecrets for a fork, pinned
release, or private registry. The default latest tag uses pull policy
Always; use IfNotPresent only with an immutable tag.
- Set
service.port only to change the cluster-internal Service port. The
container port and health contract remain selector-dependent.
Use the plain manifest
Follow the header in
deploy/helm/quickstart/sparq-server-quickstart.yaml. Create the namespace and
sparq-auth-token Secret separately, then apply the file. It intentionally
contains no Ingress and no Secret object.
Validate changes
helm lint ./deploy/helm/sparq --set auth.existingSecret=test-secret
helm template sparq ./deploy/helm/sparq \
--set auth.existingSecret=test-secret > /tmp/sparq.yaml
kubeconform -strict -summary -exit-on-error /tmp/sparq.yaml
Read deploy/helm/README.md and deploy/helm/sparq/values.yaml for the complete
value reference. Unsafe combinations fail during helm lint or helm template
through values.schema.json.