Skip to main content

Helm base chart

The base chart deploys Vikunja itself: Deployment, Service, ServiceAccount, optional PersistentVolumeClaim, optional HorizontalPodAutoscaler, optional PodDisruptionBudget, and a Gateway API HTTPRoute. It does not provision databases, secrets, or observability — see the platform chart for those.

The container image is consumed unchanged from docker.io/vikunja/vikunja. No custom build is maintained.

Values reference: helm/base/values.yaml

Install

helm install vikunja ./helm/base \
--set gateway.hostnames[0]=vikunja.yourdomain.com \
--set 'env[0].name=VIKUNJA_SERVICE_PUBLICURL' \
--set 'env[0].value=https://vikunja.yourdomain.com'

In practice you'll keep overrides in a values file and reference it with -f values-prod.yaml.

Configuration

Vikunja is configured entirely through environment variables — see the upstream config reference. The naming convention is VIKUNJA_<SECTION>_<KEY>.

Default env

The chart ships a Postgres-backed default that lines up with the vikunja-platform chart:

env:
- name: VIKUNJA_SERVICE_PUBLICURL
value: "https://vikunja.example.com" # override per environment
- name: VIKUNJA_SERVICE_ENABLEMETRICS
value: "true"
- name: VIKUNJA_DATABASE_TYPE
value: postgres
- name: VIKUNJA_DATABASE_HOST
value: vikunja-pg-rw # CNPG service from the platform chart
- name: VIKUNJA_DATABASE_USER
value: vikunja
- name: VIKUNJA_DATABASE_DATABASE
value: vikunja
- name: VIKUNJA_DATABASE_SSLMODE
value: require
- name: VIKUNJA_FILES_BASEPATH
value: /app/vikunja/files

Injecting secrets

Don't put credentials in env. Use envFrom to pull from a Secret — typically the one populated by the platform chart's ExternalSecret:

envFrom:
- secretRef:
name: vikunja

The platform chart's defaults populate that Secret with VIKUNJA_DATABASE_PASSWORD and VIKUNJA_SERVICE_JWTSECRET. See the platform chart docs for the data mapping.

Persistence

Vikunja stores uploaded files at /app/vikunja/files (configured via VIKUNJA_FILES_BASEPATH). The chart always mounts a writable volume there — either a PVC or an emptyDir:

persistence:
files:
enabled: true # creates a PVC named <release>-vikunja-files
size: 5Gi
accessMode: ReadWriteOnce
storageClass: "" # omit for the cluster default
# existingClaim: my-pvc # to reuse an existing PVC instead

When enabled: false (default), files live in an emptyDir and are lost on pod restart — fine for a quick demo, never for production.

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 this chart only owns the route itself.

Minimum configuration

gateway:
parentRefs:
- name: default-gateway
namespace: gateway-system
sectionName: https # pin to the HTTPS listener
hostnames:
- vikunja.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. Whatever hostname you set here must also match VIKUNJA_SERVICE_PUBLICURL in env.

Custom routing rules

The default catch-all sends all traffic to the service. Override gateway.rules to split paths or apply filters.

Scaling

Horizontal autoscaling is off by default and should stay off unless /app/vikunja/files is on RWX storage (or files are migrated out — Vikunja doesn't currently support an S3 backend).

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 Vikunja fully offline:

podDisruptionBudget:
enabled: true
minAvailable: 1
# maxUnavailable: "25%" # mutually exclusive — set minAvailable: null to use this

Probes

Liveness and readiness probes target /api/v1/info on the container's http port (3456). Override the defaults in livenessProbe / readinessProbe if you've fronted Vikunja with a path prefix.

Security context

The pod runs as UID 1000 with readOnlyRootFilesystem: true and all Linux capabilities dropped. The chart always mounts an emptyDir at /tmp plus the files volume at /app/vikunja/files. If Vikunja needs to write anywhere else, add an extraVolumes / extraVolumeMounts pair rather than loosening the security context.