refactor: scope stack docker object names to avoid collision on shared hosts#20
Merged
Conversation
Signed-off-by: Noppanat Wadlom <noppanat.wad@gmail.com>
Signed-off-by: Noppanat Wadlom <noppanat.wad@gmail.com>
timzsu
requested changes
May 6, 2026
Collaborator
timzsu
left a comment
There was a problem hiding this comment.
Only a few minor comments.
| `FLOWMESH_VERSION` to a PR-identifying slug (e.g. `myfeature`) so parallel | ||
| PRs don't overwrite each other's local images. | ||
|
|
||
| When multiple people share one host, give each stack its own |
Collaborator
There was a problem hiding this comment.
Suggested change
| When multiple people share one host, give each stack its own | |
| When multiple deployments share one host, give each stack its own |
Those deployments are not necessarily owned by multiple people. One people testing multiple deployments concurrently can benefit from this as well.
| When multiple people share one host, give each stack its own | ||
| `FLOWMESH_STACK_SUFFIX` and distinct `SERVER_HTTP_PORT`, | ||
| `SERVER_GRPC_PORT`, `REDIS_CONTROL_PORT`, and `REDIS_TELEMETRY_PORT`. | ||
| The suffix isolates Docker object names; the ports isolate host bindings. |
Collaborator
There was a problem hiding this comment.
Suggested change
| The suffix isolates Docker object names; the ports isolate host bindings. | |
| The suffix isolates Docker object names (including containers, volumes, and networks); the ports isolate host bindings. |
The Docker image names are not isolated, so we still need to avoid image tag overlap. This is explicit in cli/stack/src/flowmesh_cli_stack/env_schema.py, but here I am not sure if it will be a bit ambiguous for agents.
| directory or volume so the server can access the worker's task results. | ||
| Otherwise, downstream tasks that depend on upstream outputs will stall | ||
| in the dispatching loop indefinitely. | ||
| - When multiple people share one host, you can set `FLOWMESH_STACK_SUFFIX` |
Collaborator
There was a problem hiding this comment.
Suggested change
| - When multiple people share one host, you can set `FLOWMESH_STACK_SUFFIX` | |
| - When multiple deployments share one host, you can set `FLOWMESH_STACK_SUFFIX` |
Signed-off-by: Noppanat Wadlom <noppanat.wad@gmail.com> Co-authored-by: Zhengyuan Su (苏政渊) <su.zhengyuan@u.nus.edu>
Signed-off-by: Noppanat Wadlom <noppanat.wad@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Purpose
The
flowmesh stackCLI hardcoded the compose project name, container names, network name, and named volumes. Two contributors sharing a single host could not bring up independent stacks side-by-side: the secondflowmesh stack upwould either reuse the first stack's containers and volumes or fail outright on name collisions. This PR templates every stack-managed Docker object name behind an opt-inFLOWMESH_STACK_SUFFIX, so a fresh suffix yields a fully isolated stack.Changes
cli/stack/src/flowmesh_cli_stack/assets/compose.yml— template the compose project name, allcontainer_namefields, the network, and every named volume on${FLOWMESH_STACK_SLUG:-flowmesh_node}; defaultWORKER_RESULTS_DIRto the slug-scoped volume so the server can mount the worker's results.cli/stack/src/flowmesh_cli_stack/utils.py— add_resolve_stack_suffix(sanitizes the user-supplied suffix to a Docker-safe token, capped at 48 chars) andapply_stack_resource_env(resolves the slug, setsCOMPOSE_PROJECT_NAME/FLOWMESH_STACK_SLUG, and defaultsWORKER_RESULTS_DIRwhen empty).cli/stack/src/flowmesh_cli_stack/stack.py— callapply_stack_resource_envfrom the stack loader so every compose invocation inherits the resolved slug.cli/stack/src/flowmesh_cli_stack/env_schema.py+assets/.env.example— registerFLOWMESH_STACK_SUFFIXand drop the hardcodedflowmesh_resultsdefaults fromSERVER_RESULTS_DIR/WORKER_RESULTS_DIRso they fall back to the slug-scoped volume.docs/CLI.md,docs/ENV.md— document the multi-stack workflow and the suffix knob.tests/cli/test_stack_utils.py— cover the empty / sanitized / invalid suffix paths and theWORKER_RESULTS_DIRdefault..github/workflows/security.yml+docs/CODE_STYLE.md— extend the pip-audit ignore list (and rationale table) for four new pillow advisories (GHSA-wjx4-4jcj-g98j,GHSA-5xmw-vc9v-4wf2,GHSA-r73j-pqj5-w3x7,GHSA-pwv6-vv43-88gr); all four require pillow ≥ 12.2.0, blocked by the existinggradio 5.50cap held byvllm-omni 0.18.Design
FLOWMESH_STACK_SUFFIXis the user-facing knob;apply_stack_resource_envresolves it once intoFLOWMESH_STACK_SLUGandCOMPOSE_PROJECT_NAME, which compose then interpolates into every templated name. An empty suffix keeps the historicalflowmesh_nodename, so single-stack users see no change.The suffix is sanitized at the CLI boundary (punctuation →
-, runs collapsed, capped at 48 chars) so arbitrary user input still produces valid Docker names; a suffix that sanitizes to empty fails fast with an actionableValueErrorinstead of an opaque compose error.WORKER_RESULTS_DIRis defaulted in Python rather than in compose, because the server reads it at runtime and needs the actual slug-scoped volume name, not a compose-key alias.SERVER_RESULTS_DIRkeeps its compose-key fallback since it is consumed only by compose itself.Test Plan
uv run pre-commit run --all-filesuv run pytest tests/Test Result
pre-commitpasses on the changed files.uv run pytest tests/.flowmesh stack cleanwhile the first keeps running, and the workflow submitted against the first stack runs to completion before the final teardown.Pre-submission Checklist
pre-commit run --all-filesand fixed any issues.uv run pytest tests/passes locally.uv sync --all-extras --frozen).[BREAKING]and described migration steps above.