Step 2

Installation

Download the release package, extract it on the VPS, and run the installer. It provisions Docker, Node.js, Caddy, and Supabase, then starts the app.

1. Download & extract

SSH into your VPS, then download the latest timetracker-server-<version>.tar.gz release asset and extract it into ~/timetracker/server:

bash
mkdir -p ~/timetracker/server
curl -L -o timetracker-server.tar.gz <release-asset-url>
tar -xzf timetracker-server.tar.gz -C ~/timetracker/server

2. Run the installer

The package ships with an install.py script that provisions everything:

bash
cd ~/timetracker/server
python3 install.py

It prompts for a few values — press Enter to accept a default, or type your own:

  • API URL — e.g. https://api.yourdomain.com
  • Dashboard URL — e.g. https://app.yourdomain.com
  • License key
  • SMTP from-address and SMTP password

Replace the default URLs

The API and Dashboard URLs default to the maintainer's domains — be sure to enter your own, or the deployment will point at the wrong host.

Docker needs a fresh login, then re-run

On a host without Docker, the installer installs it, adds your user to the docker group, and then exits. Start a new login session so the group takes effect, and run the installer again:
bash
sudo su - $USER          # or simply reconnect over SSH
cd ~/timetracker/server
python3 install.py
On the second run it continues through the remaining steps.

From there the installer provisions the base packages, Node.js (via NVM), Caddy, and the Supabase containers; generates the server environment and public runtime config; installs production dependencies; registers the app with PM2; schedules a cron job; and configures Caddy. When it finishes it prints the database migration command — that's the next step.

Re-running is safe

The installer is idempotent. If you run it again it reuses the secrets it already generated rather than creating new ones, so existing sessions and containers keep working.