This setup works for Timekeeper on a Synology NAS, Docker Desktop or Docker Engine. Tailscale Serve provides HTTPS access within your tailnet and forwards requests to the server’s local HTTP endpoint. Install the server using the Synology deployment guide or local Docker guide, then configure access here.
The DSM installer also offers optional Tailscale detection and manual root commands for persistent forwarding and cleanup before uninstall. The manual instructions below work on all deployment hosts.
Connect the server host and client device to Tailscale. Enable MagicDNS and HTTPS certificates in the tailnet; Serve prompts for missing setup. Tailnet access rules must allow the client device to reach this host on TCP port 8443. See HTTPS setup.
Run the commands on the host operating system, where http://127.0.0.1:8080
is reachable. Keep TIMEKEEPER_BIND_ADDRESS=127.0.0.1 in the deployment .env.
Both Compose setups already publish their gateway on this address. If you changed
TIMEKEEPER_HTTP_PORT, replace 8080 in the commands below.
The native DSM package automatically selects and remembers its local port. Read that non-secret port on the NAS before configuring Serve:
timekeeper_port=$(sudo cat /var/packages/timekeeper/target/private/config/http-port)
case "$timekeeper_port" in ''|*[!0-9]*) exit 1 ;; esac
sudo /var/packages/Tailscale/target/bin/tailscale serve status
sudo /var/packages/Tailscale/target/bin/tailscale serve --bg --https=8443 "http://127.0.0.1:$timekeeper_port"
sudo /var/packages/Tailscale/target/bin/tailscale serve status
Use another HTTPS port if 8443 already serves an application. This is a one-time administrator operation; Timekeeper’s package account does not need permission to manage Tailscale. Installing Timekeeper alone does not enable Serve. The generic Compose instructions below use port 8080 unless you configured another one.
On Synology, install and sign in to the Tailscale package through Package Center, then open an SSH shell on the NAS. If the CLI is unavailable in your shell, use its package path with administrator privileges:
alias tailscale='sudo /var/packages/Tailscale/target/bin/tailscale'
See the official Synology instructions for package installation and SSH access.
On macOS, install CLI integration from the Tailscale app settings, or use its bundled CLI in this shell:
alias tailscale='/Applications/Tailscale.app/Contents/MacOS/Tailscale'
See the macOS CLI instructions.
On Windows with Docker Desktop, run Serve on Windows. On Linux, use the
installed tailscale CLI on the Docker host.
Check that the local server is ready:
curl --fail --silent --show-error http://127.0.0.1:8080/q/health/ready
Check existing endpoints, then enable the Timekeeper endpoint:
tailscale status
tailscale serve status
tailscale serve --bg --https=8443 http://127.0.0.1:8080
tailscale serve status
Choose another HTTPS port if 8443 already serves another application, and allow
that port in the tailnet’s access rules. --bg keeps the endpoint available
after the command exits and resumes it after Tailscale restarts. The host must
remain running and connected. See the Serve CLI reference.
Use the full HTTPS DNS name printed by Serve. For example:
| Client | Address |
|---|---|
| Browser | https://timekeeper.tail1234.ts.net:8443/web/ |
| Eclipse Server URL | https://timekeeper.tail1234.ts.net:8443/api/v1 |
| Readiness | https://timekeeper.tail1234.ts.net:8443/q/health/ready |
Replace the example hostname with your host’s printed name. Use that DNS name
for certificate validation; Eclipse requires HTTPS outside loopback. Browser
sessions use normal account sign-in; Eclipse uses a personal API token created
under My Account. On first deployment, set TIMEKEEPER_PUBLIC_ORIGIN to
the exact HTTPS origin (including the port when non-default). After installation,
change the public address in Administration → General settings and restart
every server instance. If the saved address is unreachable, use the explicit
operator recovery in the account guide.
Both access paths use the same private account and persistent database.
From the client device, verify readiness:
curl --fail --silent --show-error https://timekeeper.tail1234.ts.net:8443/q/health/ready
If this fails, check local server readiness first, then Serve status, the Tailscale connection, DNS and access rules for the selected HTTPS port. If local requests work but HTTPS returns an empty HTTP 400, compare the request using the public hostname on the server host:
curl --include --header 'Host: timekeeper.tail1234.ts.net:8443' http://127.0.0.1:8080/web/
Use your actual hostname and selected local port. Quarkus 3.40 automatically restricts Host headers when bound to loopback. The DSM package adds the hostname from the installation’s public HTTPS origin to its allowlist, while keeping local health checks and rejecting unrelated hosts. Upgrade older package candidates if they reject that hostname. See Quarkus Host validation.
To remove this endpoint, run on the server host:
tailscale serve --bg --https=8443 off
After schema-5 initialization, change the public HTTPS address in Administration and restart Timekeeper. Tailscale forwarding remains an operator command; changing the application address does not create a Serve rule. The account guide also covers recovery when the previous hostname is no longer reachable.