Self-hosted task and project management at tasks.haiven.site. Vikunja 2.3.0 provides kanban boards, task lists, CalDAV sync, due-date reminders, and a full REST API — all from a single Go binary backed by dedicated PostgreSQL 17 and the shared Haiven Redis cache.
| Type | URL |
|---|---|
| Web UI | https://tasks.haiven.site |
| API health | https://tasks.haiven.site/api/v1/info |
| API (OpenAPI UI) | https://tasks.haiven.site/api/v1/docs |
| CalDAV | https://tasks.haiven.site/dav/ |
# Start
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml up -d
# Status
docker inspect vikunja --format='{{.State.Health.Status}}'
docker inspect vikunja-db --format='{{.State.Health.Status}}'
# Smoke test
curl -sf https://tasks.haiven.site/api/v1/info | python3 -m json.tool
# Logs
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml logs -f vikunja
/api/v1/docssso.haiven.site)./files/ (20 MB default limit)flowchart TD
Browser([Browser / Mobile]) -->|HTTPS 443| Traefik
CalDAV([DAVx5 / Tasks.org]) -->|HTTPS /dav/| Traefik
API([API clients]) -->|HTTPS /api/v1/| Traefik
subgraph web["web network"]
Traefik[Traefik\ntasks.haiven.site\nwildcard cert]
end
Traefik -->|HTTP 3456| Vikunja
subgraph container["vikunja container"]
V[Go backend + Vue frontend\nPort 3456]
FV["./files\nUpload volume"]
CV["config.yml\nread-only"]
V --- FV
V --- CV
end
subgraph backend["backend network"]
DB[(vikunja-db\nPostgreSQL 17\n5432)]
RD[(redis\nDB index 2\n6379)]
SMTP[smtp-relay\n1025]
AUTH[Authentik\nsso.haiven.site]
end
V -->|SQL| DB
V -->|cache| RD
V -->|SMTP| SMTP
V -->|OIDC discovery| AUTH
Design notes:
vikunja/vikunja serves both Go backend and Vue frontend on port 3456 (the old vikunja/api + vikunja/frontend split was retired in v2.0.0).vikunja-db is on backend only (no host port). Redis is the shared redis container at DB index 2.| File | Purpose |
|---|---|
/mnt/apps/docker/vikunja/.env |
All secrets and runtime settings (chmod 600) |
/mnt/apps/docker/vikunja/config.yml |
Minimal config; env vars take precedence |
Key env vars:
| Variable | Value |
|---|---|
VIKUNJA_SERVICE_PUBLICURL |
https://tasks.haiven.site/ |
VIKUNJA_DATABASE_TYPE |
postgres |
VIKUNJA_DATABASE_HOST |
vikunja-db |
VIKUNJA_CACHE_TYPE |
redis |
VIKUNJA_CACHE_REDIS_DB |
2 |
VIKUNJA_MAILER_HOST |
smtp-relay |
VIKUNJA_AUTH_OPENID_ENABLED |
true |
See .env.example for the full template with all options documented.
docker exec vikunja-db pg_dump -U vikunja vikunja \
| gzip > /mnt/storage/backups/vikunja/vikunja-$(date +%Y%m%d_%H%M%S).sql.gz
rsync -avz /mnt/apps/docker/vikunja/files/ /mnt/storage/backups/vikunja/files/
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml stop vikunja
docker exec -it vikunja-db psql -U vikunja -d postgres \
-c "DROP DATABASE vikunja WITH (FORCE);"
docker exec -it vikunja-db psql -U vikunja -d postgres \
-c "CREATE DATABASE vikunja OWNER vikunja;"
gunzip -c /mnt/storage/backups/vikunja/<timestamp>.sql.gz \
| docker exec -i vikunja-db psql -U vikunja -d vikunja
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml start vikunja
Warning: Project deletion in Vikunja is permanent — no trash bin. Maintain daily backups.
Vikunja 2.3.0 does not expose a Prometheus /metrics endpoint. No built-in exporter exists at this version.
Current monitoring:
https://tasks.haiven.site/api/v1/info (expected: HTTP 200, "version": "v2.3.0")docker inspect vikunja --format='{{.State.Health.Status}}'TODO: Add a custom Blackbox Exporter probe or track the upstream Prometheus metrics issue for a future Vikunja release.
# Update image tag in docker-compose.yml, then:
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml pull
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml up -d
docker compose -f /mnt/apps/docker/vikunja/docker-compose.yml logs -f vikunja
# Watch for xormigrate migration lines — clean output = success
| Symptom | Check |
|---|---|
| 502 Bad Gateway | Verify port label (3456) and both networks attached |
| OIDC login loop | VIKUNJA_SERVICE_PUBLICURL must have trailing slash; redirect URI must match exactly |
| JWT secret error | VIKUNJA_SERVICE_JWTSECRET must be >= 32 chars |
| DB connection refused | Both containers on backend network; vikunja-db healthy |
| File uploads fail | chown -R 1000:1000 /mnt/apps/docker/vikunja/files/ |
| CalDAV not working | Use a CalDAV token (not OIDC credentials) from Account Settings |
| Mobile OIDC errors | Use API token (tk_ prefix) for mobile app auth |
For detailed troubleshooting, see the full plan at /mnt/apps/docker/_server-setup/08/08l-vikunja-v2.md Section 15.
| Path | Purpose |
|---|---|
/mnt/apps/docker/vikunja/ |
Service root |
/mnt/apps/docker/vikunja/files/ |
User file attachments (must be chown 1000:1000) |
/mnt/apps/docker/vikunja/openapi.json |
Static copy of OpenAPI spec (fetched from live instance) |
/mnt/storage/backups/vikunja/ |
Backup destination |
/mnt/apps/docker/_server-setup/08/08l-vikunja-v2.md/mnt/apps/docker/vikunja/USER_GUIDE.md/mnt/apps/docker/vikunja/CLAUDE.md/mnt/apps/docker/vikunja/openapi.json