Self-hosting
TaskForce runs on one machine with Docker: the app, its API, sign-in (Keycloak), the database (PostgreSQL), file storage (MinIO) and a small AI gateway. Your data stays on that machine. AI comes from Ollama on the same machine by default, or from any OpenAI-compatible API you choose.
Requirements
- Docker with Compose v2: Docker Desktop on Windows and macOS, Docker Engine and its compose plugin on Linux.
- About 6 GB of free memory for TaskForce and 10 GB of disk, more for your data.
- Optional, for AI: Ollama with
qwen3:8b(chat) andbge-m3(search), about 6 GB of models. A GPU makes answers much faster.
Install
selfhost-init writes .env from .env.selfhost.example with new secrets. It never overwrites an existing .env:
the secrets in it protect your database and your encrypted data, so back it up with them.
The first start builds the images from the repository and takes 10 to 20 minutes, depending on the machine and the
connection. Then open http://localhost:3000 and create your account: the first person to sign up gets a workspace
and can invite the others.
docker compose ps shows each service; docker compose logs -f backend follows the API if something looks wrong.
AI
Without AI, everything else works: Cortex and issue drafting say that AI is not configured, and search falls back to plain text.
- Ollama on this machine (default): install Ollama, then
ollama pull qwen3:8bandollama pull bge-m3. On Linux, make Ollama listen beyond localhost so the containers can reach it (OLLAMA_HOST=0.0.0.0in its service settings). - Ollama in a container:
docker compose --profile ollama up -d, setOLLAMA_BASE_URL=http://ollama:11434in.env, thendocker compose exec ollama ollama pull qwen3:8band the same forbge-m3. - An OpenAI-compatible API (OpenAI, Groq, Mistral, a vLLM server…): set
AI_BASE_URL,AI_API_KEY,AI_MODELandAI_MODEL_FASTin.env.
AI use counts against the owner of each workspace. To cap it, set AI_MONTHLY_TOKENS_PER_ACCOUNT: tokens per month
for all the workspaces of one owner, 0 for no cap. After a change in .env: docker compose up -d.
TaskForce sends sign-up codes, invitations and password resets by email. Without an SMTP server (the default):
- sign-up does not verify addresses, so anyone who reaches the app can create an account with any address, including one you invited. Keep the instance on a private network, or configure email;
- invitations are not emailed: the invited person signs up with the invited address and finds the invitation in the app;
- a forgotten password is reset by an admin in the Keycloak console (
http://localhost:8180, useradmin, passwordKEYCLOAK_ADMIN_PASSWORDin.env): realmtaskforce, Users, the person, Credentials, Reset password.
With an SMTP server, fill the MAIL_* values in .env, set SIGNUP_EMAIL_VERIFICATION=true and run
docker compose up -d.
Using it from other machines
By default every port listens on this machine only (BIND_ADDRESS=127.0.0.1). To open it to your network:
- In
.env, setBIND_ADDRESS=0.0.0.0and replacelocalhostwith this machine’s address inTF_APP_URL,TF_API_URL,TF_KEYCLOAK_URLandTF_STORAGE_URL. If you stay on plain http, also setAUTH_REFRESH_COOKIE_SECURE=false: browsers drop secure cookies over http (localhost aside), and sessions would end after 30 minutes. - Rebuild the app, which keeps the addresses it was built with:
docker compose up -d --build.
Sign-in sends passwords to the API. Beyond a trusted network, serve the four addresses over HTTPS with a reverse
proxy (Caddy, nginx, Traefik) and use the https:// addresses in .env.
Keycloak keeps the addresses it was first started with for its realm: after changing TF_APP_URL or TF_API_URL,
update the client taskforce-api (Valid redirect URIs, Web origins) in the Keycloak console.
Coding agents and integrations
- Each person can delegate issues to Claude Code running on their own computer: see
Coding agents. The runner only talks to the API, at
TF_API_URL. - GitHub and Slack need an OAuth app of your own, with
<TF_API_URL>/api/integrations/github/callbackand<TF_API_URL>/api/integrations/slack/callbackas callback URLs: see Integrations. - MCP servers and webhook receivers on your own network are refused unless you set
MCP_ALLOW_PRIVATE_NETWORK=trueorWEBHOOKS_ALLOW_PRIVATE_NETWORK=true.
Update
Database changes apply by themselves when the API starts. Back up before updating.
Backup and restore
What to keep: .env, the database and the files.
The dump contains both the TaskForce and the Keycloak databases. To restore on a fresh install, start only PostgreSQL
(docker compose up -d postgres), load the dump
(docker compose exec -T postgres psql -U taskforce -d postgres < taskforce-backup.sql), restore the files into the
taskforce_minio_data volume, then docker compose up -d. Use the same .env as the backup. Errors about roles or
databases that already exist are expected: the first start created them.
Stop or remove
docker compose stopstops everything and keeps your data.docker compose down -vdeletes everything, data included.