Expose Swarm's pids limit (Resources.Limits.Pids) alongside memory and CPU limits
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 37.4k
- Forks
- 3k
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 73
Description
Summary
Applications expose memoryLimit / cpuLimit, which map to TaskSpec.Resources.Limits.{MemoryBytes,NanoCPUs}. Docker Swarm also supports Resources.Limits.Pids (docker service create --limit-pids, API 1.41+), but Dokploy has no field for it, so there is no supported way to bound the number of processes a service may create.
Why this matters
The use case is running untrusted or semi-trusted code — an analysis/CI sandbox, a plugin runner, anything that executes user-supplied work. Memory and CPU limits do not stop a fork bomb from exhausting the host's PID space, which affects every other container on the node, not just the offending one.
Why the existing lever isn't a substitute
ulimitsSwarm is exposed and it's tempting to use nproc for this. It does not work reliably, and the failure is silent:
RLIMIT_NPROC is counted by the kernel per real uid, across the entire system. Docker does not remap uids unless userns-remap is enabled, so a container whose job account sits at the distro default (uid 1000) shares its process budget with the host's own first user and with every other container process at uid 1000. Those processes are invisible from inside the container but are counted by the kernel.
Concretely: an nproc cap validated cleanly on a dev machine (where nothing else runs at uid 1000) and then starved legitimate work on a production VPS (where plenty does). The effective headroom is unknowable from inside the container and varies with unrelated host load. It's possible to work around by allocating a uid outside the host's range, but that's a per-image workaround for something the orchestrator can express directly and per-container.
Resources.Limits.Pids is a cgroup limit scoped to the container, so it has none of that coupling.
Suggested change
The builder currently reads roughly:
// packages/server/src/utils/docker/utils.ts (~line 545)
return {
Limits: {
MemoryBytes: memoryLimit ? Number.parseInt(memoryLimit) : undefined,
NanoCPUs: cpuLimit ? Number.parseInt(cpuLimit) : undefined,
},
Reservations: { ... },
};
Adding Pids: pidsLimit ? Number.parseInt(pidsLimit) : undefined alongside the existing two, plus a nullable pidsLimit column and the matching form field, would follow the pattern already established by memoryLimit/cpuLimit (and by ulimitsSwarm for the schema/UI side).
Note Pids is a limit only — Swarm has no pids reservation — so it belongs under Limits and has no Reservations counterpart.
Environment
Dokploy v0.29.8 (checked against v0.29.14 release notes; no pids field found).
Happy to put up a PR if this approach looks right to you.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/server/src/utils/docker/utils.ts around line 545 and trace the existing memoryLimit and cpuLimit handling. Then follow the schema and form patterns used by those fields and ulimitsSwarm. Done means a nullable pidsLimit field is exposed and persisted, the form accepts it, and Swarm task limits include it without adding a reservation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, typescript
- Domain
- devops
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100