Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Supervisor Laravel Package

pierotto/supervisor

A Laravel package for working with Supervisor process control: generate and manage supervisor configurations, control and monitor worker processes, and simplify running queue workers and background jobs in your application.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package with Composer and publish/define its config so you have a single source of truth for the programs this app needs:

composer require pierotto/supervisor
  1. Look at the config file first. Everything of interest is the supervisor array: a group key (new in 3.1.0) and a programs map. The README's examples use Symfony's %kernel.project_dir% placeholder syntax, but the generator itself is framework-agnostic — in Laravel use base_path() / config() values instead.

  2. Define one program and generate the file. Start with a single queue worker, run the package's dump/generate command (or call SupervisorConfigGenerator directly from a small artisan command or test), and inspect the resulting .ini. Confirm the [program:...] section carries the command, log paths and restart policy you expect.

  3. Wire it into supervisor. Point supervisor's include directive at the directory where you write the generated file (/etc/supervisor/conf.d/ on most distros), then:

    supervisorctl reread
    supervisorctl update
    supervisorctl status
    
  4. Set group on day one if you share a host. This is the headline feature of 3.1.0 and is much cheaper to adopt before you have running processes than after:

    'group' => 'myapp',
    'programs' => [
        'worker' => ['command' => 'php '.base_path('artisan').' queue:work'],
    ],
    

    That emits an extra [group:myapp] section listing worker, and the process becomes addressable as myapp:worker.

First real use case: replace a hand-written .conf for a Horizon/queue worker with a generated one you can regenerate in CI and diff in code review.

Implementation Patterns

Generate at deploy time, not by hand. Treat the supervisor .ini as a build artefact. A deploy step that runs the generator and then reread + update against the app's group is the core loop:

supervisorctl stop myapp:*
# deploy: composer install, migrate, etc.
supervisorctl reread
supervisorctl update myapp
supervisorctl start myapp:*

Quote the glob if your shell would expand it (supervisorctl stop 'myapp:*').

One group per application. The group name should be stable and app-specific (myapp, myapp-staging). This is what lets several projects share a single supervisord without one project's deploy touching another's processes.

Environment-aware config. Build the program array from config() and env() rather than hardcoding paths: log directory under storage_path('logs'), numprocs from an env var, command prefixed with the correct PHP binary. Since the config is plain PHP, you get per-environment program sets for free — just make sure the generated filename and group name differ per environment so staging can't overwrite production.

Group the long-running workers, not one-shot commands. Schedule-style tasks belong in the scheduler/cron, not supervisor. Reserve programs for things that must be supervised: queue workers, websocket servers, consumers.

Program-level tuning belongs in the config array. numprocs, autorestart, stopwaitsecs, stopsignal, stdout_logfile, redirect_stderr are all normal supervisor options and should live next to the command so they're reviewable in the same diff. For workers that fork children, prefer stopasgroup/killasgroup so a stop doesn't orphan grandchildren.

Generator as a collaborator. If you need custom output (multiple files, header comments, per-program groups), instantiate SupervisorConfigGenerator yourself instead of relying on the packaged command. The 3.1.0 constructor takes the group as the last argument with a default, so existing positional instantiation keeps working and you only add the argument — or a named argument — when you want grouping.

Test the generated text. A small PHPUnit test asserting the rendered .ini contains [group:myapp] and programs = worker catches regressions from package upgrades far earlier than a broken deploy.

Gotchas and Tips

  • supervisorctl update <group> needs supervisor 3.2+. Check supervisord --version on the target host before you build the whole deploy script around group-scoped updates.
  • Adding group to an already-running project renames its processes. The old ungrouped worker still exists with the same command, and a group-scoped update will not remove it — you'll end up with duplicate workers competing for the same queue. The README documents a one-off migration; do that (stop the old ungrouped processes, remove their sections, reread, update) in the same deploy that introduces group. Do not simply add the option and redeploy.
  • Prefer group-scoped commands over stop all / reload on shared hosts. supervisorctl reload restarts the supervisord daemon itself and therefore every project on the machine. That's the exact failure mode group exists to prevent.
  • Order matters: reread then update. reread only parses the config files; update applies them. Running update alone after regenerating the file does nothing useful.
  • Upgrading to 3.1.0 is a no-op if you don't set group. It defaults to an empty string, so output is byte-for-byte identical to 3.0.0. Safe to bump and deploy without touching config.
  • A program can only be in one group. If you hand-edit generated files or stack multiple generated configs in conf.d, supervisor will complain about a program being claimed twice — usually surfaced as an error during reread. Keep one generated file per group per host.
  • Process names change with grouping. Anything scripted against supervisorctl status worker or log filenames containing the bare program name needs updating to the myapp:worker form (and worker_00 style suffixes once numprocs > 1).
  • Debug by validating the file before restarting anything. Run supervisord -n -c /path/to/generated.ini in the foreground, or watch the reread output — supervisor reports malformed sections there, and it's far better to see that than to stop every worker on the box during a deploy.
  • Watch file ownership. The generated file is written by your deploy user but read by supervisord (often root). Write to a temp file and rename, or set permissions explicitly, otherwise a partially written file can be picked up by a concurrent reread.
  • Keep log paths per program and outside the release directory (e.g. storage/logs/supervisor/). Symlinked release folders change target on each deploy, and supervisor keeps the file handle it opened at start — so logs silently land in a deleted release if you put them under the release path.
  • Extension point to watch: the group is injected through the generator's constructor. If you decorate or extend SupervisorConfigGenerator, update your subclass signature to account for the new trailing argument; it's defaulted, so you won't get a fatal error, but a subclass that reorders arguments will silently drop the group.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource