Section 1 — Platform Manuals
Engineers Manual
Deployment, configuration, and operations guide for engineers running the Track Any Device platform.
1. Platform Architecture
The platform runs as a set of Docker containers orchestrated by Docker Compose. Each surface is a separate container image pulled from Docker Hub:
server-login— SSO identity provider (Passport, Fortify)server-admin— Filament admin panelserver-api— central REST API (mobile, tenant portal, my portal)server-graphql— GraphQL API and Explorerserver-tenant— per-tenant operational portal (one container per tenant)server-cron— Laravel scheduler (offline detection, workflow triggers)server-queue— Laravel queue worker (signal processing, jobs)jt808-server— JT808 GPS TCP server (Go)
Infrastructure: MySQL 8.0, Redis 7, Soketi (WebSocket), InfluxDB (telemetry), Cloudflare Tunnel (routing).
The web frontend (track-any-device.com) is deployed separately to Cloudflare Pages.
2. Installation
The install script handles the full setup interactively:
mkdir tad && cd tad curl -fsSL https://raw.githubusercontent.com/track-any-device/.github/main/install.sh | bash
The script will prompt for:
- Domain — your main domain (e.g.
your-company.com) - Database — name and user (passwords auto-generated)
- Cloudflare Tunnel token — from Zero Trust dashboard
- SMS Gateway — optional, for 2FA OTP delivery
All other secrets (app keys, Pusher credentials, Passport RSA keys, InfluxDB tokens) are auto-generated. After confirming, it:
- Writes a complete
.envwith no placeholders - Generates
docker-compose.yml - Pulls all images and starts the stack
- Waits for MySQL and API container to be ready
- Runs
migrate+db:seedautomatically
3. Updating
Pull the latest images, apply new migrations, and restart changed services:
bash ~/tad/install.sh --update
This is safe to run at any time. It regenerates the compose file with the latest image tags and runs migrate --force automatically.
4. Cloudflare Tunnel
Go to Zero Trust → Networks → Tunnels → your tunnel → Public Hostnames and add:
| Subdomain | Service | Notes |
|---|---|---|
| login | http://login:80 | SSO |
| admin | http://admin:80 | Filament |
| api | http://api:80 | REST API |
| graphql | http://graphql:80 | GraphQL |
| ws | http://soketi:6001 | WebSocket — enable WS in settings |
| {slug} | http://tenant_{slug}:80 | One per tenant |
The root domain (your-company.com) is served by Cloudflare Pages — no tunnel entry needed.
docker compose --profile frp up -d) or Cloudflare Spectrum (Business plan) to expose the TCP port.5. Adding a Tenant Portal
Each tenant gets their own server-tenant container:
- Approve the tenant in the admin panel → copy the generated API key and SSO client credentials from the Portal API Keys tab
- Add a service block to
~/tad/docker-compose.ymlfollowing the commented example at the bottom of the file - Run
docker compose up -d tenant_{slug} - Add a Cloudflare Tunnel ingress rule:
{slug}.your-domain.com → http://tenant_{slug}:80
6. Running Artisan Commands
Use the api container (it has the full app code):
docker compose exec -w /var/www/html api php artisan <command>
Common commands:
# Re-run all migrations and seed php artisan migrate:fresh --seed --force # Check migration status php artisan migrate:status # Manage queue workers php artisan queue:restart # Run offline detection manually php artisan devices:detect-offline
cli container is a tools-only image (PHP + Composer + pnpm). It does NOT have app code — always use api for artisan commands on a production install.7. JT808 Device Provisioning
When a GPS tracker connects to port 7018 for the first time with an unknown IMEI, it is auto-created as a pending device in the admin panel. An administrator must approve it before signal data is processed.
To approve: Admin panel → Devices → find the pending device → Approve. Once approved, signals flow into the queue worker and are stored in MySQL (latest snapshot) and InfluxDB (history).
8. Monitoring
Optional logging stack (Grafana + Loki + Promtail):
docker compose --profile logging up -d # Grafana → http://localhost:3000
JT808 server exposes Prometheus metrics at :9090/metrics — connection counts, frame throughput, SOS alarms, decode errors.
9. Backup
Critical data to back up:
- MySQL data volume —
docker run --rm -v tad_mysql_data:/data busybox tar czf - /data ~/tad/.env— contains all generated secrets including Passport RSA keys- InfluxDB volume —
tad_influxdb_data(telemetry history)
The .env file is the most critical — without the Passport private key, existing tokens cannot be validated and all users will need to re-authenticate.
