Skip to content

Zombie Process Accumulation leading to grocy API failure -> BB stops working #283

@Dannypeja

Description

@Dannypeja

Problem

BarcodeBuddy fails intermittently with "Could not connect to Grocy server" in rootless Docker environments due to zombie process accumulation exhausting PID limits.

Impact: Breaks after ~70 scans (1-2 days of use)
Cause: 2 zombie processes created per barcode scan


Evidence

Application Errors

2025-11-12 06:28:22: Could not connect to Grocy server: Could not lookup Grocy barcodes

This is probably due to no process being available for the simple curl or DNS lookup of grocy-url/api/

Kernel Logs

$ dmesg -T | grep fork
cgroup: fork rejected by pids controller

Zombie Accumulation

$ docker top barcodebuddy | grep defunct
299  1  Zs  [screen] <defunct>
302  1  Zs  [php] <defunct>
389  1  Zs  [screen] <defunct>
391  1  Zs  [php] <defunct>
477  1  Zs  [screen] <defunct>
479  1  Zs  [php] <defunct>
566  1  Zs  [screen] <defunct>
568  1  Zs  [php] <defunct>

After 4 scans: 8 zombies (2 per scan: screen + php)
All zombies have PPID=1 (not being reaped by supervisor)

PID Exhaustion

$ cat /sys/fs/cgroup/.../pids.current
170
$ cat /sys/fs/cgroup/.../pids.max
171

Container at capacity → fork() fails → DNS resolution fails → Grocy API unreachable


Why Only Rootless Docker?

Docker Mode PID Limit Result
Rootful 4,194,304 Bug hidden (would take years)
Rootless ~171 (systemd limit) Breaks in 1-2 days

This was the case on a raspberry pi zero 2.


Suspected Source

File: example/grabInput.sh line 151

sudo -H -u $WWW_USER /usr/bin/screen -dm /usr/bin/php "$SCRIPT_LOCATION" $enteredText

The screen -dm spawns detached processes that become zombies when they exit. Pattern matches exactly: 2 zombies per scan (screen + php), both PPID=1.

Potential fix: Using & instead of screen -dm might resolve this, as the parent process could then properly reap the child when it exits:

sudo -H -u $WWW_USER /usr/bin/php "$SCRIPT_LOCATION" $enteredText &

Verification Steps

Check for zombies:

docker top barcodebuddy | grep defunct | wc -l

Monitor PID growth:

watch 'docker stats --no-stream barcodebuddy --format "PIDs: {{.PIDs}}"'

PIDs should stay constant (~30). If growing by 2 per scan → zombie leak confirmed.


Temporary Workaround

For rootless Docker users experiencing this:

Increase PID limits:

# /etc/systemd/system/user-.slice.d/override.conf
[Slice]
TasksMax=2048
# docker-compose.yml
services:
  barcodebuddy:
    pids_limit: 750

Auto-restart to clear zombies:

# Timer to restart every 2 days
# /etc/systemd/system/barcodebuddy-restart.timer
[Timer]
OnCalendar=*-*-1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31 02:00:00

This buys time but doesn't fix root cause.


Environment: Rootless Docker, systemd with TasksMax limits, cgroups v2
Reproducibility: 100% in rootless Docker with PID constraints
Affected Repos: Forceu/barcodebuddy (grabInput.sh), forceu/barcodebuddy-docker (uses script)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions