Skip to content
Back to skills

Ywc Docker Isolate

ASecurity

(ywc) Use when parallel Git worktrees each run their own Docker stack and collide on host ports ("port is already allocated") — derives a deterministic per-worktree host-port block + COMPOSE_PROJECT_NAME, tears down only that worktree's stack, and audits stale stacks. Delegated from `ywc-parallel-executor` (audit/setup/teardown). Triggers: "docker port 격리", "compose 포트 충돌", "ywc-docker-isolate", "docker isolate", "worktree docker stack", "Docker ポート分離". Do not use for projects without Docker/...

  • 8 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 2, 2026
toolsgoshellbashdockergit

Works with

  • cli

Security analysis

A100/100

Pro scans all 13 files and shows the line behind each finding

Scanned September 2, 2026

npx -y skills add yongwoon/ywc-agent-toolkit --skill ywc-docker-isolate --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ywc Docker Isolate?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ywc Docker Isolate
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/yongwoon-ywc-docker-isolate/badge)](https://www.skillsdirectory.com/skills/yongwoon-ywc-docker-isolate)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ywc-docker-isolate
description: >-
  (ywc) Use when parallel Git worktrees each run their own Docker stack and
  collide on host ports ("port is already allocated") — derives a deterministic
  per-worktree host-port block + COMPOSE_PROJECT_NAME, tears down only that
  worktree's stack, and audits stale stacks. Delegated from
  `ywc-parallel-executor` (audit/setup/teardown). Triggers: "docker port 격리",
  "compose 포트 충돌", "ywc-docker-isolate", "docker isolate", "worktree docker
  stack", "Docker ポート分離". Do not use for projects without
  Docker/docker-compose (no-op), non-Docker workspace isolation, or
  `ywc-sequential-executor` (single task, no worktree port collision).
---

# ywc-docker-isolate

**Announce at start:** "I'm using the ywc-docker-isolate skill to isolate this worktree's Docker host ports."

Deterministic, per-worktree Docker host-port isolation for parallel Git worktree
development. Each worktree derives a unique port block **purely from its task
name** — no central registry, no runtime coordination — and writes it to a
worktree-local env-file plus a `.ywc-docker-ports` persist file. The committed
compose / env-file is never mutated (per-worktree namespacing, not save/restore).
The deterministic engine lives in bundled scripts; this skill is the one-line
interface to them.

## Rationalization Defense

When tempted to skip a step, check this table first:

| Excuse | Reality |
|---|---|
| "Only one worktree is active right now — isolation is unnecessary" | Isolation is unconditional in the executor hook. A second worktree may start at any time, and the deterministic block is what guarantees they never collide. Run `setup` for every task worktree. |
| "Just edit the compose `ports:` / committed `.env` to free the port" | The original compose and committed env-file are immutable (NFR-1). Isolation writes only a worktree-local env-file managed block + `.ywc-docker-ports`; mutating tracked files pollutes `git diff` and breaks the other worktrees. |
| "`ss` is enough to check whether a port is free" | `ss` is Linux-only and absent on macOS. Port checks go through the cross-platform `check_port_in_use` (`ss`→`lsof`→`netstat`, fail-safe when none exist) — never call `ss` directly. |
| "Re-running setup can just re-compute the hash to get the same ports" | Reproducibility (AC2) comes from reading back `.ywc-docker-ports`, not from re-hashing. A re-hash would drift if an external process transiently held a port. Always read back the persist file; re-hash only on first allocation. |
| "`audit` returned exit 0, so there are no leftover stacks" | `audit` exit is **always 0** — residual stacks are signalled by **non-empty stdout**, not the exit code. Parse stdout; never gate on the audit exit code. |
| "A leftover stack from a prior run is harmless — proceed" | A stale `ywc-<task>_*` stack occupies the *same deterministic port* the next run derives, so resume is guaranteed to collide. Pre-flight `audit` must fail-loud (or `--prune`) before setup. |

## Modes

The deterministic logic is in `scripts/` — invoke it with a single line per mode.
The CLI contract (arguments, writes, exit codes) is authoritative and is what
`ywc-parallel-executor` integrates against.

### `setup` — allocate and apply the port block

```bash
bash claude-code/skills/ywc-docker-isolate/scripts/setup-docker-ports.sh \
  --task-name <task> --worktree-path <dir> [--compose-file <file>] [--port-vars VAR1,VAR2]
```

- Writes a worktree-local env-file managed block (`COMPOSE_PROJECT_NAME=ywc-<sanitized-task>` + each `*_PORT`) and the `.ywc-docker-ports` persist file.
- Stdout: the resolved port map (`COMPOSE_PROJECT_NAME` + `VAR=port` lines).
- **Exit 0** = isolation applied, or no-op (no compose → "no docker — skipping isolation"). **Exit 1** = ports hardcoded (cannot isolate) / salt chain exhausted / corrupt persist / squatter live-check / sanitize-empty.
- Re-run on the same worktree reads back `.ywc-docker-ports` (deterministic, AC2) and live-checks every port before returning — a squatted port fails loud (AC13).

### `teardown` — remove only this worktree's stack

```bash
bash claude-code/skills/ywc-docker-isolate/scripts/teardown-docker.sh \
  (--task-name <task> | --project-name <proj>) --worktree-path <dir> [--keep-volumes]
```

- Runs `docker compose -p <project> down --volumes` (default; `--keep-volumes` preserves data), idempotent (exit 0 even with no running stack), deletes `.ywc-docker-ports` on success.
- **Exit 0** = teardown verified / nothing to do. **Exit 1** = `compose down` failed (`LEAKED_DOCKER_STACK` marker, wave **non-blocking**) or sanitize/malformed project (`SANITIZE_ERROR` marker, wave **blocking**). Both markers are written to **stderr** — distinguish the two by the marker string, not the exit code.

### `audit` — report leftover stacks for expected tasks

```bash
bash claude-code/skills/ywc-docker-isolate/scripts/audit-docker-stacks.sh \
  --expect <task1,task2,...> [--prune]
```

- Detects residual `ywc-<task>` stacks. **Stdout non-empty = residual present** (each line `RESIDUAL_DOCKER_STACK: <project> (<n> container(s))`); **exit is always 0**.
- `--prune` tears residual stacks down (`down --volumes`) and confirms each on stdout (`pruned residual stack: <project>`). Without `--prune`, the caller (parallel-executor Pre-flight) must fail-loud and abort the run on any residual. **Gate on stdout non-empty only when `--prune` is not passed** — the prune confirmation lines would otherwise read as residuals.

## Integration (ywc-parallel-executor)

One-line pointers only (no inline prose in the executor body):

- **Pre-flight** (after worktree audit): `audit --expect <wave tasks>` — non-empty stdout → abort run with the printed stacks + `--prune` remediation.
- **Step 4a** (after 4a-verify, per task): `setup --task-name <t> --worktree-path <wt>` — exit 1 → task BLOCKED + worktree preserved, wave continues.
- **Step 4g** (before `cleanup-worktree.sh`, inside the 4e-DONE loop): `teardown --task-name <t> --worktree-path <wt>` — preserved (BLOCKED) worktrees skip 4g, so teardown is skipped automatically.

## Common Mistakes

- Calling `ss` directly instead of the cross-platform helper — breaks on macOS.
- Gating on the `audit` exit code instead of stdout non-empty — misses every residual stack.
- Re-hashing on re-run instead of reading back `.ywc-docker-ports` — breaks AC2 determinism under transient external port use.
- Placing the teardown pointer outside the 4e-DONE loop — would tear down BLOCKED-preserved worktrees.
- Writing isolation values into the committed compose/env-file instead of the worktree-local env-file managed block — pollutes `git diff` (NFR-1).

## Validation

- `bash -n` clean on all `scripts/*.sh`.
- `setup` twice with the same `--task-name` yields an identical port map (AC2).
- Three distinct task names yield three distinct port blocks and `COMPOSE_PROJECT_NAME` values (AC1).
- `validate_ywc_skills.py` PASS; README locale set (`.md` / `.en.md` / `.ja.md` / `.ko.md`) present.

## References

> **Action required before running `setup`**: Read [references/port-allocation.md](references/port-allocation.md) for the hash formula, `var_index` sort rule, salt chain, modulo bias, and the AC2 determinism guarantee.

> **Action required before running `setup`**: Read [references/preconditions.md](references/preconditions.md) for compose detection, env-var mapping limits (short vs long syntax), the YAML parser priority, the platform port-check tool table, and the env-file vs shell-export precedence.

Files in this skill

  • README.en.md2.2 KB
  • README.es.md2.6 KB
  • README.ja.md2.3 KB
  • README.ko.md2.3 KB
  • README.md2.3 KB
  • README.zh.md2.4 KB
  • SKILL.md7.4 KB
  • references/port-allocation.md3.5 KB
  • references/preconditions.md3.7 KB
  • scripts/_lib.sh6.2 KB
  • scripts/audit-docker-stacks.sh2.4 KB
  • scripts/setup-docker-ports.sh10.7 KB
  • scripts/teardown-docker.sh2.9 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.