RCA-2026-03-17-001: Kroki Orphan Containers

Executive Summary

Kroki diagram rendering containers (4 total) were found running 13+ hours after an Antora build, consuming system resources. Root cause: direct builds from spoke repos (domus-captures) bypass the domus-docs Makefile which has auto-stop logic. Resolution: manual cleanup with docker stop via xargs pattern, plus documentation of the cleanup command.

Timeline

Time Event

2026-03-16 ~18:00

Antora build executed (likely from domus-captures or direct npx)

2026-03-17 07:58

Containers still running 13+ hours later

2026-03-17 08:15

Discovered via docker ps

2026-03-17 08:16

Cleanup executed via xargs pattern

Problem Statement

Symptoms

  • docker ps showed 4 Kroki containers running:

    • domus-kroki (main)

    • domus-kroki-bpmn

    • domus-kroki-excalidraw

    • domus-kroki-mermaid

  • All containers up for 13+ hours

  • Unnecessary resource consumption

Expected Behavior

Kroki containers should stop automatically after Antora build completes.

Actual Behavior

Containers remained running indefinitely.

Root Cause

5 Whys Analysis

Why # Question and Answer

1

Why were containers still running?
Because: No stop command was issued after the build.

2

Why was no stop command issued?
Because: Build was run outside of domus-docs Makefile.

3

Why was build run outside domus-docs?
Because: User ran npx antora or build from spoke repo directly.

4

Why doesn’t spoke repo stop containers?
Because: Only domus-docs Makefile has kroki-stop target.

5

Why isn’t this documented?
Because: Assumption that all builds go through domus-docs.

Root Cause Statement

Kroki containers are started by Antora but only stopped by the domus-docs Makefile. Direct builds from spoke repos or npx antora commands leave containers orphaned.

Resolution

Immediate Actions

Cleanup command using xargs:

# List running Kroki containers
docker ps --filter "name=domus-kroki"

# Stop all Kroki containers in one command
docker ps -q --filter "name=domus-kroki" | xargs docker stop

xargs Pattern Breakdown

docker ps -q --filter "name=domus-kroki" | xargs docker stop
#         β”‚                  β”‚                 β”‚
#         β”‚                  β”‚                 └─ xargs: pass container IDs as args to docker stop
#         β”‚                  └─ filter: only containers matching "domus-kroki"
#         └─ -q: quiet mode, output only container IDs

Why xargs here:

  • docker stop accepts multiple container IDs

  • xargs batches the IDs from stdin into a single command

  • Avoids loop: for id in $(docker ps -q …​); do docker stop $id; done

  • One process instead of N processes

Alternative (explicit names)

docker stop domus-kroki domus-kroki-bpmn domus-kroki-excalidraw domus-kroki-mermaid

Less flexible - requires knowing all container names.

Verification

docker ps --filter "name=domus-kroki"
# Should return empty (no containers)

Preventive Measures

Short-term

Action Owner Status

Document cleanup command in CLAUDE.md

Evan

[x] Done (this RCA)

Add alias for quick cleanup

Evan

[ ] Pending

Suggested alias:

alias kroki-stop='docker ps -q --filter "name=domus-kroki" | xargs -r docker stop'

Note: -r prevents xargs from running if input is empty.

Long-term

Action Owner Status

Add kroki-stop to spoke repo Makefiles

Evan

[ ] Pending

Consider using --rm flag when starting containers

Evan

[ ] Investigate

Detection

How was it detected?

Manual observation via docker ps.

Detection Gap

Could add periodic check:

# Add to cron or shell startup
docker ps --filter "name=domus-kroki" --format "WARNING: {{.Names}} running for {{.RunningFor}}" | grep -q "hours\|days" && echo "Orphan Kroki containers detected"

Lessons Learned

What went well

  • Quick identification via docker ps

  • Clean one-liner solution with xargs

Key Takeaways

  1. xargs converts stdin to arguments - perfect for docker stop which takes multiple IDs

  2. Filter patterns - --filter "name=pattern" targets containers by name prefix

  3. Build hygiene - always use Makefile targets that include cleanup

  4. -q for IDs only - many docker commands have quiet mode for scripting

CLI Mastery: xargs Patterns for Docker

# Stop containers by pattern
docker ps -q --filter "name=prefix" | xargs docker stop

# Remove stopped containers by pattern
docker ps -aq --filter "name=prefix" | xargs docker rm

# Remove images by pattern
docker images -q "*/pattern*" | xargs docker rmi

# Prune with confirmation bypass
docker ps -q --filter "status=exited" | xargs -r docker rm

# Parallel stop (faster for many containers)
docker ps -q --filter "name=prefix" | xargs -P 4 -I {} docker stop {}

Metadata

Field Value

RCA ID

RCA-2026-03-17-001

Author

Evan Rosado

Date Created

2026-03-17

Status

Final

Category

Operations / Container Management