Skip to content

Bug Collector (updates.wantok.cz)

The bug collector accepts bug reports from SafeCall installations and creates GitLab issues. It runs as a systemd service on the update host (mnew.ssh / updates.wantok.cz) and is redeployed automatically on every bun commit.

Client-side sync (installations → collector) is documented under CLI backup & restore (safecall app bugs sync).

Automatic deploy

On each release commit (bun commitserver build via scripts/build/server.sh):

  1. SafeCall binaries upload to /home/thomas/updates/
  2. scripts/build/bug-collector.sh runs tests, compiles releases/bug-collector-x64, SCPs it to mnew.ssh:/home/thomas/bug-collector/bug-collector.new, atomically renames it, and restarts the service:
bash
sudo /bin/systemctl restart bug-collector.service

--server-only / --skip-upload on server.sh skips both SafeCall artifact upload and bug-collector deploy.

Manual build (no upload):

bash
./scripts/build/bug-collector.sh --skip-upload
# or from package:
cd bug-collector && bun run build

One-time server setup

Run on mnew.ssh as a user with sudo.

1. Directory

bash
mkdir -p /home/thomas/bug-collector
chown thomas:thomas /home/thomas/bug-collector

2. Environment file

Create /home/thomas/bug-collector/bug-collector.env (never deployed from git):

bash
BUG_COLLECTOR_PORT=8791
BUG_COLLECTOR_SHARED_SECRET=replace-me
GITLAB_TOKEN=glpat-...
GITLAB_PROJECT_ID=group/safecall
# GITLAB_API_URL=https://gitlab.com/api/v4
BUG_COLLECTOR_DB_PATH=/home/thomas/bug-collector/bug-collector.db

BUG_COLLECTOR_SHARED_SECRET must match server_bug_collector_shared_secret on installations that sync reports.

3. systemd unit

Create /etc/systemd/system/bug-collector.service:

ini
[Unit]
Description=SafeCall bug collector
After=network.target

[Service]
Type=simple
User=thomas
WorkingDirectory=/home/thomas/bug-collector
ExecStart=/home/thomas/bug-collector/bug-collector
Restart=on-failure
EnvironmentFile=/home/thomas/bug-collector/bug-collector.env

[Install]
WantedBy=multi-user.target

Enable and start (after the first binary is in place, or start after the first deploy):

bash
sudo systemctl daemon-reload
sudo systemctl enable bug-collector.service
sudo systemctl start bug-collector.service
sudo systemctl status bug-collector.service

Health check:

bash
curl -sS http://127.0.0.1:8791/health
# → ok

4. sudoers (passwordless restart)

Allow the deploy user to restart the service without a password (same pattern as MetaPrism). Use visudo / a drop-in under /etc/sudoers.d/:

thomas ALL=(root) NOPASSWD: /bin/systemctl restart bug-collector.service

The path must be exactly /bin/systemctl and the unit name exact — deploy runs:

bash
ssh mnew.ssh sudo /bin/systemctl restart bug-collector.service

Verify:

bash
sudo -l

5. nginx

Proxy public https://updates.wantok.cz/bugs/ to the local service:

nginx
location /bugs/ {
    proxy_pass http://127.0.0.1:8791/bugs/;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    client_max_body_size 10m;
}

Reload nginx after editing. Installations use https://updates.wantok.cz/bugs as server_bug_collector_url (SafeCall brand default).

API surface

MethodPathAuth
GET/health or /bugs/healthnone
POST/v1/reports or /bugs/v1/reportsAuthorization: Bearer <secret>
POST/v1/status or /bugs/v1/statusAuthorization: Bearer <secret>
POST/v1/comments or /bugs/v1/commentsAuthorization: Bearer <secret>

See the bug-collector/README.md in the repository for field details. Unknown paths / bad auth / schema mismatches return a minimal empty-body error status.

Status sync (POST /v1/status) keeps GitLab opened/closed aligned with each installation's local open / fixed state. Daily open pings that already match GitLab do nothing; mismatches get a comment plus reopen or close.

Troubleshooting

SymptomCheck
Deploy asks for sudo passwordsudoers NOPASSWD rule missing or path/unit mismatch
Service fails after restartjournalctl -u bug-collector.service -n 50; env file secrets; binary chmod +x
Installations never syncserver_bug_tracker_enabled, URL, and shared secret on the install; daily 16:00 cron app bugs sync