francodacosta/supervisord
PHP client for Supervisord's XML-RPC API that lets you start, stop, restart and inspect supervisor programs and processes, read logs, and check status from Laravel or any plain PHP application.
Architecture fit. The package is a narrow, single-purpose generator: it models supervisord [program:*] blocks in PHP objects and renders them to INI. It slots into a Laravel codebase as a library, not a framework integration — there is no service provider, no config publishing, no facade. That is a good shape for our use case, because the natural insertion point is an Artisan command (supervisor:render) that runs at deploy time and writes to conf.d, keeping generated config a build artifact rather than runtime state. Where this earns its place is any topology where program definitions are dynamic: per-tenant worker pools, per-queue program fan-out, environment-specific numprocs, or log paths derived from app config. If our supervisor config is a single static file with three worker programs, this package is net-negative complexity — we should hand-write fifteen lines of INI.
Integration feasibility. Composer-installable with no dependents in the wild, which cuts both ways: trivial to add, and no evidence of anyone running it in production. The integration surface is small (likely composer require, instantiate a supervisor/program object, call a render or write method), so a spike is 2–4 hours, not a sprint. The real feasibility questions are environmental, not code-level: writing into /etc/supervisor/conf.d requires root or a sudoers rule for the deploy user, and the package has no opinion on that.
Technical risk. Three concerns, in order:
environment= line is an injection vector — a newline in a queue name can emit arbitrary supervisord directives. This is not a CVE-class issue for us, but it is a correctness and blast-radius issue, since a malformed file can break supervisord's config parse for the whole include directory. The package's escaping behavior must be read from source, not assumed.numprocs, process_name=%(program_name)s_%(process_num)02d, environment, stopwaitsecs, user, redirect_stderr, stdout_logfile_maxbytes, and group blocks. If these are missing we are patching a fork to wrap a template engine — at which point writing our own Blade template is cheaper.Key questions. What PHP versions are supported and when was the last release? Does it write files or return strings? How does it escape values in command= and environment=? Does it handle secret-bearing env vars, and does it set file permissions on output? Is there any test suite covering INI output? What is the license, and can we fork it internally? Does it model groups and includes, or only flat programs?
Stack fit. Good for the generator role, poor for anything beyond it. Keep it strictly at the render boundary: our config (config/supervisor.php) is the source of truth, the package produces INI text, and our own thin service handles file writes, permissions, and supervisorctl reread && update. Do not let the package's objects leak into application code.
Migration path. Start behind a feature flag with dual output: generate configs to a staging path and diff them against the hand-maintained INI in the repo. Run that in CI for a week; any diff is either a bug in our config model or an undocumented behavior in the package, and both are worth knowing before cutover.
Compatibility. Pin the exact version in composer.json. If the PHP constraint excludes our runtime, fork to internal/php-supervisord under our VCS and require it via a vcs repository entry — this is the likely outcome and should not be treated as a surprise. Confirm the supervisord version on our hosts (3.x vs 4.x) matches the directive set the package emits.
Sequencing.
supervisor:generate command with a --check dry-run mode and explicit permission handling (0640, root-owned).reread/update, gated on a successful supervisorctl status.Maintenance. Effectively zero upstream velocity, so we own the code. Budget a few hours per year for PHP-version bumps and supervisord directive drift, plus the initial fork cost. This is acceptable only because the artifact is a text file — the failure mode of an unmaintained library here is a broken config, not a broken runtime.
Support. No community, no dependents, no issue history to mine. Internal documentation and a named owner are mandatory. Anyone debugging a supervisor problem at 2 a.m. will not find help online for this package specifically.
Scaling. This is where the package pays off: generating N programs for N queues or tenants from config scales linearly in code and removes a class of copy-paste drift. The operational cost shifts to reload behavior — supervisorctl update restarts changed programs, killing in-flight jobs. stopwaitsecs must exceed our longest job's graceful shutdown, and deploys should be sequenced so config reload happens after workers drain.
Failure modes.
supervisorctl reread gate that fails the deploy loudly.environment= lines will contain DB passwords and API keys. Files must be 0640 root:root, never world-readable, and never written into the repo or a build artifact. This is the highest-severity operational risk in the whole integration.conf.d writes surface only at deploy time; test on a real host, not in a container that runs as root by default.user, or supervisord will fail to start the program.Ramp-up. Low. The API is small enough to read in an afternoon, but the team needs working supervisord knowledge — reread vs update vs restart, process naming, and log rotation — to operate it safely. Plan half a day of knowledge transfer and a runbook covering config regeneration, rollback to the previous INI, and recovery from a failed parse.
How can I help you explore Laravel packages today?