Some checks failed
ci / go (push) Has been cancelled
ci / admin-ui (push) Has been cancelled
ci / runtime-sdk (push) Has been cancelled
ci / helm (push) Has been cancelled
ci / openapi (push) Has been cancelled
ci / container (push) Has been cancelled
ci / release-config (push) Has been cancelled
ci / shared styling (push) Has been cancelled
ci / security (push) Has been cancelled
ci / all green (push) Has been cancelled
481 lines
18 KiB
YAML
481 lines
18 KiB
YAML
# Go Bananas!! Helm values
|
|
#
|
|
# Every value has a safe default so that `helm install` works with no arguments at
|
|
# all. The exceptions are the authentication credentials, which are required when
|
|
# auth.mode is oidc and are supplied through an existing Secret.
|
|
#
|
|
# The defaults are tuned for a small internal deployment. Before running this in
|
|
# production, read the annotated sections: replica count, the ingress, the resource
|
|
# requests and the persistence choice all deserve a deliberate decision.
|
|
|
|
# ------------------------------------------------------------------ global ---
|
|
|
|
global:
|
|
# imageRegistry overrides the registry for every image the chart pulls. Used by a
|
|
# cluster with a mirrored registry or an air-gapped pull-through cache.
|
|
imageRegistry: ""
|
|
# imagePullSecrets are added to every ServiceAccount.
|
|
imagePullSecrets:
|
|
- name: nexus-registry
|
|
# extraLabels are added to every object the chart creates, for cost allocation
|
|
# and for a Prometheus `release` label if the cluster does not add one.
|
|
extraLabels: {}
|
|
# extraAnnotations are added to every object.
|
|
extraAnnotations: {}
|
|
|
|
# ------------------------------------------------------------------- image ---
|
|
|
|
image:
|
|
registry: nexus.urpi.be
|
|
repository: docker-hosted/go-bananas
|
|
# tag defaults to the chart's appVersion, so upgrading the chart upgrades the
|
|
# image. Set it to an immutable digest for a reproducible deployment.
|
|
tag: "0.0.1"
|
|
# digest pins the image by content. Takes precedence over tag when set, which is
|
|
# the strongest guarantee that a rollout is running exactly what was reviewed.
|
|
digest: ""
|
|
pullPolicy: IfNotPresent
|
|
|
|
# --------------------------------------------------------------- deployment ---
|
|
|
|
deployment:
|
|
# Two replicas by default: the service is stateless apart from the SQLite file,
|
|
# so horizontal scaling is only safe when persistence is a shared volume or a
|
|
# network filesystem. See the persistence section.
|
|
replicaCount: 2
|
|
|
|
# extraArgs are appended to the container command. The binary takes no positional
|
|
# arguments; this exists for future flags without a chart change.
|
|
extraArgs: []
|
|
|
|
# revisionHistoryLimit keeps the last N ReplicaSets so a rollback is possible
|
|
# without the Deployment controller's default of ten consuming etcd history.
|
|
revisionHistoryLimit: 5
|
|
|
|
# minReadySeconds makes a new pod count as ready only after it has been healthy
|
|
# for this long, which stops a rolling update from proceeding on the strength of
|
|
# a single lucky probe.
|
|
minReadySeconds: 10
|
|
|
|
# progressDeadlineSeconds aborts a rollout that cannot complete, rather than
|
|
# leaving a Deployment stuck in progress indefinitely.
|
|
progressDeadlineSeconds: 600
|
|
|
|
strategy:
|
|
type: RollingUpdate
|
|
rollingUpdate:
|
|
maxSurge: 1
|
|
maxUnavailable: 0
|
|
|
|
podAnnotations: {}
|
|
podLabels: {}
|
|
|
|
# hostAliases is mostly useful for a development cluster where the identity
|
|
# provider is not in public DNS.
|
|
hostAliases: []
|
|
|
|
# terminationGracePeriodSeconds must exceed the application's shutdown timeout
|
|
# (config.shutdownTimeoutMs) or in-flight requests are cut off mid-response.
|
|
# The chart refuses to render when it does not.
|
|
terminationGracePeriodSeconds: 45
|
|
|
|
# A preStop sleep gives the Service endpoints controller time to remove this pod
|
|
# from the endpoint list before the process starts refusing connections.
|
|
# Without it, a rolling update drops requests that were already routed.
|
|
lifecycle:
|
|
preStop:
|
|
enabled: true
|
|
sleepSeconds: 3
|
|
|
|
# nodeSelector, tolerations, affinity and topologySpreadConstraints are passed
|
|
# through to the pod spec unchanged.
|
|
nodeSelector: {}
|
|
tolerations: []
|
|
affinity: {}
|
|
topologySpreadConstraints: []
|
|
|
|
# priorityClassName for a cluster where the API tier matters.
|
|
priorityClassName: ""
|
|
|
|
# ---------------------------------------------------------------- resources ---
|
|
|
|
resources:
|
|
requests:
|
|
cpu: 50m
|
|
memory: 96Mi
|
|
limits:
|
|
# No CPU limit is set deliberately. A CPU limit throttles the process when the
|
|
# node is busy, which for a latency-sensitive asset server produces exactly the
|
|
# tail latency it is meant to prevent. The memory limit is the one that matters:
|
|
# it is what keeps a runaway cache from taking the node down.
|
|
memory: 384Mi
|
|
|
|
# ------------------------------------------------------------------- config ---
|
|
|
|
config:
|
|
# environment is the deployment name. Anything other than development or test
|
|
# turns off the dev authentication bypass and the TLS-skip switch.
|
|
environment: production
|
|
|
|
logLevel: info
|
|
# json in production so the log is structured for a collector.
|
|
logFormat: json
|
|
|
|
# publicBaseUrl is the externally reachable origin, with no trailing slash.
|
|
# It is used to build the OIDC redirect URI, the absolute URLs in the runtime
|
|
# manifest and the HSTS decision, so getting it wrong means a login loop.
|
|
#
|
|
# The default points at a local hostname so that `helm install` works with no
|
|
# arguments. Override it for any real deployment.
|
|
publicBaseUrl: "http://themes.go-bananas.local"
|
|
|
|
# basePath prefixes every route, for deployments behind a path-based ingress
|
|
# such as https://example.com/themes/. Leave empty for the default of /.
|
|
basePath: ""
|
|
|
|
# rateLimitPerMinute caps requests per client per minute on the runtime API.
|
|
# The default is high because the legitimate pattern is one request per page
|
|
# view; the limit exists to stop abuse, not to ration traffic.
|
|
rateLimitPerMinute: 3000
|
|
|
|
# trustedProxies are the CIDRs whose X-Forwarded-For header may be believed.
|
|
# Empty means forwarding headers are ignored entirely and the direct peer is
|
|
# recorded, which is the safe default. Set this to the ingress controller's
|
|
# address or the audit log will record the ingress pod instead of the client.
|
|
trustedProxies: []
|
|
|
|
# corsAllowedOrigins are browser origins allowed to call the admin API
|
|
# cross-origin. The runtime API is public by design and is not affected.
|
|
corsAllowedOrigins: []
|
|
|
|
# enableMetrics exposes /metrics in Prometheus format.
|
|
enableMetrics: true
|
|
# enableProfiler exposes net/http/pprof. Off by default: a profiler on a
|
|
# network-reachable endpoint is a denial-of-service surface, so it is opt-in and
|
|
# should be paired with a NetworkPolicy.
|
|
enableProfiler: false
|
|
|
|
# shutdownTimeoutMs bounds graceful shutdown. Must be lower than
|
|
# deployment.terminationGracePeriodSeconds.
|
|
shutdownTimeoutMs: 25000
|
|
|
|
# runtimeCdnBaseUrl is the absolute base the runtime manifest hands to
|
|
# consumers. Set it when the stylesheets are served from a CDN or a separate
|
|
# asset host, so that consumers fetch from there instead of from this service.
|
|
runtimeCdnBaseUrl: ""
|
|
|
|
# database tuning. The defaults suit an embedded SQLite file; see docs on
|
|
# persistence before changing them.
|
|
database:
|
|
# maxConns bounds the connection pool. SQLite serialises writers, so a small
|
|
# pool is faster than a large one, not slower.
|
|
maxConns: 8
|
|
# busyTimeoutMs is how long a blocked writer waits before failing.
|
|
busyTimeoutMs: 5000
|
|
|
|
# sessionTTLHours is how long an administrative session lasts. The session is a
|
|
# signed cookie with no server-side record, so an expiry cannot be revoked
|
|
# early — see the identity section for the trade-off this represents.
|
|
sessionTTLHours: 8
|
|
|
|
# -------------------------------------------------------------- persistence ---
|
|
#
|
|
# The database is a single SQLite file. Two deployment shapes are supported:
|
|
#
|
|
# type: emptyDir A per-pod temporary file. Every theme change is lost when a
|
|
# pod restarts. Correct only for a demo or for evaluating the
|
|
# service; the built-in themes are re-seeded automatically so
|
|
# the instance still comes up, but operator work is not kept.
|
|
#
|
|
# type: persistentVolumeClaim A ReadWriteOnce volume. Correct for a
|
|
# single-replica deployment, which is the shape this chart
|
|
# recommends in production.
|
|
#
|
|
# Note on replicas: RWO volumes cannot be attached to two pods at once. With
|
|
# replicaCount > 1 and a PVC, only one pod mounts the volume successfully and the
|
|
# others crash-loop. Running more than one replica therefore requires either
|
|
# replicaCount: 1, or a filesystem that permits multiple mounts.
|
|
|
|
persistence:
|
|
enabled: true
|
|
type: persistentVolumeClaim
|
|
accessMode: ReadWriteOnce
|
|
size: 2Gi
|
|
# storageClassName: "" uses the cluster default.
|
|
storageClassName: ""
|
|
# existingClaim mounts a volume the operator manages. Its lifecycle is then the
|
|
# operator's responsibility: this chart will not delete or resize it.
|
|
existingClaim: ""
|
|
mountPath: /srv/data
|
|
|
|
# A snapshot taken before an upgrade, when the upgrade involves a destructive
|
|
# change to the schema. Restoring is a manual kubectl apply.
|
|
snapshot:
|
|
enabled: false
|
|
# CronJob schedule in the cluster's timezone.
|
|
schedule: "0 3 * * *"
|
|
# How long to keep snapshots.
|
|
retention: 14
|
|
|
|
# ------------------------------------------------------------------ service ---
|
|
|
|
service:
|
|
type: ClusterIP
|
|
port: 80
|
|
# nodePort, only used when type is NodePort.
|
|
nodePort: ""
|
|
# ClusterIP: set to None for a headless service, which a StatefulSet needs.
|
|
clusterIP: ""
|
|
# The session cookie's Secure attribute and SameSite=None both require the
|
|
# browser to see the service over HTTPS. Set to true when TLS terminates at the
|
|
# ingress.
|
|
sessionSecure: true
|
|
sessionSameSite: Lax
|
|
annotations: {}
|
|
labels: {}
|
|
|
|
# ----------------------------------------------------------------- ingress ---
|
|
|
|
ingress:
|
|
enabled: false
|
|
className: nginx
|
|
annotations: {}
|
|
hosts:
|
|
- host: themes.example.com
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
# tls is empty for a plain-HTTP installation. For the usual production shape,
|
|
# point it at a cert-manager cluster issuer so the certificate is renewed
|
|
# without anyone remembering to.
|
|
tls: []
|
|
# - secretName: go-bananas-tls
|
|
# hosts:
|
|
# - themes.example.com
|
|
|
|
# ---------------------------------------------------------------- identity ---
|
|
#
|
|
# This is the part that most often goes wrong in a deployment, so it is worth being
|
|
# explicit about the three modes.
|
|
|
|
identity:
|
|
# disabled No authentication. Every request is granted administrator access.
|
|
# Refused by the application outside a development environment, so
|
|
# this cannot be deployed to production by accident.
|
|
# dev Every request is authenticated as a local administrator.
|
|
# Also refused outside development.
|
|
# oidc OpenID Connect against a real provider. The production choice.
|
|
mode: oidc
|
|
|
|
# sessionSecretKey is the key inside the Secret that holds the session signing
|
|
# secret. The secret must be at least 32 bytes.
|
|
#
|
|
# kubectl create secret generic go-bananas-auth \
|
|
# --from-literal=session-secret="$(openssl rand -base64 48)" \
|
|
# --from-literal=oidc-client-secret="..."
|
|
#
|
|
# The secret is never templated into a ConfigMap or written to a log. Rotating
|
|
# it invalidates every open session at once.
|
|
sessionSecretKey: session-secret
|
|
|
|
oidc:
|
|
# issuer is the OIDC issuer URL. Everything else — the authorization,
|
|
# token, userinfo and JWKS endpoints — is discovered from
|
|
# /.well-known/openid-configuration, so this is the only provider-specific
|
|
# value needed.
|
|
#
|
|
# The default is the shared development realm. The realm path is part of the
|
|
# issuer: this string must match the `iss` claim in the ID token exactly,
|
|
# including a trailing slash if the provider emits one. A mismatch here is the
|
|
# single most common cause of "invalid issuer" at the callback.
|
|
issuer: "https://auth-dev.urpi.be/realms/urpi"
|
|
|
|
# clientId is the client identifier registered with the provider.
|
|
clientId: "go-bananas"
|
|
|
|
# clientSecretKey names the key inside existingSecret (or generatedSecret)
|
|
# holding the client secret. Referencing it by key name rather than by value
|
|
# is what keeps the secret out of values.yaml.
|
|
clientSecretKey: oidc-client-secret
|
|
|
|
# existingSecret is a Secret you manage. Preferred for production: the chart
|
|
# will not create, rotate or delete it, and its contents never appear in a
|
|
# rendered manifest.
|
|
#
|
|
# kubectl create secret generic go-bananas-auth \
|
|
# --from-literal=session-secret="$(openssl rand -base64 48)" \
|
|
# --from-literal=oidc-client-secret="…"
|
|
existingSecret: ""
|
|
# existingSecretKeys overrides the key names inside existingSecret, for a
|
|
# Secret managed by an external secrets operator with its own naming.
|
|
existingSecretKeys: {}
|
|
|
|
# generatedSecret creates a Secret owned by this release. The session secret is
|
|
# preserved across upgrades by reading the live Secret back, so an upgrade does
|
|
# not sign every user out.
|
|
#
|
|
# The OIDC client secret cannot be generated — it has to come from the provider.
|
|
# A generated Secret therefore contains an empty client secret, which means the
|
|
# deployment will fail to authenticate until one is supplied. For anything real,
|
|
# use existingSecret.
|
|
generateSecret: true
|
|
|
|
# scopes requested in addition to openid. The email scope is what makes
|
|
# `email` appear in the session; groups is what the role mapping reads.
|
|
scopes:
|
|
- profile
|
|
- email
|
|
- groups
|
|
|
|
# Group-to-role mapping, read from the `groups` claim.
|
|
#
|
|
# The most privileged matching group wins; a user in no configured group gets
|
|
# viewer. The default is deliberately least privilege, so a mapping mistake
|
|
# fails closed rather than granting access nobody intended.
|
|
adminGroups: []
|
|
editorGroups: []
|
|
viewerGroups: []
|
|
# With all three empty, every authenticated user is a viewer. Populate these
|
|
# from the provider's actual group names before rolling this out to real users;
|
|
# the group names are realm-specific and are not guessed here.
|
|
|
|
# redirectURL overrides the computed callback. Leave empty unless the
|
|
# provider has a different redirect URI registered, which happens behind a
|
|
# path-based ingress or when several environments share a provider client.
|
|
redirectURL: ""
|
|
|
|
postLogoutRedirectURL: ""
|
|
# End-session endpoint, for providers that do not follow the RP-initiated
|
|
# logout convention.
|
|
logoutURL: ""
|
|
|
|
# skipTLSVerify disables certificate verification against the provider. It
|
|
# exists so that a development provider presenting a self-signed certificate
|
|
# can be used, and the application refuses to start with it enabled outside
|
|
# development.
|
|
skipTLSVerify: false
|
|
|
|
# timeout and insecureSkipVerify exist for the same development reason.
|
|
timeoutSeconds: 15
|
|
|
|
# ------------------------------------------------------------------- probes ---
|
|
|
|
probes:
|
|
liveness:
|
|
enabled: true
|
|
path: /healthz
|
|
initialDelaySeconds: 3
|
|
periodSeconds: 15
|
|
timeoutSeconds: 3
|
|
failureThreshold: 3
|
|
readiness:
|
|
enabled: true
|
|
path: /readyz
|
|
initialDelaySeconds: 2
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
startup:
|
|
enabled: true
|
|
path: /healthz
|
|
periodSeconds: 3
|
|
failureThreshold: 30
|
|
|
|
# --------------------------------------------------------------- autoscaling ---
|
|
|
|
autoscaling:
|
|
enabled: false
|
|
minReplicas: 2
|
|
maxReplicas: 10
|
|
targetCPUUtilizationPercentage: 70
|
|
# targetMemoryUtilizationPercentage is left unset by default: memory here is
|
|
# dominated by the render cache, which grows with the number of themes rather
|
|
# than with load, so scaling on it would respond to a content change rather than
|
|
# to traffic.
|
|
targetMemoryUtilizationPercentage: 0
|
|
behavior: {}
|
|
|
|
# ------------------------------------------------------- disruption budgets ---
|
|
#
|
|
# A PDB only helps if it does not also block a node drain. minAvailable: 1 with two
|
|
# replicas permits exactly one disruption, which is the useful setting.
|
|
|
|
podDisruptionBudget:
|
|
enabled: true
|
|
minAvailable: 1
|
|
# maxUnavailable: 1
|
|
# unhealthyPodEvictionPolicy: AlwaysAllow
|
|
|
|
# --------------------------------------------------------- service account ---
|
|
|
|
serviceAccount:
|
|
create: true
|
|
name: ""
|
|
annotations: {}
|
|
automountServiceAccountToken: false
|
|
|
|
rbac:
|
|
# create is off by default: the service talks to nothing in the cluster, so the
|
|
# default ServiceAccount needs no rules at all.
|
|
create: false
|
|
rules: []
|
|
|
|
# ------------------------------------------------------------ network policy ---
|
|
#
|
|
# A default-deny ingress with an explicit allowance for the ingress controller and
|
|
# for Prometheus. Without this, any pod in the cluster can reach the admin API.
|
|
|
|
networkPolicy:
|
|
enabled: false
|
|
# ingressNamespaces restricts which namespaces may reach the service. Empty means
|
|
# the whole cluster.
|
|
allowedNamespaces: []
|
|
# metricsPaths is the additional path allowed from the metrics sources.
|
|
metricsPaths: ["/metrics"]
|
|
|
|
# ------------------------------------------------------------------- extras ---
|
|
|
|
podSecurityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 65532
|
|
runAsGroup: 65532
|
|
fsGroup: 65532
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: true
|
|
capabilities:
|
|
drop: ["ALL"]
|
|
|
|
# extraEnv is for one-off variables that do not warrant a chart value. Anything
|
|
# added here is the operator's responsibility to keep consistent across replicas.
|
|
extraEnv: []
|
|
|
|
# extraVolumes and extraVolumeMounts are for a sidecar or a config file the chart
|
|
# does not model.
|
|
extraVolumes: []
|
|
extraVolumeMounts: []
|
|
|
|
# metricsServiceMonitor creates a Prometheus Operator ServiceMonitor. Requires the
|
|
# Prometheus Operator CRDs to be installed.
|
|
metrics:
|
|
serviceMonitor:
|
|
enabled: false
|
|
interval: 30s
|
|
scrapeTimeout: 10s
|
|
labels: {}
|
|
honorLabels: true
|
|
|
|
# ------------------------------------------------------------------- extras ---
|
|
#
|
|
# `extraManifests` is an escape hatch for a resource this chart does not model. It
|
|
# is templated, so a value can reference another template's output.
|
|
extraManifests: []
|
|
# - apiVersion: v1
|
|
# kind: ConfigMap
|
|
# metadata:
|
|
# name: {{ include "go-bananas.fullname" . }}-extra
|
|
# data:
|
|
# example: "value"
|