Skip to content

Use tini as container init - #21

Open
ArshyaAI wants to merge 1 commit into
chrysb:mainfrom
ArshyaAI:fix-tini-entrypoint
Open

Use tini as container init#21
ArshyaAI wants to merge 1 commit into
chrysb:mainfrom
ArshyaAI:fix-tini-entrypoint

Conversation

@ArshyaAI

Copy link
Copy Markdown

This runs OpenClaw under tini so the container has a real PID 1 reaper.\n\nWhy:\n- Railway/OpenClaw cron and subprocess workflows can leave orphaned child processes.\n- With node as PID 1, adopted children can remain as defunct zombies.\n- tini is the standard minimal init for containers and forwards signals while reaping children.\n\nChange:\n- Install Debian tini in the image.\n- Use ENTRYPOINT ["/usr/bin/tini", "--"] before the existing alphaclaw start CMD.\n\nVerified on Railway by deploying the same Dockerfile shape: PID 1 became /usr/bin/tini -- alphaclaw start, healthcheck stayed healthy, and no zombie processes were present after post-deploy smoke checks.

@ArshyaAI

Copy link
Copy Markdown
Author

Deployment verification from Railway service openclaw-railway-template:\n\n- Deployed this Dockerfile shape successfully via Railway CLI upload.\n- PID 1 is now /usr/bin/tini -- alphaclaw start.\n- Healthcheck remains healthy.\n- Post-deploy process scan showed no defunct zombie processes.\n- Public OpenClaw router stayed healthy.\n\nThis fixes the observed production issue where node as PID 1 did not reap adopted child processes from cron/subprocess workflows.

@Nicholasbell03

Copy link
Copy Markdown

Strong +1 on this. Hit the same fork failure on Railway and the diagnosis matches exactly what this PR fixes.

About 67 minutes after a fresh deploy, my container had 87 defunct openclaw-pairing processes, all parented to PID 1 (node). They accumulate at roughly one per minute:

  • The gateway respawns the pairing child on a tight cadence.
  • Node, sitting at PID 1 with no SIGCHLD handler, never wait()s on them.
  • Railway pins cgroup pids.max to 1000.

Combined with ~100 live processes, the container exhausts its PID slots in 13–14 hours after each restart. After that, every fork() in the cgroup returns EAGAIN, which is where "cannot fork on every shell command" comes from. It also explains why alphaclaw self-update and the cron jobs silently start failing around the same window, and why a restart appears to "fix" it (clears the zombies, cycle resets).

A few older closed issues look like the same root cause wearing different masks:

The patch here is the right structural fix — tini as PID 1 reaps adopted children automatically and the leak goes away. Would be great to get it merged. Every Railway deploy of this template hits this eventually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants