Helm base chart
The base chart deploys the application itself: Deployment, Service, ServiceAccount, HorizontalPodAutoscaler, and a Gateway API HTTPRoute. It does not provision databases, secrets, or observability — see the platform chart for those.
Values reference: helm/base/values.yaml
Install
helm install ghostfolio ./helm/base \
--set gateway.hostnames[0]=ghostfolio.yourdomain.com
Configuration
Environment variables
Set env to inject environment variables into the container:
env:
- name: LOG_LEVEL
value: "info"
# - name: DATABASE_URL # usually injected via envFrom from a Secret
# value: "..."
Injecting secrets
Don't put credentials in env. Use envFrom to pull from a Secret — typically one generated by the platform chart's ExternalSecrets integration:
envFrom:
- secretRef:
name: ghostfolio
See the platform chart docs for how the Secret gets populated.
Ingress
The base chart emits a Gateway API HTTPRoute. A parent Gateway (with listeners and TLS) is expected to be provided by the platform — typically a gateway chart such as hiroba-gateway — so the app chart only owns the route itself.
Minimum configuration
gateway:
parentRefs:
- name: default-gateway
namespace: gateway-system
sectionName: https # pin to the HTTPS listener
hostnames:
- ghostfolio.yourdomain.com
Pin sectionName to an HTTPS listener to avoid silently serving plaintext. HTTP→HTTPS redirect is a listener-level concern and lives on the parent Gateway, not in this chart.
Custom routing rules
The default catch-all sends all traffic to the service. To split paths (e.g. /api to a different backend) set gateway.rules:
gateway:
rules:
- matches:
- path:
type: PathPrefix
value: /api
filters:
- type: RequestHeaderModifier
requestHeaderModifier:
add:
- name: X-Forwarded-Prefix
value: /api
Scaling
Horizontal autoscaling is off by default:
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 80
PodDisruptionBudget
Once you're running more than one replica, enable a PDB so node drains / cluster upgrades can't take the app fully offline:
podDisruptionBudget:
enabled: true
minAvailable: 1
# maxUnavailable: "25%" # mutually exclusive — set minAvailable: null to use this
The selector reuses app.selectorLabels, so it matches the Deployment's pods automatically — no cross-release label coupling needed.
Probes
Liveness and readiness probes target /healthz and /readyz on the container port. Override the defaults in livenessProbe / readinessProbe if your application exposes different paths.
Security context
The pod runs as UID 1000 with readOnlyRootFilesystem: true and all Linux capabilities dropped. If your application needs to write to the filesystem, add an emptyDir volume under extraVolumes / extraVolumeMounts rather than loosening the security context.