Docker daemon CPU saturation after redeploy while Logs tab is open
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 37.4k
- Forks
- 3k
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 73
Description
To Reproduce
- Open an application's Logs tab in Dokploy.
- Redeploy or restart that same application while the Logs tab is open.
- Close the Logs tab after the new container has replaced the old container.
- Monitor the host's processes with
pidstat,top, orhtop.
This was observed twice on the same single-node Docker Swarm host. It may depend on JSON log rotation/container replacement timing.
Current vs. Expected behavior
Current behavior
After the container is replaced, one or more Docker log requests started by Dokploy remain active even after the browser Logs tab is closed. The Docker daemon then consumes most of the host CPU indefinitely.
In the latest occurrence:
dockerdsustained approximately 314% CPU on a four-core host.- The affected application was using approximately 1-3% CPU during direct sampling.
- Other containers were mostly idle.
- Closing the browser tab did not recover the CPU.
- Restarting only the Dokploy service immediately reduced
dockerdto approximately 18% CPU average, without restarting application containers.
A SIGUSR1 Docker daemon stack dump showed many log-reader goroutines, including:
github.com/docker/docker/api/server/httputils.WriteLogStream
github.com/docker/docker/daemon/logger/loggerutils.tailFiles
github.com/docker/docker/daemon/logger/jsonfilelog.getTailReader
github.com/docker/docker/pkg/tailfile.(*scanner).Scan
Several hot goroutines were repeatedly executing pread while resolving the last 300 lines across current and rotated *-json.log files. Some offsets were already beyond the current file size.
Expected behavior
Closing or navigating away from the Logs tab, and replacing the selected container, should cancel and terminate all associated server-side log commands. No Docker log reader should remain indefinitely or saturate the Docker daemon.
Provide environment information
Dokploy: v0.29.12
Docker Engine: 28.5.0
Docker API: 1.51
Kernel: Linux 6.8.0-134-generic x86_64
Deployment: Self-hosted, single-node Docker Swarm
Dokploy and applications: Same server
Logging driver: json-file
Which area(s) are affected?
Docker, Application, Docker Compose, Logs UI
Additional context
Dokploy's current getContainerLogs() implementation executes docker container logs --timestamps --tail ... and awaits the command:
There does not appear to be a timeout or abort/cancellation path around this command. If Docker's tail scanner gets stuck during container replacement or log rotation, the in-flight command can survive after the UI stops requesting new logs.
Potential safeguards:
- Apply a bounded timeout to every
docker logscommand. - Terminate the child process when the HTTP/tRPC request is cancelled or disconnected.
- Cancel outstanding log requests when the selected container is removed/replaced.
- Avoid overlapping polling requests for the same container.
Workaround
- Close Dokploy Logs tabs before redeploying.
- If
dockerdremains hot, restart only the Dokploy service to terminate the orphaned log commands. - A full Docker daemon restart was not required in the latest occurrence.
Related issues
Issue #4661 also reports high CPU, but appears unrelated: it concerns a TimeoutNegativeWarning loop in the Dokploy Node.js process. In this report, the hot process was dockerd, and the stack dump directly identified Docker log-tail readers.
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/services/docker.ts, especially getContainerLogs() at lines 357-417, and inspect how the docker container logs command is created and awaited. Trace request cancellation during Logs-tab closure and container replacement; done means associated log commands terminate instead of leaving Docker log readers running indefinitely or saturating dockerd.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, typescript
- Domain
- backend, devops
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100