Skip to content

Commit 37341d1

Browse files
sijieclaude
andcommitted
fix: remove the unnamed volumes the local stacks left behind
`docker compose down` keeps the unnamed volumes that the Kafka and RustFS images declare, and the next `up` creates new ones. Each `local/down.sh` and restart left four more empty volumes, and each `local/engine.sh` one more: nine after one pass through the course. `local/down.sh` now removes the containers with `rm --volumes` before `down`, and `local/engine.sh` removes the engine's stopped containers with `--volumes`. Named volumes hold the data and are not touched: after a stop and a start, the topic, the view and the table are still there. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Nq3n2MeC9XrC31wYfdjZv
1 parent 3a7c263 commit 37341d1

3 files changed

Lines changed: 60 additions & 3 deletions

File tree

‎local/down.sh‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,22 @@ if [ -n "$mcp" ]; then
2929
fi
3030

3131
# The engine. `down` by project name also removes the gateway, and needs no file.
32+
# Without --reset, `rm --volumes` goes first: `down` alone keeps the unnamed
33+
# volumes that some images declare, and the next start makes new ones beside
34+
# them. Your data is in named volumes, which `rm --volumes` does not touch. It
35+
# is quiet and may fail: `down` stops whatever it left.
3236
if $reset; then
3337
docker compose --progress quiet --project-name "$project" down -v --remove-orphans
3438
else
39+
docker compose --progress quiet --project-name "$project" rm --stop --force --volumes >/dev/null 2>&1 || true
3540
docker compose --progress quiet --project-name "$project" down --remove-orphans
3641
fi
3742

3843
# The streaming stack.
3944
if $reset; then
4045
streaming down -v --remove-orphans
4146
else
47+
streaming rm --stop --force --volumes >/dev/null 2>&1 || true
4248
streaming down --remove-orphans
4349
fi
4450

‎local/engine.sh‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,12 @@ start_engine() {
6969
# Replace what is not running. A container whose port could not be bound
7070
# (another program had it) stays cut off from its network: Docker starts it
7171
# with loopback only from then on, even once the port is free (seen with
72-
# Docker Engine 29.2). The engine's data is in volumes, so nothing is lost.
72+
# Docker Engine 29.2). The engine's data is in named volumes, so nothing is
73+
# lost: `--volumes` takes only the unnamed ones an image declares, which would
74+
# otherwise be left behind at every start.
7375
local name
7476
while IFS= read -r name; do
75-
[ -z "$name" ] || docker rm "$name" >/dev/null
77+
[ -z "$name" ] || docker rm --volumes "$name" >/dev/null
7678
done < <(engine_stopped_containers)
7779
ork local --data-dir "$ORK_DIR" start --with-gateway
7880
}

‎local/tests/run.sh‎

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,13 @@ case "$1" in
5353
;;
5454
exec) cat "$FAKE_DOCKER_DIR/provider-status" 2>/dev/null ;; # the harness asks the provider
5555
run) ;; # curl on the engine's network: the MCP server answers
56-
compose) ;;
56+
compose)
57+
# `rm` can be made to fail, noisily: stopping must not depend on it.
58+
if [[ " $* " == *" rm "* && -f "$FAKE_DOCKER_DIR/compose-rm-fails" ]]; then
59+
echo "No stopped containers" >&2
60+
exit 1
61+
fi
62+
;;
5763
*) exit 1 ;;
5864
esac
5965
EOF
@@ -226,6 +232,7 @@ test_engine_replaces_its_containers_that_are_not_running() {
226232
start_engine
227233
check "removes a container that never started, before the engine starts" removed_before_the_start ork-registry-1
228234
check "removes a container that has stopped, before the engine starts" removed_before_the_start ork-migrate-1
235+
check "takes each one's unnamed volumes with it" grep -qx -- "rm --volumes ork-migrate-1" "$FAKE_DOCKER_DIR/calls"
229236
check "leaves a running container alone" not removed ork-harness-1
230237
check "leaves other projects' containers alone" not removed someone-elses-container
231238
check "then starts the engine" started
@@ -240,6 +247,48 @@ test_engine_starts_when_nothing_has_stopped() {
240247
check "and starts the engine" started
241248
}
242249

250+
# ------------------------------------------------------------------ stopping --
251+
252+
asked() { grep -qE -- "$1" "$FAKE_DOCKER_DIR/calls"; } # asked <regex>: docker was asked this
253+
254+
test_stopping_keeps_your_data_and_leaves_no_unnamed_volumes() {
255+
# `down` alone keeps the unnamed volumes some images declare. Every stop and
256+
# start left four more behind.
257+
fresh_repo down
258+
engine_started
259+
run down.sh
260+
check "stopping succeeds" [ "$STATUS" -eq 0 ]
261+
check "the engine's containers go with their unnamed volumes" \
262+
asked '^compose .*--project-name ork-local-[0-9a-f]{8} rm --stop --force --volumes$'
263+
check "so do the streaming stack's" \
264+
asked '^compose .*--project-name hello-data-agent .*rm --stop --force --volumes$'
265+
check "both stacks are brought down" [ "$(grep -cE '^compose .* down --remove-orphans$' "$FAKE_DOCKER_DIR/calls")" -eq 2 ]
266+
check "no named volume is deleted" not asked ' down -v'
267+
check "says your data is kept" out_has "Your data is kept"
268+
}
269+
270+
test_stopping_does_not_depend_on_removing_unnamed_volumes() {
271+
fresh_repo down-rm-fails
272+
engine_started
273+
touch "$FAKE_DOCKER_DIR/compose-rm-fails"
274+
run down.sh
275+
check "stopping succeeds when that step fails" [ "$STATUS" -eq 0 ]
276+
check "both stacks are still brought down" [ "$(grep -cE '^compose .* down --remove-orphans$' "$FAKE_DOCKER_DIR/calls")" -eq 2 ]
277+
check "and that step's messages are not shown" [ ! -s "$R/err" ]
278+
}
279+
280+
test_reset_deletes_the_volumes_with_the_stacks() {
281+
fresh_repo down-reset
282+
engine_started
283+
printf 'TUTORIAL_STACK=local\n' >"$R/.env"
284+
run down.sh --reset
285+
check "reset succeeds" [ "$STATUS" -eq 0 ]
286+
check "the engine's volumes are deleted" asked '^compose .*--project-name ork-local-[0-9a-f]{8} down -v --remove-orphans$'
287+
check "the streaming stack's too" asked '^compose .*--project-name hello-data-agent .*down -v --remove-orphans$'
288+
check "the engine's keys go with its volumes" [ ! -e "$R/.lab/ork" ]
289+
check "and the local .env" [ ! -e "$R/.env" ]
290+
}
291+
243292
# ------------------------------------------------------ checking the engine --
244293

245294
PROVIDER_KEY=sk-ant-test-key-0123456789

0 commit comments

Comments
 (0)