Confirmed against the real deployed server: Cloudflare Tunnel's free tier caps request bodies at ~100MB and returns a plain 413 - a direct LAN upload of the same 250MB test file succeeds, the identical request through yaris.ceaf.dev does not. Real dashcam clips average ~320MB, so no dashcam video could ever complete an upload through the tunnel as it stood, regardless of the earlier memory-streaming fix. Server: new /api/v1/dashcam/upload/chunk (accepts one chunk at a time, keyed by relative_path+sha256+chunk_index/total_chunks, reassembles and verifies the sha256 once every chunk has arrived) and /api/v1/dashcam/upload/status (reports which chunk indices a given upload already has, or "already_uploaded" if it's done) endpoints. Chunks are staged under STORAGE_DIR/.upload_tmp/<device>/<sha256>/ and cleaned up after reassembly; a stale partial set left by a differently -chunked earlier attempt is detected via a small marker file and wiped before restarting. The original single-shot /upload endpoint is left in place unchanged. Client (modules/app_upload.py): _upload_dashcam_files() now calls _upload_video_chunked(), which checks /status first (so a prior partial upload resumes instead of restarting from byte 0) and then POSTs any missing 40MB chunks (DASHCAM_CHUNK_SIZE, comfortably under Cloudflare's cap) via the same streaming MultipartEncoder approach as before. Co-authored-by: Copilot <[email protected]>
yaris-obd remote server
A small Flask + Postgres API that receives trip/GPS log batches and dashcam video files uploaded by the Pi (see the repo root readme.md and PLAN.md for the overall project). Designed to run as a docker-compose stack on an unraid server (or any Docker host).
What it does
GET /health— unauthenticated liveness check.POST /api/v1/tracking/batch— bulk-insert a batch of GPS/trip points.POST /api/v1/dashcam/upload— upload one dashcam video file (multipart, content-addressed by sha256 so retries/duplicates are safe).
Both upload endpoints require two headers: X-Device-Name and X-Api-Key
(see Registering a device
below). Postgres is not published to the LAN — only the api container
talks to it, over the internal compose network.
Deploying on unraid
- Get the code onto the unraid box (same repo as the Pi, just the
server/sub-folder matters here):ssh root@<unraid-ip> mkdir -p /mnt/user/app/git && cd /mnt/user/app/git git clone [email protected]:quoije/yaris-obd.git cd yaris-obd/server - Copy the env template and fill in a real Postgres password:
Recommended
cp .env.example .env nano .env # set POSTGRES_PASSWORD, and DATA_DIR if you want data on the arrayDATA_DIRfor unraid:/mnt/user/appdata/yaris-obd-server(keeps Postgres data + dashcam files on the array, backed up like your other appdata). - Build and start the stack:
This is also importable into unraid's Compose Manager plugin if you'd rather manage start/stop/updates from the Unraid UI.
docker compose up -d --build - Confirm it's healthy:
docker compose ps curl http://localhost:8098/health
Registering a device and getting an API key
Run this once per device (e.g. once for the Pi) after the stack is up:
docker compose exec api python3 scripts/create_device.py yaris-2013
This prints a one-time API key — copy the YARIS_UPLOAD_DEVICE_NAME /
YARIS_UPLOAD_API_KEY values into the Pi's upload-client config. Only the
key's sha256 hash is stored server-side; the raw key is never shown again
(re-run the script with the same device name to rotate/replace the key).
Exposing it outside the LAN
Two options, either works with this API unchanged:
- Cloudflare Tunnel (already running on this unraid box): add a public
hostname rule in the Cloudflare dashboard pointing at
http://<unraid-lan-ip>:8098(orhttp://api:8098if you point the tunnel at theapicontainer directly on the compose network). Good for small tracking-data batches; large dashcam uploads may hit the tunnel's per-request size limit. - Router port-forward (fallback if needed): forward an external port to
<unraid-lan-ip>:8098and let your router/firewall (e.g. Unifi) handle the security side. No changes needed here either way.
For large dashcam uploads from home, consider adding a local DNS
override/rewrite (e.g. in AdGuard Home, same trick used for yaris.local on
the Pi) so the hostname resolves directly to the unraid LAN IP while on the
home network, bypassing the tunnel entirely for big transfers.
Toggling dashcam uploads off
The Pi's web UI has a setting to pause dashcam file uploads while keeping
GPS/trip log uploads running — no server-side change needed, the Pi simply
stops calling /api/v1/dashcam/upload while the toggle is off.
Local development / testing without unraid
cd server
cp .env.example .env # edit POSTGRES_PASSWORD
docker compose up --build
curl http://localhost:8098/health