Devcontainer Cleanup
Date: 2026-02-18
Issue: claw/research#5
Status: Verified findings
Problem Statement
A small team sharing a Linux development server uses VSCode Remote Development with devcontainers. The devcontainers run indefinitely, causing the server to gradually fill up until the OOM killer activates and performance degrades.
Research Question: What options exist for reaping long-running devcontainers while keeping resource usage within bounds?
Findings
Finding 1: DevContainer Shutdown Action Configuration
DevContainer behavior when VSCode closes is controlled by the shutdownAction property in devcontainer.json.
| Value | Behavior | Best For |
|---|---|---|
none |
Container continues running | Persistent dev environments |
stopContainer |
Stops the container on close | Single-container projects |
stopCompose |
Stops Docker Compose services | Multi-service projects |
Current Defaults:
- Image/Dockerfile-based: defaults to
stopContainer - Docker Compose-based: defaults to
stopCompose
Verification:
- VSCode Documentation confirms these options1
- Multiple GitHub issues confirm the behavior, though some report inconsistent results across VSCode versions23
Finding 2: Resource Limits via runArgs
Memory and CPU constraints can be enforced at container creation time via the runArgs property in devcontainer.json.
Configuration Example:
Available Limits:
| Flag | Description | Verfied |
|---|---|---|
--memory |
Hard memory limit | ✅ Via Docker cgroups4 |
--memory-swap |
Total memory + swap limit | ✅ Docker docs5 |
--cpus |
CPU quota (e.g., 2.0 = 2 cores) | ✅ StackOverflow6 |
--pids-limit |
Process ID limit | ✅ Docker docs5 |
--shm-size |
Shared memory size | ✅ Community usage7 |
Warning: Docker uses Linux cgroups v1 or v2 for enforcement. Soft limits may not prevent OOM if the kernel is under pressure5.
Finding 3: Docker-Level Automatic Cleanup
Server-side cleanup can be automated using Docker’s built-in prune commands combined with scheduling.
Option A: Periodic Container Prune (Cron)
Effect: Removes containers that have been stopped for 48+ hours8.
Option B: Systemd Timer for Cleanup
Effect: Triggers cleanup daily via systemd910.
Option C: Label-Based Selective Cleanup
Recommendation: Use labels to identify devcontainers and prune only those older than a defined idle threshold.
Finding 4: Idle Detection and Auto-Stop
DevContainers themselves have no built-in idle timeout, but external tooling can provide this.
Approach: Process Activity Monitoring
A script can monitor container activity and stop idle containers:
Note: This is a custom implementation; no native DevContainer idle timeout exists11.
Finding 5: Per-User Resource Accounting
For multi-user shared servers, consider Docker user namespaces or cgroups v2 for per-user resource limits.
| Approach | Description |
|---|---|
| Docker user namespaces | Isolate containers per UID range |
| cgroups v2 (Linux 5.2+) | Per-user resource limits |
| Systemd slice limits | Apply resource caps per user session |
Recommendations
Immediate Solutions (Low Effort)
- Set
shutdownAction: stopContainerindevcontainer.jsonfor non-persistent work - Add resource limits via
runArgsto cap memory per container - Schedule nightly prune of stopped containers older than 24 hours
Comprehensive Solution (Medium Effort)
-
Server-side systemd timer that:
- Stops containers idle for >4 hours
- Removes stopped containers after 24 hours
- Prunes unused images weekly
-
DevContainer template with resource limits pre-configured:
-
Monitoring dashboard showing per-container resource usage
Long-term Solution (Higher Effort)
- Migrate to Kubernetes-based dev environments (e.g., Gitpod, DevPod) with built-in resource quotas
- Implement cgroups v2 with per-user limits on the shared server
References
Verification Summary
| Finding | Source Type | Status |
|---|---|---|
| shutdownAction options | Official Docs | ✅ Verified |
| Resource limits via runArgs | Community + Docs | ✅ Verified |
| Docker prune commands | Official Docs | ✅ Verified |
| cgroups enforcement | Docker Docs | ✅ Verified |
| Idle auto-stop | Not native | ⚠️ Requires custom implementation |
Document Revision: 1.0
Next Steps: Implement recommendations per team preference (immediate vs comprehensive approach)
-
VSCode Dev Containers Documentation - shutdownAction: https://code.visualstudio.com/docs/devcontainers/containers ↩︎
-
GitHub Issue #8991 - DevContainers wont shutdown: https://github.com/microsoft/vscode-remote-release/issues/8991 ↩︎
-
StackOverflow - shutdownAction behavior: https://stackoverflow.com/questions/70645618 ↩︎
-
Docker Resource Constraints: https://docs.docker.com/engine/containers/resource_constraints/ ↩︎
-
Docker Memory Limits via cgroups: https://fabianlee.org/2020/01/18/docker-placing-limits-on-container-memory-using-cgroups/ ↩︎ ↩︎ ↩︎
-
StackOverflow - DevContainer memory limits: https://stackoverflow.com/questions/58521691 ↩︎
-
DevContainer Spec - runArgs: https://containers.dev/implementors/json_reference/ ↩︎
-
Docker Container Prune Docs: https://docs.docker.com/reference/cli/docker/container/prune/ ↩︎
-
Docker Tip #32 - Automatic Cleanup: https://nickjanetakis.com/blog/docker-tip-32-automatically-clean-up-after-docker-daily ↩︎
-
Systemd Timer Approach: https://medium.com/@123rpv/optimizing-docker-with-systemd-6a2b90c5d900 ↩︎
-
GitHub Issue #640 - Resource specification request: https://github.com/microsoft/vscode-dev-containers/issues/640 ↩︎