Quickstart

Get a running TaskLabs instance in a few minutes with Docker Compose.

Prerequisites

  • Docker 24 or newer, with Compose v2.
  • Node.js 20 or newer.
  • pnpm for workspace installs and tooling.
  • The frontend/ and backend/ packages installed with pnpm install at the repo root.

Quickstart

Copy the example environment file to .env.dev and fill in the documented values.

bash
cp .env.example .env.dev

Start the database, backend, and admin dashboard.

bash
docker compose --env-file .env.dev -f docker-compose.dev.yml \
  up -d postgres backend dashboard

Generate the security keys the backend needs. This is a one-time step.

bash
docker compose --env-file .env.dev -f docker-compose.dev.yml \
  exec backend ./generate_admin_key.sh

pnpm --dir backend keys

Paste the generated values into .env.dev as each command instructs, then start the app with the frontend and the Convex watcher.

bash
docker compose --env-file .env.dev -f docker-compose.dev.yml \
  up --build frontend convex-dev

Open the address you set as FRONTEND_ORIGIN in your .env.dev and continue to first-run setup.

First-run setup

The first visit shows a setup wizard. It claims the platform admin account with the credentials you choose, then sends you to the app. If public registration is enabled, other members can register from the login screen; otherwise they join through workspace invitations.

Telegram chat linking

Telegram notifications need a real public HTTPS origin. Leave TELEGRAM_WEBHOOK_ORIGIN empty until you have one — TaskLabs will not invent a fallback origin.

Starting it daily

After the one-time key setup, starting the stack is a single command.

bash
docker compose --env-file .env.dev -f docker-compose.dev.yml up -d

The dev stack uses the isolated project name tasklabs-dev, so it never reuses production volumes or state.

Production instance

The same Compose model powers a production instance. It runs the production image of the frontend, a one-shot Convex deploy step, and the backup scheduler — no watchers, no bind mounts.

Create the production environment file from the example and fill in the documented values: public origins (FRONTEND_ORIGIN, CONVEX_CLOUD_ORIGIN, CONVEX_SITE_ORIGIN, CORS_ALLOWED_ORIGINS), Postgres, and the RustFS + backup Telegram credentials.

bash
cp .env.example .env
# edit .env — every required key is documented in the template

Start the database, backend, and admin dashboard first.

bash
docker compose --env-file .env -f docker-compose.yml \
  up -d postgres backend dashboard

Generate the one-time security keys exactly as in the dev flow: the backend admin key on the live container, and the Convex Auth signing keys with pnpm --dir backend keys.

bash
docker compose --env-file .env -f docker-compose.yml \
  exec backend ./generate_admin_key.sh

pnpm --dir backend keys

Paste CONVEX_SELF_HOSTED_ADMIN_KEY, JWT_PRIVATE_KEY, and JWKS into .env, then bring up the whole stack. The build compiles the production frontend image; convex-deploy runs once to sync the Convex Auth env and push functions before the frontend starts; db-backup joins the stack.

bash
docker compose --env-file .env -f docker-compose.yml up --build -d

Check the health of all services, then open FRONTEND_ORIGIN to complete first-run setup.

bash
docker compose --env-file .env -f docker-compose.yml ps

Behind a proxy

Production is designed to sit behind Dokploy + Cloudflare Tunnel. Public subdomains map to the frontend, Convex API, and site proxy ports; the dashboard stays internal and is reached over an SSH tunnel. See the Production docs for the full checklist.

Never hand-edit the prod admin key

The admin key is generated on the live backend container and stored only in gitignored .env files. It is the single credential that deploys functions to your instance.