Task Manager is a small self-hosted task tracker with a command-line client, a FastAPI service, and SQLite storage. It supports task status, ownership, due dates, work notes, and text or date-based searches.
- Create, inspect, update, search, and delete tasks from the CLI.
- Track
todo,in_progress, andcompletedtasks. - Store task descriptions, owners, due dates, and timestamped work notes.
- Edit long descriptions with
$EDITOR. - Run the API as a systemd service or a Docker container.
- Persist data in a configurable SQLite database.
- Python 3.10 or newer for Python installation and development.
uvfor the reproducible development workflow.- Fedora tooling when building the RPM locally.
Install both console commands from a checkout:
uv tool install .This provides:
task: the command-line client.task_server: the FastAPI server.
The client connects to http://localhost:8000 by default. To use another
server, create ~/.taskrc:
[default]
api_url = https://tasks.example.comStart the server before using the client:
TASK_DB_PATH=./task_manager.db task_serverCommon commands:
task ping
task add --title "Review pull request" --description "Review API changes"
task list
task show --id 1
task update --id 1 --status in_progress
task note --id 1 --note "Finished the API review"
task search --text "pull request"
task delete --id 1Run task --help or task <command> --help for the complete options.
The image is published to both Docker Hub and GitHub Container Registry:
edimatt/task-managerghcr.io/edimatt/task-manager
Run it with a named volume for the SQLite database:
docker run --detach \
--name task-manager \
--publish 127.0.0.1:8000:8000 \
--volume task-manager-data:/var/lib/task_manager \
edimatt/task-manager:latestVerify the service:
curl http://localhost:8000/pingBuild an image locally:
make docker FEDORA_VERSION=41The docker target has rpm as a prerequisite. It automatically runs the
tests, builds the source distribution, creates the RPM, and only then builds
the container image with that RPM:
test + sdist -> rpm -> docker image
Run this target on Fedora with the RPM development tools and Docker installed.
The RPM is built for the host Fedora release, so pass the same release through
FEDORA_VERSION when it differs from the Fedora 44 default. The Docker build
uses that value for both the base image tag and the RPM .fc<release> suffix,
preventing an RPM for another Fedora release from being installed accidentally.
Override the local image tag when needed:
make docker FEDORA_VERSION=41 DOCKER_IMAGE=task-manager:devThe API has no authentication or TLS termination. Do not expose it directly to an untrusted network; place it behind an appropriately configured reverse proxy or firewall.
The container runs with the fixed UID and GID 10001. For Kubernetes
PersistentVolumes, use a pod-level security context such as:
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001Build the Fedora RPM:
make rpmpyproject.toml is the single source of truth for the application version.
Display the current version with either command:
uv version --short
make versionSet a specific version or increment the patch version with:
uv version 0.1.1
uv version --bump patchThe Makefile and RPM build automatically consume this value. In RPM packaging,
Version is the upstream application version, while Release identifies the
packaging revision and is maintained separately.
Install it:
sudo dnf install dist/task_manager-*.rpm
sudo systemctl enable --now task_server.serviceThe service runs as taskd and stores its database at:
/var/lib/task_manager/task_manager.db
The RPM creates taskd only when the account does not already exist. It does
not remove the account during package erasure, preserving ownership of existing
task data and avoiding deletion of an externally managed service account.
Create the locked development environment:
uv sync --locked --extra devRun lint and tests:
uv run --no-sync ruff check src test
uv run --no-sync pytestRun a development server:
TASK_DB_PATH=./dev.db uv run task_serverBuild the source distribution:
uv build --sdistPull requests run lint and tests. Pushes to main additionally build the
source distribution and RPM, then install that RPM into a Docker image and
publish:
edimatt/task-manager:latestedimatt/task-manager:<commit-sha>ghcr.io/edimatt/task-manager:latestghcr.io/edimatt/task-manager:<commit-sha>
Docker Hub publishing requires the DOCKERHUB_TOKEN GitHub Actions secret.
GHCR publishing uses the repository-scoped GITHUB_TOKEN.
While the service is running, interactive OpenAPI documentation is available at:
http://localhost:8000/docs
Task Manager is licensed under the MIT License.