Dokploy / Dokploy/dokploy

Expose Swarm's pids limit (Resources.Limits.Pids) alongside memory and CPU limits

Open
#5,009 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.