Skip to content

fix(cli): remove profile-deactivated containers before every compose up - #804

Merged
VijitSingh97 merged 1 commit into
developfrom
fix/795-profile-deactivation-containers
Aug 1, 2026
Merged

fix(cli): remove profile-deactivated containers before every compose up#804
VijitSingh97 merged 1 commit into
developfrom
fix/795-profile-deactivation-containers

Conversation

@VijitSingh97

Copy link
Copy Markdown
Collaborator

What

Reproduced #795's root cause empirically: compose up --remove-orphans never removes the container of a service whose profile just went inactive — the service is still in the compose file, so compose does not count it as an orphan (verified against compose v2 / docker 29.0.1: a profiled service's running container survives an up --remove-orphans with the profile off). A tari local→remote switch therefore left the old minotari_node running — offline, flailing, re-syncing into a reclaimed dir — against a remote-mode config. The monerod local→remote path had the same latent bug; the apply-path comment claiming --remove-orphans covered it was wrong.

compose_up_checked (the choke point apply/up/upgrade all route through) now reconciles from the committed .env before the up: every profile-gated service (monerod, tari, wallet-rpc, tari-wallet) whose profile token is absent gets compose rm -sf. That command resolves explicitly named services regardless of active profiles and exits 0 when nothing runs, so the steady state is a no-op — and a box already stuck with a stale node container (the #795 bench reproduction) heals on its next up instead of needing a manual rm -f. Removal runs BEFORE the up so the old local node never runs beside the remote-mode p2pool. On-disk chain data is untouched, exactly as the apply preview promises.

Coverage

Stack tier (tests/stack/run.sh), driven through the real apply against the docker stub's call log:

  • baseline both-nodes-local apply reconciles only the (off) payout-confirm wallets — neither node container is touched;
  • tari local→remote switch adds tari to the removal list, and the removal precedes the recreate up;
  • monero local→remote rides the same guard for monerod.

docs/configuration.md already promises "switch to remote mode and the stack won't run a local one" — this makes the code match the doc, so no doc change.

Closes #795

🤖 Generated with Claude Code

compose up --remove-orphans never removes the container of a service
whose profile just went inactive — the service is still in the compose
file, so compose does not count it as an orphan. A tari local→remote
switch therefore left the old minotari_node running (offline,
re-syncing) against a remote-mode config; monerod local→remote had the
same latent bug, and the apply-path comment claiming --remove-orphans
covered it was wrong (disproven empirically against compose v2 /
docker 29.0.1).

compose_up_checked now reconciles from the committed .env before the up:
every profile-gated service (monerod, tari, wallet-rpc, tari-wallet)
whose profile token is absent gets 'compose rm -sf'. The command
resolves named services regardless of active profiles and exits 0 when
nothing runs, so the steady state is a no-op and a box already stuck
with a stale node container heals on its next up.

Closes #795

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@VijitSingh97
VijitSingh97 merged commit 9551ac7 into develop Aug 1, 2026
15 checks passed
@VijitSingh97
VijitSingh97 deleted the fix/795-profile-deactivation-containers branch August 1, 2026 04:24
@VijitSingh97

Copy link
Copy Markdown
Collaborator Author

Two residual observations from an adversarial pass over the parallel (now-closed) #806, both applying to the merged code here:

  1. Reverse-switch coverage gap: the stack tests drive local→remote and assert the container is gone, but no case drives remote→local and asserts the freshly-reactivated profile's container comes back up in the same apply. The code path looks sound (a token present in the committed profiles is skipped by the removal, and compose recreates normally) — worth one assertion next time that file is touched.
  2. The service↔profile map is hardcoded in remove_deactivated_profile_containers. A future profile-gated service added to docker-compose.yml silently escapes removal. A drift guard in tests/stack (enumerate profiles: from the compose file and assert the map covers them, like the depends_on count guard from tier 1: assert the compose depends_on graph (edges + conditions) #565) would catch it at CI time.

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

apply leaves the deactivated-profile tari container running after a local→remote switch

1 participant