# Host Port block `10880`–`10889` on ubudual5060 is allocated to this project. `:10880` is Ty's local Node/SvelteKit and must never be bound by project deploys. The dev-test environment binds `0.0.0.0` so any machine on `192.168.1.0/24` can reach it. ## Dev-test environment (M2 current, M3 incoming) - Host: `ubudual5060` / LAN `192.168.1.202` / Tailscale `100.64.0.9` - Container: `slabuploader-m2-overnight` (image `slabuploader-m2:overnight`) - Port: **10881** → 80, bound `0.0.0.0` - URLs: `http://192.168.1.202:10881` (LAN) · `http://100.64.0.9:10881` (Tailscale) - M3 replaces this container on the same port; remove the M2 container once M3 is healthy. ## Ty local Node/SvelteKit (do not overwrite) - Host: `ubudual5060` / `100.64.0.9` - Container: `slabuploader-m1` - Port: **18080** → 80 (inventory previously listed 10880; that port is off limits to project deploys) - URL: `http://100.64.0.9:18080` - **Never** recreate or remap this container for project deploys. Future deploys use a **separate** container name and a free port in `10880`–`10889` (other than `10880`), bound `0.0.0.0`. Do not put a host name in the product spec. ## Deploy records ### 2026-09-21 02:41 PDT — #90 wood primary category + derived thickness band - Source ref: `0329052` on `issue-89-metadata-lock` (pushed to Gitea; pulled into `~/slab-deploy`). - Images (built on `ubudual5060`): `deploy-frontend:latest` `1c169c29f131`, `deploy-fastapi:latest` `32671659639b`. - Compose: `deploy/docker-compose.yml` + host-local (untracked) `deploy/override-m3.yml`. - URL: `http://192.168.1.202:10881` (LAN) · `http://100.64.0.9:10881` (Tailscale). - `matches HEAD`: **yes**. - Sample data preserved: **yes** — 24 slabs before and after `up -d` (no `-v`, no volume removal). - Verified on the live stack: served asset `assets/index-tlFib3RM.js` (sha256 `3b665746ec81f28e…`) contains the new markers and no `#thickness` select; `POST /api/v1/slabs` at `thickness_in 1.0` stored band `350` (`1"- 1 1/2"`); `PUT` at `2.75` re-banded to `352`; a client-sent stale band id was ignored; `POST /review` no longer lists thickness as missing; the Review screen in a real browser (LAN URL) shows the wood-category MultiSelect closed summary with names + count, the `Primary wood category` radio set switching on click, and the band as read-only text. - Not exercised: the Woo publish path. Rows created **before** this deploy keep `thickness_term_id` NULL until their next save (the band is derived on write, so any Review commit fills it in).