| What | Where |
|---|---|
| Host | OpenClaw EC2 i-013cea9c6cd35a538, EIP 34.198.157.4, Amazon Linux 2023 |
| Shell | ssh-ec2 ssh --instance-id i-013cea9c6cd35a538 '<cmd>' |
| Service | systemd location-service (user location), 127.0.0.1:18810 |
| Code / venv | /opt/location-service/app, /opt/location-service/venv (python3.13) |
| Data | /var/lib/location-service/location.db (SQLite, WAL) |
| Secrets (box) | /etc/location-service/location.env (600, location) |
| Secrets (Mac) | location-tracking/secrets/location.env (gitignored): LOCATION_API_TOKEN, LOCATION_OVERLAND_TOKEN, LOCATION_OWNTRACKS_TOKEN, LOCATION_OPENCLAW_HOOK_TOKEN |
| TLS | Caddy, /etc/caddy/sites/location.caddy (imported by /etc/caddy/Caddyfile) |
| DNS | terraform/ → Route53 A location.evanrthomas.com → OpenClaw EIP (state s3://evanrthomas-tfstate/location-tracking/terraform.tfstate) |
cd ~/github.com/ethomas2/location-tracking
(cd backend && venv/bin/python -m pytest tests) # optional
scripts/deploy.sh
Idempotent: copies code/docs/secrets, installs deps only when requirements.txt changed, restarts the service,
installs the Caddy site + import, and syncs OpenClaw's hooks config, LOCATION_API_* gateway env and the location
skill (from ../openclaw-ec2/skills/location); restarts the OpenClaw gateway only if those changed.
ssh-ec2 ssh --instance-id i-013cea9c6cd35a538 'sudo journalctl -u location-service -n 100 --no-pager'
ssh-ec2 ssh --instance-id i-013cea9c6cd35a538 'systemctl status location-service --no-pager'
ssh-ec2 ssh --instance-id i-013cea9c6cd35a538 'sudo systemctl restart location-service'
curl -s https://location.evanrthomas.com/healthz
The access log is off on purpose (Overland's token may be in the query string).
secrets/location.env (new value: openssl rand -hex 24).scripts/deploy.sh (updates the box env file, the gateway env / hooks token, restarts what changed).LOCATION_OVERLAND_TOKEN), OwnTracks password, or anything using the API token.
LOCATION_OPENCLAW_HOOK_TOKEN and LOCATION_API_TOKEN are only used on the box; deploy handles them.SQLite online backup (safe while running), streamed to the Mac as base64 so the ssh-ec2 banner can't corrupt it:
ssh-ec2 ssh --instance-id i-013cea9c6cd35a538 \
'sudo -u location python3 -c "import sqlite3; s=sqlite3.connect(\"/var/lib/location-service/location.db\"); d=sqlite3.connect(\"/var/lib/location-service/backup.db\"); s.backup(d); d.close()" && sudo base64 /var/lib/location-service/backup.db && sudo rm /var/lib/location-service/backup.db' \
2>/dev/null | grep -E '^[A-Za-z0-9+/=]+$' | base64 -d > location-$(date +%F).db
sqlite3 location-$(date +%F).db 'select count(*) from fixes'
Restore: stop the service, copy the file to
/var/lib/location-service/location.db owned by location, start it. The root EBS volume is the only other copy;
there is no automatic off-box backup yet.
H="Authorization: Bearer $LOCATION_API_TOKEN"
curl -s -H "$H" https://location.evanrthomas.com/events?limit=20 | jq
curl -s -H "$H" -X DELETE "https://location.evanrthomas.com/location/history?device=test-device"
/etc/caddy/Caddyfile (owned by openclaw-ec2/scripts/web-proxy.sh) ends with import /etc/caddy/sites/*.caddy;
each extra site is a file there. After editing: caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile &&
sudo systemctl reload caddy. openclaw.evanrthomas.com must keep redirecting to Google login (302).