Requirements
WarmDesk is a single statically-linked binary. No runtime dependencies are required on the host.
OS | Linux, macOS, or Windows (x86-64 or ARM64) |
RAM | 128 MB minimum (SQLite); 256 MB with PostgreSQL or MySQL |
Disk | 50 MB for the binary, plus database and uploaded files |
Network | Inbound HTTP/HTTPS on your chosen port; outbound SMTP (optional) |
Quick start
1. Download
Download the latest release archive for your platform from the releases page.
Linux releases are distributed as .tar.gz archives containing the server binary and the bundled web frontend.
Extract the archive before running:
# Linux x86-64
wget https://github.com/tonk/warmdesk/releases/latest/download/warmdesk-v0.9.20-linux-amd64.tar.gz
mkdir warmdesk && tar -xzf warmdesk-v0.9.20-linux-amd64.tar.gz -C warmdesk
cd warmdesk
# Linux ARM64
wget https://github.com/tonk/warmdesk/releases/latest/download/warmdesk-v0.9.20-linux-arm64.tar.gz
mkdir warmdesk && tar -xzf warmdesk-v0.9.20-linux-arm64.tar.gz -C warmdesk
cd warmdeskNote | Replace v0.9.20 with the actual version number from the releases page. |
Desktop installers for macOS (.dmg) and Linux (.AppImage) are listed in the Desktop apps section.
2. Configure
Create a minimal warmdesk.yaml in the same directory as the binary:
port: 8080
jwt_secret: replace-with-a-long-random-string # REQUIRED — server refuses default valueSee the full configuration reference below.
3. Run
./warmdeskOn first start, WarmDesk creates warmdesk.db (SQLite) in the current directory and starts listening on port 8080.
Open http://localhost:8080 in your browser and register the first user.
Tip | On an empty database, that first registration becomes an admin automatically. Further admins can be promoted from Admin → Users. |
Build from source
git clone https://github.com/tonk/warmdesk.git
cd warmdesk
# Build frontend + backend into dist/
make build
# Run from the build output
cd dist
WEB_DIR=./web JWT_SECRET=your-secret ./warmdeskRequires Go 1.21+ and Node.js 20+.
Configuration reference
Configuration is loaded in priority order:
CLI flag:
--config /path/to/file.yamlCONFIG_FILEenvironment variablewarmdesk.yamlin the current directoryBuilt-in defaults
Every YAML key has a matching environment variable override (e.g. port → PORT).
| Key | Env var | Default | Description |
|---|---|---|---|
|
|
| HTTP port to listen on |
|
| (none — required) | HS256 signing secret; server refuses to start at default value |
|
|
|
|
|
|
| Database connection string |
|
|
| Path to the compiled frontend |
|
|
| Directory for uploaded files |
|
|
| Maximum file upload size in MB |
|
| (optional) | Redis connection URL for multi-instance WebSocket pub/sub |
|
| CORS allowed origins; | |
|
|
| Set to |
|
|
| TLS mode for remote PostgreSQL/MySQL: |
Important | Set db_tls_mode: verify-full for any remote database. Without TLS, credentials travel in plaintext. |
Database setup
SQLite (default)
No setup required. The database file is created automatically on first run.
PostgreSQL
# Create database and user
psql -U postgres -c "CREATE USER warmdesk WITH PASSWORD 'secret';"
psql -U postgres -c "CREATE DATABASE warmdesk OWNER warmdesk;"# warmdesk.yaml
db_driver: postgres
db_dsn: host=localhost user=warmdesk password=secret dbname=warmdesk sslmode=disableMySQL / MariaDB
mysql -u root -e "CREATE DATABASE warmdesk CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql -u root -e "CREATE USER 'warmdesk'@'%' IDENTIFIED BY 'secret';"
mysql -u root -e "GRANT ALL ON warmdesk.* TO 'warmdesk'@'%';"# warmdesk.yaml
db_driver: mysql
db_dsn: warmdesk:secret@tcp(localhost:3306)/warmdesk?charset=utf8mb4&parseTime=True&loc=LocalRunning as a service (systemd)
A ready-made systemd unit is included in deploy/warmdesk.service.
# Copy binary, web frontend, and config
sudo cp -r warmdesk/ /opt/warmdesk/
sudo cp warmdesk.yaml /opt/warmdesk/
# Install and enable the service
sudo cp deploy/warmdesk.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl enable --now warmdesk
sudo journalctl -u warmdesk -f # follow logsReverse proxy (nginx)
The deploy/nginx.conf template configures nginx as a TLS-terminating reverse proxy.
server {
listen 443 ssl http2;
server_name warmdesk.example.com;
ssl_certificate /etc/letsencrypt/live/warmdesk.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/warmdesk.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}proxy_http_version 1.1 and the Upgrade/Connection headers are required for WebSocket to work through the proxy.
Desktop apps
Pre-built Tauri 2 desktop apps are available on the releases page:
warmdesk-linux-amd64.AppImage— Linux (no install required)warmdesk-mac-universal.dmg— macOS (Intel + Apple Silicon)warmdesk-windows-installer.exe— Windows NSIS installer
The desktop app wraps the same Vue 3 frontend.
On launch it prompts for the server URL and stores credentials in sessionStorage.
Horizontal scaling
To run multiple instances behind a load balancer:
redis_url: redis://redis-host:6379/0
db_driver: postgres
db_dsn: host=pg-primary user=warmdesk ...All instances must share the same database and Redis instance. WebSocket broadcasts and rate-limiter state are routed through Redis so every instance sees every event.
Note | The in-process rate limiter does not yet have a Redis backend. For strict rate limiting across multiple instances, place a WAF or rate-limiting proxy in front. |
Demo data seeder
WarmDesk ships with a warmdesk-seed binary that populates a fresh database with sample projects, boards, cards, users, and time entries.
It is included in the release .tar.gz alongside the main binary — no compilation required.
Warning | The seeder creates fictitious data in the database it connects to. Never run it against a production instance. |
Running the seeder
# Extract the release archive (if not already done)
tar -xzf warmdesk-v0.9.20-linux-amd64.tar.gz -C warmdesk
cd warmdesk
# Seed the default SQLite database in the current directory
./warmdesk-seed
# Seed a specific database via environment variables
DB_DRIVER=postgres \
DB_DSN="host=localhost user=warmdesk password=secret dbname=warmdesk_demo sslmode=disable" \
./warmdesk-seedAfter seeding, start the server normally. The seeder prints the credentials of the created demo accounts to stdout.
What the seeder creates
Several sample projects (Kanban and Scrum) with columns and cards
Cards with descriptions, checklists, labels, assignees, and comments
A set of demo users with different global roles
Sample time entries spread across the past few weeks
Example customers and contracts
Security checklist
❏
jwt_secretis a long random string (not the default)❏
gin_modeisreleasein production❏
allowed_originslists only your actual domain(s)❏
db_tls_mode: verify-fullis set for remote databases❏ TLS is terminated at the reverse proxy (nginx / Apache / Caddy)
❏ Firewall blocks direct access to port 8080 from the internet
❏
upload_diris outside the web root❏ Backups are scheduled and tested