Skip to main content

Vikunja

A self-hosted to-do and project management application.

Vikunja is an open-source, self-hosted task manager with list/Kanban/Gantt views, team collaboration, due dates, labels, and recurring tasks. It has a clean web UI and mobile apps. Self-hosting means no subscription fees and full ownership of your task data.

Alternatives considered

Cloud Hosted

ToolOpen SourceFree TierMonthly Cost
TodoistNoLimitedFrom $5/user/mo
TrelloNoLimitedFrom $5/user/mo
AsanaNoLimitedFrom $10.99/user/mo

Self Hosted

ToolOpen SourceFull FeaturesNotes
PlaneYesYesJira-like; project and issue tracking

Installation

Architecture

  • Deployment: Single vikunja deployment in the vikunja namespace
  • Image: vikunja/vikunja:2.3.0 (digest-pinned)
  • Database: CNPG PostgreSQL cluster (Longhorn-encrypted PVCs, HA with two replicas)
  • Storage: Longhorn PVC (vikunja-files) for file attachments
  • Networking: ClusterIP service on port 3456, HTTPRoute via internal gateway

Security

  • Runs as runAsUser: 0, runAsNonRoot: false
  • Longhorn PVCs encrypted at rest via SOPS-managed keys

Updates

Managed by Renovate. Image is digest-pinned.

Data Management

  • Database: CNPG PostgreSQL cluster (Longhorn-encrypted PVCs, HA)
  • PVC: vikunja-files (Longhorn-encrypted, k8up.io/backup: "true") for file attachments
  • Backups: k8up Schedule backs up CNPG Longhorn PVCs to Hetzner S3.

User Management

OIDC configured via VIKUNJA_AUTH_OPENID_* env vars from the vikunja-openid SOPS-encrypted secret. Provider is PocketID (VIKUNJA_AUTH_OPENID_PROVIDERS_POCKETID_*).

Configuration Management

  • OIDC credentials (client ID, secret, auth URL) from SOPS-encrypted secret (vikunja-openid)
  • SMTP credentials from shared SOPS-encrypted secret (allinkl-smtp-credentials)
  • Week start and other app settings from env vars
  • Database credentials injected from CNPG-generated secret

Administration

Usage

Create projects, add tasks, and organize work using list, Kanban, or Gantt views. Assign due dates, labels, and team members to tasks. Share projects with other users for collaborative task management. OIDC SSO allows login with existing identity provider credentials.

Cluster-specific deviations from the above live in the per-cluster README — see k8s/apps/talos/vikunja/README.md.

Cluster Deployment

Vikunja — Talos cluster

Cluster-specific notes only. General product info, "why we use it", and alternatives live in docusaurus/docs/apps/vikunja.mdx.

Deviations from defaults

Defaults live in docusaurus/docs/apps/vikunja.mdx — document anything this cluster does differently here, with a one-line reason.

Kubernetes Metadata
  • Image: vikunja/vikunja:2.3.0@sha256:f6b80393c1998cd5cd0dc38d24762c59ab4c10000a6f1032ef5b554e262cab93
Rendered manifests (kustomize build)
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kustomize.toolkit.fluxcd.io/force: enabled
labels:
app.kubernetes.io/instance: vikunja
app.kubernetes.io/name: vikunja
name: vikunja
namespace: vikunja
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/instance: vikunja
app.kubernetes.io/name: vikunja
ingress: public
strategy:
rollingUpdate: null
type: Recreate
template:
metadata:
labels:
app.kubernetes.io/instance: vikunja
app.kubernetes.io/name: vikunja
ingress: public
spec:
containers:
- env:
- name: VIKUNJA_DEFAULTSETTINGS_WEEK_START
value: '1'
- name: VIKUNJA_MAILER_ENABLED
value: 'true'
- name: VIKUNJA_MAILER_HOST
valueFrom:
secretKeyRef:
key: host
name: allinkl-smtp-credentials
- name: VIKUNJA_MAILER_PORT
valueFrom:
secretKeyRef:
key: port
name: allinkl-smtp-credentials
- name: VIKUNJA_MAILER_USERNAME
valueFrom:
secretKeyRef:
key: username
name: allinkl-smtp-credentials
- name: VIKUNJA_MAILER_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: allinkl-smtp-credentials
- name: VIKUNJA_MAILER_FROMEMAIL
value: noreply@kueber.eu
- name: VIKUNJA_DATABASE_TYPE
value: postgres
- name: VIKUNJA_DATABASE_HOST
valueFrom:
secretKeyRef:
key: host
name: cnpg-app
- name: VIKUNJA_DATABASE_DATABASE
valueFrom:
secretKeyRef:
key: dbname
name: cnpg-app
- name: VIKUNJA_DATABASE_USER
valueFrom:
secretKeyRef:
key: user
name: cnpg-app
- name: VIKUNJA_DATABASE_PASSWORD
valueFrom:
secretKeyRef:
key: password
name: cnpg-app
envFrom:
- secretRef:
name: vikunja-openid
image: vikunja/vikunja:2.3.0@sha256:f6b80393c1998cd5cd0dc38d24762c59ab4c10000a6f1032ef5b554e262cab93
livenessProbe:
failureThreshold: 5
httpGet:
path: /
port: 3456
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 2
name: vikunja
ports:
- containerPort: 3456
name: web
protocol: TCP
readinessProbe:
failureThreshold: 5
httpGet:
path: /
port: 3456
periodSeconds: 30
successThreshold: 1
timeoutSeconds: 2
volumeMounts:
- mountPath: /etc/vikunja/config.yml
name: vikunja-config
subPath: config.yaml
- mountPath: /app/vikunja/files
name: vikunja-files
securityContext:
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
volumes:
- name: vikunja-config
secret:
secretName: vikunja-config
- name: vikunja-files
persistentVolumeClaim:
claimName: vikunja-files