feat(services): add per-service Docker resource limits#53
Conversation
Mirror CashPilot #95 (2026-07-05 fleet OOM remediation): declare an
optional docker.resources block (mem_limit, mem_reservation,
oom_score_adj) in the service YAML and apply it on the container
HostConfig at creation, so earner memory ceilings and OOM-kill priority
are durable across restarts instead of set out-of-band.
- catalog: parse docker.resources into DockerConfig.Resources
(OomScoreAdj is *int so absent is distinguishable from an explicit 0)
- runtime: set HostConfig Memory / MemoryReservation / OomScoreAdj from
the block when present; memory-swap left unset. Binary-unit size
parsing ("768m" = 768 MiB, "2g" = 2 GiB) matching docker --memory
- services: protect storj (2g) / mysterium (768m) / anyone-protocol
(1536m) with negative oom_score_adj; cap expendable earners (128-256m)
with positive scores so the kernel reaps them first under pressure
- tests: size parsing, HostConfig application, and YAML parse
|
Warning Review limit reached
Next review available in: 37 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (20)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #53 +/- ##
==========================================
+ Coverage 62.81% 63.41% +0.60%
==========================================
Files 8 8
Lines 1826 1867 +41
==========================================
+ Hits 1147 1184 +37
- Misses 597 601 +4
Partials 82 82
🚀 New features to boost your workflow:
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
Mirrors CashPilot #95 — part of the 2026-07-05 fleet OOM remediation. Makes per-service earner memory limits durable in the Desktop app by declaring them in the service YAML and applying them on the Docker
HostConfigat container creation. Previously containers were created with no memory ceiling, so a leaking earner could OOM the host.What changed
Schema + data model
services/_schema.yml: documents an optionaldocker.resourcesblock —mem_limit(e.g."768m"/"2g"), optionalmem_reservation, andoom_score_adj(int, -1000..1000).internal/catalog: parses it intoDockerConfig.Resources.OomScoreAdjis a*intso an absent value is distinguishable from an explicit0and is applied only when present.Apply on the container (
internal/runtime)Deploy()now callsapplyResourceLimits(hostConfig, svc.Docker.Resources)right beforeContainerCreate.HostConfig.Memory,HostConfig.MemoryReservation, andHostConfig.OomScoreAdj— each only when present in the YAML.memory-swapis deliberately left unset (Docker derives it fromMemory).parseMemoryBytesconverts Docker-style size strings using binary units ("768m"= 768 MiB,"2g"= 2 GiB), matchingdocker run --memory/ composemem_limit. A malformed size fails the deploy fast rather than running the earner unbounded.Service limits (same values as #95, for the services that exist in this repo):
2g-1001536m-100768m-100256m300256m200128m200128m300Protected storage/VPN services get a negative
oom_score_adj; expendable bandwidth earners get positive scores so the kernel reaps them first under memory pressure. The other 34 catalog services are untouched.Tests
parseMemoryBytes: binary units, trailingb, mixed case, whitespace, fractional mantissa, and rejection of empty/non-positive/garbage inputs.applyResourceLimits: values land onHostConfig;memory-swapstays unset; an absent block leaves defaults; a malformed size errors without mutatingHostConfig.docker.resourcesparses from YAML; a service without the block leaves the fields zero/nil.gofmt -lclean ·go vet ./...clean ·go test -race -covermode=atomic ./...green (all 8 packages). Also verified the 15 real service YAMLs load to the exact intended values through the real catalog parser.