Description
Today only one of client-dev, scylla-dev, or fake-data can be up at a time. Every service has a fixed container_name and every host port is hardcoded, so a second stack collides on names and ports. Make the dev compose profiles parallel-safe by parameterizing host ports through env vars and dropping fixed container names. Defaults must match today's behavior exactly so production profiles (router, brick, tpu) and current single-stack workflows are byte-identical to today. Multiple ng serve clients and multiple cargo-run scyllas already work via existing flags and are out of scope.
Acceptance Criteria
- A single
./argos.sh <profile> up with no env vars binds exactly the same host ports it does today (db 5432, scylla 8000, client 80, siren 1883/9002, grafana 3002). No production behavior changes.
- Setting STACK_OFFSET=N (e.g.
STACK_OFFSET=10 ./argos.sh fake-data up) shifts every published host port by N and suffixes the compose project name so a second stack can run alongside the first with zero collisions on names or ports.
- All host port bindings in compose.yml, compose.client-dev.yml, compose.client.yml, compose.siren.yml, and compose.grafana.yml are env-driven via ${VAR:-default} with defaults that match today's values.
- The dockerized client's BACKEND_URL follows the offset, so a second client-dev stack's client points at its own scylla, not the default one.
- Router, brick, and tpu profile files are unchanged on disk and the router image still builds.
- /run-local detects backends across the offset port range and reports which stack is up when the chosen scylla isn't on 8000.
Proposed Solution
- Drop container_name from every dev-path service: compose/compose.yml, siren-base/compose.siren.yml, siren-base/compose.grafana.yml, angular-client/compose.client.yml, compose/compose.calypso.yml. The project-name prefix from argos.sh -p already handles uniqueness.
- Parameterize host ports as ${VAR:-default}:container_port for db (5432), scylla (8000), client (80), siren (1883 and 9002), grafana (3002). Also pass SCYLLA_PORT into the scylla container so its listener tracks the host binding.
- Update compose.client-dev.yml BACKEND_URL to follow SCYLLA_HOST_PORT.
- Extend argos.sh: when STACK_OFFSET is unset or 0, behavior is identical to today. When STACK_OFFSET=N is set, the script exports ODYSSEY_DB_PORT=$((5432+N)), SCYLLA_HOST_PORT=$((8000+N)), CLIENT_HOST_PORT=$((80+N)), SIREN_MQTT_PORT=$((1883+N)), SIREN_WS_PORT=$((9002+N)), GRAFANA_HOST_PORT=$((3002+N)), and uses a project name like odyssey_client-dev_o10 so down/logs/exec target the right stack.
- Switch scylla-server/integration_test.sh's docker rm -f odyssey-db to a project-aware compose down so it doesn't depend on the fixed container name.
- Update compose/README.md with the STACK_OFFSET recipe and concurrent-stack example, and update .claude/skills/run-local/SKILL.md to scan 8000/8010/8020/… for backend liveness and surface which stack is which.
- Testing: single-stack regression (no env vars, ports identical to today), two-stack parallel run with STACK_OFFSET=10 on the second one, and confirm the router image still builds.
Description
Today only one of client-dev, scylla-dev, or fake-data can be up at a time. Every service has a fixed container_name and every host port is hardcoded, so a second stack collides on names and ports. Make the dev compose profiles parallel-safe by parameterizing host ports through env vars and dropping fixed container names. Defaults must match today's behavior exactly so production profiles (router, brick, tpu) and current single-stack workflows are byte-identical to today. Multiple ng serve clients and multiple cargo-run scyllas already work via existing flags and are out of scope.
Acceptance Criteria
./argos.sh <profile> upwith no env vars binds exactly the same host ports it does today (db 5432, scylla 8000, client 80, siren 1883/9002, grafana 3002). No production behavior changes.STACK_OFFSET=10 ./argos.sh fake-data up) shifts every published host port by N and suffixes the compose project name so a second stack can run alongside the first with zero collisions on names or ports.Proposed Solution