This guide covers installing Taskwondo without Docker Compose. You'll need to provide your own PostgreSQL, NATS, and S3-compatible storage (MinIO, AWS S3, etc.) and a reverse proxy for the web frontend.
- PostgreSQL 15+
- NATS with JetStream enabled
- S3-compatible object storage (MinIO, AWS S3, DigitalOcean Spaces, etc.)
- Nginx (or any web server that can serve static files and reverse-proxy)
Download the server bundle (taskwondo-server-*.tar.gz) from the Releases page. The Dev Build release always has the latest build from main.
taskwondo-server-<version>/
bin/taskwondo-api # API server (static Linux binary)
bin/taskwondo-worker # Background worker (static Linux binary)
html/ # Web frontend (static files)
nginx.conf # Nginx site configuration (reference)
.env.template # Configuration template
install.sh # Setup script
Generate a .env file from the template:
./install.sh --manual-setupThis walks you through the required settings interactively, generating secrets automatically. Use -y for non-interactive mode with auto-generated defaults:
./install.sh --manual-setup -yThen edit .env to set your database URL, storage credentials, and NATS URL.
To see all available configuration variables with descriptions:
./install.sh --manual-setup-info# JWT_SECRET (64-char hex)
openssl rand -hex 32
# ADMIN_PASSWORD (32-char base64)
openssl rand -base64 24Create the database and user in PostgreSQL:
CREATE USER taskwondo WITH PASSWORD 'your-password';
CREATE DATABASE taskwondo OWNER taskwondo;Migrations run automatically on startup. To run them without starting the server:
bin/taskwondo-api -migrate-onlyCreate a bucket in your S3-compatible storage matching the STORAGE_BUCKET value. For MinIO:
mc mb myminio/taskwondo-attachmentsSource the environment and start the binary:
set -a && source .env && set +a
bin/taskwondo-apiThe API listens on API_HOST:API_PORT (default 0.0.0.0:8080). On first start it runs migrations and seeds the admin user.
To run as a systemd service, create /etc/systemd/system/taskwondo-api.service:
[Unit]
Description=Taskwondo API
After=network.target postgresql.service
Requires=taskwondo-worker.service
[Service]
Type=simple
EnvironmentFile=/opt/taskwondo/.env
ExecStart=/opt/taskwondo/bin/taskwondo-api
Restart=on-failure
User=taskwondo
WorkingDirectory=/opt/taskwondo
[Install]
WantedBy=multi-user.targetThe worker processes background jobs (email notifications, stats aggregation). It requires a running NATS server with JetStream enabled.
set -a && source .env && set +a
bin/taskwondo-workerTo run as a systemd service, create /etc/systemd/system/taskwondo-worker.service:
[Unit]
Description=Taskwondo Worker
After=network.target postgresql.service
[Service]
Type=simple
EnvironmentFile=/opt/taskwondo/.env
ExecStart=/opt/taskwondo/bin/taskwondo-worker
Restart=on-failure
User=taskwondo
WorkingDirectory=/opt/taskwondo
[Install]
WantedBy=multi-user.targetThe html/ directory contains the built frontend. Serve it with Nginx (or any static file server) and proxy /api/ requests to the API.
The included nginx.conf is a working reference configuration. Key points:
- Serves static files from the
html/directory - Proxies
/api/and health endpoints (/healthz,/readyz) to the API backend - SPA fallback: all non-file routes serve
index.html - Static asset caching with
Cache-Control: public, immutable - Upload limit set to 55 MB (
client_max_body_size)
Adjust proxy_pass http://api:8080 to match your API address (e.g. http://127.0.0.1:8080).
Example Nginx setup:
cp nginx.conf /etc/nginx/sites-available/taskwondo
ln -s /etc/nginx/sites-available/taskwondo /etc/nginx/sites-enabled/
# Edit the file: update root path, proxy_pass address, server_name
nginx -t && systemctl reload nginx- Liveness:
GET /healthz— returns200if the process is running - Readiness:
GET /readyz— returns200when the database is reachable