Operations
One image. One database. Yours.
Self-hosting is the default here, not a stripped-down edition of something else. The same image runs a single box and a multi-workspace platform, with the full feature set on both.
# The whole thing, on one machine
git clone https://github.com/Jersyfi/hubtask.git && cd hubtask
cp deploy/docker/.env.example .env # set the secrets
docker compose -f deploy/docker/compose.yaml up -d
# API: http://localhost:8080/api/v1
# Meta: http://localhost:8080/api/v1/meta/capabilitiesWhat it needs
PostgreSQL, and that is the list
There is no Redis to run, no message broker to keep alive, no search cluster to size. PostgreSQL is the store, the job queue, the event outbox, the full-text index and the tenant boundary — one dependency to back up, patch and understand.
Object storage is optional: attachments go to an S3-compatible bucket if you have one, and to a volume if you do not. The vector extension is optional too — with it, search gains a semantic pass; without it, search is lexical and the installation says so through the capability endpoint rather than failing.
deployment.mdSupported, and proven by a job
| Runtime | Status |
|---|---|
| Docker Compose, amd64 and arm64 | supported |
| Podman Compose | supported |
| Kubernetes 1.28+, amd64 | supported |
| Kubernetes, arm64 | best effort |
| PostgreSQL 16 and 17 | supported |
| PostgreSQL 15 and older | unsupported |
| A loose binary, no container | unsupported |
“Supported” here means a job in the pipeline runs the software on it and a defect there blocks a release. “Best effort” means it is expected to work and nobody has automated the proof — which is a different promise, and it is written down as one.
support-matrix.mdBackups
Your target, your schedule, and a restore that has been rehearsed
Archives are encrypted and go where you tell them: a local volume, an S3-compatible bucket — AWS, MinIO, Ceph, Wasabi, Backblaze, Hetzner and the rest, the endpoint is yours to name — SFTP, or WebDAV including Nextcloud. Schedules are RRULEs, retention is generational, and the archive at the target can be listed without downloading it.
Restore is a first-class operation, down to a single item, including a journal of what a destructive restore removed. And the drill runs in the pipeline on every change, because the only backup worth having is one somebody has put back.
backup-restore.mdTwo details that matter at three in the morning
- No trust on first use over SFTP A target names the host’s public key or its fingerprint, or it is refused. There is no way to switch that off — a first connection that accepted whatever answered only has to be intercepted once.
- A local target cannot leave its volume The path is relative to the backup volume. Whoever configures a target is administering the instance, not the machine it sits on.
- An unbuilt target type is refused by name “Hubtask cannot talk to SMB yet” rather than a generic error — a further adapter ships when it passes the same conformance suite.
Running it
It tells you what is wrong before you have to guess
Four health levels
Liveness, startup and readiness for the orchestrator, and a meta endpoint for a person — which names what is degraded and what is missing instead of the process falling over.
Degrade, do not crash
A missing optional dependency switches a feature off and says so. Timeouts, circuit breakers, bulkheads and load shedding are in the baseline rather than added after the first outage.
Metrics, traces, logs
OpenTelemetry throughout, traces that survive the outbox and the job queue, structured logs with your content redacted, and a dashboard in the repository.
Objectives and alerts
Eight service level objectives — availability, read and write latency, event delivery, reminder punctuality, webhook delivery, automation, and confirmed writes lost, which is zero — with an alert catalogue and a runbook per alert.
Process roles
One image, several roles: API, worker, scheduler and automation. Run them together on one box or separately in a cluster with autoscaling and a disruption budget.
Upgrades that roll
Forward-only migrations designed to expand before they contract, so a new version and the previous one can run at the same time while the rollout finishes.
A fleet
The same image, at platform scale
The Helm chart separates the roles, scales the API horizontally, and ships a disruption budget and a network policy. Multi-workspace mode adds provisioning, suspension, deletion and export per workspace, quotas that keep one workspace from becoming everybody’s latency, and point-in-time recovery with a verified restore.
Running it for your own organisation, for your own clients, or as a service for other people is free: Hubtask is Apache-2.0. Only the name stays ours — an offering built on it calls itself something else. The terms
helm upgrade --install hubtask ./k8s \
-f ./k8s/values.yaml
# Roles as separate deployments
# api · worker · scheduler · automation