crazy-goat / workerman-bundle
Symfony bundle providing a Workerman runtime for high-performance long-running HTTP servers, with built-in task scheduler, process supervisor, PHAR packaging, and event-loop integration.
Package info
github.com/crazy-goat/workerman-bundle
Type:symfony-bundle
pkg:composer/crazy-goat/workerman-bundle
Requires
- php: ^8.2
- ext-pcntl: *
- ext-posix: *
- psr/log: ^3.0
- symfony/config: ^6.4|^7.0|^8.0
- symfony/console: ^6.4|^7.0|^8.0
- symfony/dependency-injection: ^6.4|^7.0|^8.0
- symfony/deprecation-contracts: ^2.5|^3.0
- symfony/event-dispatcher: ^6.4|^7.0|^8.0
- symfony/event-dispatcher-contracts: ^2.5|^3.0
- symfony/http-foundation: ^6.4|^7.0|^8.0
- symfony/http-kernel: ^6.4|^7.0|^8.0
- symfony/runtime: ^6.4|^7.0|^8.0
- symfony/service-contracts: ^2.5|^3.0
- workerman/workerman: ^5.0
Requires (Dev)
- dragonmantank/cron-expression: ^3.4
- guzzlehttp/guzzle: ^8.2
- php-cs-fixer/shim: ^3.75
- phpbench/phpbench: ^1.2
- phpstan/phpstan: 2.2.16
- phpunit/phpunit: ^10.4
- rector/rector: 2.6.2
- symfony/framework-bundle: ^6.4|^7.0|^8.0
- symfony/yaml: ^6.4|^7.0|^8.0
Suggests
- ext-event: For better performance
- ext-inotify: For effective file monitoring
- ext-zip: For workerman:build:bin (unpacking the downloaded SFX archive)
- dragonmantank/cron-expression: For parse cron expressions
- symfony/mime: For MIME type auto-detection in binary file responses
Provides
None
Conflicts
None
Replaces
None
- dev-master
- v0.31.0
- v0.30.0
- v0.29.0.x-dev
- v0.29.0
- v0.28.0.x-dev
- v0.28.0
- v0.27.0.x-dev
- v0.27.0
- v0.26.0.x-dev
- v0.26.0
- v0.25.0
- v0.24.1
- v0.24.0
- v0.23.0
- v0.22.0
- v0.21.0
- v0.20.0
- v0.19.0
- v0.18.0
- v0.17.0
- v0.16.0
- v0.15.0
- v0.14.0
- v0.13.0
- v0.12.0
- v0.11.0
- v0.10.0
- v0.9.9
- v0.9.8
- v0.9.7
- v0.9.6
- v0.9.5
- v0.9.4
- v0.9.3
- v0.9.2
- v0.9.1
- v0.9.0
- dev-process/0688-kb-retro-dec-013-dec-014
- dev-docs/issue-641-changelog-release-notes
- dev-fix/issue-583-cookie-url-decode
- dev-docs/workflow-gh-issue-limit
- dev-fix/issue-571-connection-timers-cancel-on-close
- dev-feat/issue-362-unify-waiting-strategies
- dev-fix/365-staticfiles-path-joining
- dev-fix/342-readme-static-files-middleware
- dev-perf/cache-method-exists-in-service-handler
- dev-fix/311-readme-orphaned-footnote
- dev-docs/300-license-reference-in-readme
- dev-docs/request-phpdoc-321
- dev-fix/347-inotify-watcher-phpdoc-types
- dev-fix/configloader-setbuildconfig-ordering
- dev-refactor/configloader-split-getconfig
- dev-fix/341-remove-redundant-function-exists-in-inotify-watcher
- dev-issue-294-request-converter-test-coverage
- dev-security/serverworker-ssl-file-validation
- dev-feature/276-taskhandler-processhandler-event-ordering-tests
- dev-fix/338-taskerrorevent-immutable
- dev-fix/296-http-request-handler-error-log
- dev-perf/schedulerworker-avoid-per-tick-closure
- dev-release/0.21.0-changelog
- dev-fix/298-superpowers-export-ignore
- dev-feature/299-composer-keywords-description
- dev-fix/316-pharhelper-remove-getprojectdir
- dev-docs/282-bin-directory-unexplained
- dev-docs/troubleshooting-long-running-workers
- dev-feature/http-request-handler-tests
- dev-fix/270-runtime-directory-restrictive-mode
- dev-feat/261-static-files-304-support
- dev-fix/289-readme-reboot-strategy-fqcn
- dev-feature/runner-end-to-end-test
- dev-fix/phar-compat-static-files-middleware
- dev-feature/259-phar-alias-security
- dev-feature/295-servermanager-magic-timeout-constants
- dev-feature/247-attribute-tests
- dev-feature/275-278-extract-shared-handler-listener-base
- dev-refactor/285-extract-directory-iterator-boilerplate
- dev-perf/request-converter-early-out-files
- dev-feat/precompose-middleware-pipeline
- dev-fix/zip-archive-tests
- dev-perf/remove-timer-add-on-every-request
- dev-feature/301-request-converter-refactor
- dev-fix/291-http-request-handler-refactor
- dev-changelog-0.20.0
- dev-feature/305-listen-scheme-enum
- dev-perf/246-polling-monitor-sharded-scan
- dev-docs/269-workerman-connections-docs
- dev-fix/zip-slip-protection-sfx-downloader
- dev-feature/235-static-files-security-allowlist
- dev-docs/257-version-matrix-mismatch
- dev-feature/241-test-byte-formatter
- dev-feature/chunked-response-default-strategy
- dev-feature/211-servermanager-refactoring
- dev-feature/209-scheduler-worker-behavioral-tests
- dev-refactor/214-servermanager-getconfig
- dev-docs/243-config-options-documentation
- dev-docs/231-middlewares-documentation
- dev-refactor/210-runner-extract-methods
- dev-issue-218-file-monitor-worker-test
- dev-fix/217-cookie-header-smuggling
- dev-fix/225-binaryfileresponsestrategy-onclose-overwrite
- dev-docs/232-servers-listen-docs
- dev-refactor/219-scheduler-run-callback
- dev-refactor/216-configuration-tree-builder-split
- dev-chore/changelog-0.18.0
- dev-issue-169-ci-lint-php-version
- dev-release/0.16.0
- dev-fix-155-servermanager-status-polling
- dev-fix/150-cpucount-null-safety
- dev-fix/152-trusted-proto
- dev-fix/pin-setup-php-to-sha
- dev-feature/php82-server-action-enum
- dev-chore/update-changelog-branch-protection
- dev-fix/issue-18-ssl-cert-validation
- dev-feature/kernel-state-reset-22
- dev-fix/streamed-binary-file-response-chunking
- dev-fix/multipart-empty-content
- dev-fix/60-server-protocol-e2e-tests
- dev-docs/update-changelog-69
- dev-fix/69-e2e-streamed-response-tests
- dev-feature/71-streamed-response-sse
- dev-feature/93-typed-exception-hierarchy
- dev-feature/95-branch-protection-docs
- dev-feature/file-upload-validator-87
- dev-fix/issue-85
- dev-fix/73-non-blocking-terminate
- dev-add-release-workflow
- dev-fix/issue-20-infinite-loop-graceful-stop
- dev-pr-13
- dev-add-test-bootstrap
- dev-replace-timer-with-globalevent
- dev-update-versions-and-security-fix
- dev-test-agains-sf-73
- dev-fix-double-content-type-headers
- dev-symfony-first
- dev-add-middlewares
- dev-test/separate-lint-from-tests
This package is auto-updated.
Last update: 2026-10-09 08:47:54 UTC
README
Workerman is a high-performance, asynchronous event-driven PHP framework written in pure PHP.
This bundle provides a Workerman integration in Symfony, allowing you to easily create an HTTP server, scheduler and supervisor all in one place.
This bundle allows you to replace a traditional web application stack like php-fpm + nginx + cron + supervisord, all written in pure PHP (no Go, no external binaries).
The request handler works in an event loop, which means the Symfony kernel and the dependency injection container are preserved between requests,
making your application faster with fewer (or no) code changes.
Contributing
Please see CONTRIBUTING.md for information about branch protection rules and development workflow.
What's new in this fork
This section documents the differences between crazy-goat/workerman-bundle (this fork) and the upstream luzrain/workerman-bundle.
Dependencies & Compatibility
| Aspect | crazy-goat (this fork) | luzrain (upstream) |
|---|---|---|
| PHP | ^8.2 |
>=8.1 |
| Symfony | `^6.4 | ^7.0 |
| PSR-7 bridge | Removed (not required) | Required (psr/http-factory, psr/http-message, symfony/psr-http-message-bridge) |
Features
-
Middleware system — composable request/response pipeline with
MiddlewareInterface,MiddlewareDispatchInterface,StaticFilesMiddleware(ETag, Last-Modified, 304 support, blocked extensions, dot-file blocking, symlink control, path traversal protection, LRU realpath cache with TTL, PHAR-aware path resolution),SymfonyController(kernel boot, request conversion, response, termination, service resetter), and a pipeline that is built once and cached. Each request uses one dispatcher object and one controller closure. -
Console commands — full server lifecycle management via
ServerManager:workerman:server start/stop/restart/reload/status/connections, plusworkerman:build:pharandworkerman:build:binfor packaging. -
Slowloris / DoS protection — configurable
connection_timeoutfor incomplete requests (default: 120s),keepalive_timeoutfor idle connections (default: 30s), and per-serverbody_size_cap. -
Response conversion with strategy pattern —
BinaryFileResponseStrategy(uses Workerman'swithFile(), supportsSplTempFileObject, offset/maxlen,deleteFileAfterSendcleanup),StreamedResponseStrategy(chunked transfer encoding),DefaultResponseStrategy(large responses via chunked transfer directly to connection), header name normalization with caching. Upstream buffers everything in memory. -
Memory reload strategy — reloads the worker when emalloc'ed memory exceeds
limit(default 128 MB); agc_collect_cycles()is attempted once memory passesgc_limit(default 96 MB) — synchronously, before the reload decision, whenever the worker is also abovelimit(so a collection that frees enough memory avoids the reload), and deferred to the next event-loop tick otherwise;gc_cooldown(default 60s) limits collection frequency. -
Trusted hosts —
trusted_hostsconfig key with regex patterns, rejects non-matchingHostheader viaSuspiciousOperationException(400). -
Service state resetter integration — calls
services_resetterafter kernel termination to reset stateful services between requests (critical for long-running worker correctness). -
SSL validation — validates cert/key paths, rejects symlinks for security.
-
Process inspection —
/proc-based zombie detection, orphan killing, parent PID tracking. -
PHAR/BIN runtime support —
runtime_dirconfig key withWORKERMAN_RUNTIME_DIRenv var,PharHelperfor runtime path resolution, automatic runtime directory creation, skips file monitor in PHAR mode,KernelFactorywith PHAR-awaregetCacheDir()/getLogDir(). -
Custom exception hierarchy — 20 exception classes (plus 2 marker interfaces) under
WorkermanExceptionInterface→WorkermanException→ category bases (ServerException,KernelException,MiddlewareException,SchedulerException,ValidationException) with specific exceptions for the bundle's error cases. Upstream uses only generic PHP exceptions. -
Utils::reload()— programmatic worker reload from application code withreloadAllWorkers: trueparam. -
File upload validation — structural validation of uploaded files with clear error messages. Upstream has no validation.
-
Extended
Requestclass — adds thesetHeader()method to Workerman's Request, required by the middleware system.withHeader()is a deprecated alias (since 0.23.0, removed in 1.0). -
ListenSchemeenum — type-safe HTTP/HTTPS/WS/WSS scheme parsing. Upstream uses inlinestr_starts_with()checks. -
Trigger factory improvement — uses
CronExpression::isValidExpression()for proper cron detection. Upstream uses a fragile heuristic (count(explode(' ', $expr)) === 5 && str_contains($expr, '*')). -
SchedulerWorker improvements — proper SIGCHLD handler that reaps children and logs exit codes/signals, file-lock-based PID management with symlink detection and inode mismatch protection. Upstream uses
SIG_IGNfor SIGCHLD and simplefile_put_contentsfor PID. -
SupervisorWorker improvements — handler returns
nevertype (process exits with code 1 on unexpected return), logs unexpected finish, skips processes withprocesses <= 0. -
Cache warmup improvements — signal-based success/failure detection (SIGKILL=success, SIGTERM=failure), configurable timeout via
WORKERMAN_CACHE_WARMUP_TIMEOUTenv var. Upstream uses simplepcntl_wait()with no timeout or error detection. -
Config loader improvements —
ConfigSectionenum,warmUp()validates all sections before writing,setBuildConfig()/getBuildConfig()for PHAR build config.
Code quality / DX
- Full custom exception hierarchy (20 classes plus 2 marker interfaces) instead of generic
\Exception readonlyclasses where appropriate- Extracted
ConfigurationTreeBuilder,ServicesConfigurator,WorkermanCompilerPassas separate testable classes (upstream uses anonymous closures/files) ServerManagerextracted as standalone service (testable)ServiceMethodvalue object with validation (upstream uses raw strings)ServiceHandlerTrait/ServiceErrorListenerTraitfor shared logic- Extensive test suite (unit + integration + e2e)
- PHPStan + Rector in CI pipeline
What was removed
- PSR-7 pipeline:
WorkermanHttpMessageFactory,psr/http-factory,psr/http-message,symfony/psr-http-message-bridgedependencies — replaced by direct Workerman→Symfony conversion.
Requirements
- PHP 8.2 or newer.
ext-pcntlandext-posix.- Symfony 6.4, 7 or 8.
- Workerman 5.
- Linux or macOS. Windows is not supported.
Optional: ext-event, ext-inotify, ext-zip and dragonmantank/cron-expression.
See Getting started for what each one does.
Getting started
The short version is below. The full guide is docs/getting-started.md.
Install composer packages
composer require crazy-goat/workerman-bundle
Enable the bundle
<?php // config/bundles.php return [ // ... \CrazyGoat\WorkermanBundle\WorkermanBundle::class => ['all' => true], ];
Configure the bundle
A minimal configuration might look like this. For all available options with documentation, see the command output.
$ bin/console config:dump-reference workerman
# config/services.yaml services: workerman.middleware.static_files: class: CrazyGoat\WorkermanBundle\Middleware\StaticFilesMiddleware public: true arguments: $rootDirectory: '%kernel.project_dir%/public' # config/packages/workerman.yaml workerman: servers: - name: 'Symfony webserver' listen: http://127.0.0.1:8080 processes: 4 middlewares: - workerman.middleware.static_files reload_strategy: exception: active: true when@dev: workerman: reload_strategy: file_monitor: active: true source_dir: ['%kernel.project_dir%/src'] file_pattern: ['*.php', '*.yaml'] # Polling fallback (used only without ext-inotify): polling_interval: 3 max_files_per_tick: 500
Note: The example above binds an unprivileged port (
8080) so it works withoutsudo. See Ports below 1024 for ports such as80or443.
Note:
processesis the number of workers of a server. If you leave it out, the default is the number of CPUs times 2. In a container the CPU limit is used, not the CPUs of the host. See docs/configuration.md.
Note:
listenis required. If you leave it out, the server does not start and you get anUnsupported listen schemeerror. Supported URI schemes:http://,https://,ws://(WebSocket),wss://(WebSocket over SSL).https://andwss://listeners additionally requirelocal_certandlocal_pk— see the TLS example.
Configuration reference
Every config key and every environment variable is in docs/configuration.md.
To see the keys with their defaults, run bin/console config:dump-reference workerman.
Start application
Using the Symfony console command (the bin/console below refers to your application's Symfony console, not the bin/ directory shipped by this bundle):
$ bin/console workerman:server start
$ bin/console workerman:server start -d # daemon mode
Note: All
bin/console workerman:*commands throughout this document refer to your application's Symfony console, not the scripts in this bundle'sbin/directory. Seebin/README.mdfor the bundle's own development scripts.
All commands and options are in docs/commands.md.
Config cache and runtime user
Since 0.25.0 the bundle refuses to load a configuration cache file that is not
owned by the process that loads it. An owner mismatch stops
workerman:server start with a RuntimeException. The most common case is a
cache warmed up as root in a Docker build, with a server that runs as a
non-root user.
Warm up the cache as the runtime user, or change the owner after the warm-up. The full guide, with the error message, is in Deployment, and a tested Dockerfile is in Docker. The threat model is in Config Cache File Protection. If you cannot change who warms the cache, see Guard downgrade.
Stop a server that was started by an older version before you upgrade to 0.25: see Upgrading to 0.25.
Manage the server
You can stop, restart, reload and inspect the server with bin/console workerman:server.
See docs/commands.md for all actions, options, the connections output and Utils::reload().
Reload strategies
A worker keeps the Symfony kernel between requests, so it must be replaced sometimes. Reload strategies decide when: after an exception, after N requests, at a memory limit, after a file change or after each request. You can also write your own strategy. See docs/reload-strategies.md.
Middlewares
Middlewares run before the Symfony controller and after it.
A middleware implements CrazyGoat\WorkermanBundle\Middleware\MiddlewareInterface and is listed under workerman.servers[].middlewares.
The bundle has a StaticFilesMiddleware for static files.
See docs/middlewares.md for the interface, the order of the layers and the static file headers.
For the listen address, workers, timeouts and streamed responses, see docs/http-server.md.
Scheduler
Periodic tasks are configured with the #[AsTask] attribute or with the workerman.task tag.
A schedule can be seconds, an ISO 8601 duration, a relative date, a date and time, or a cron expression.
See docs/scheduler.md for the schedule formats, the fixed-rate rule, jitter, locks and errors.
Supervisor
Long-running processes are configured with the #[AsProcess] attribute or with the workerman.process tag.
The bundle starts them again when they end.
See docs/supervisor.md for the parameters, the restart rules and errors.
Packaging (experimental)
⚠️ Experimental: PHAR and standalone binary packaging are new features. The API may change in future releases.
The bundle provides commands to package your Symfony application as a standalone PHAR archive or a native binary:
# Build a PHAR archive $ php -d phar.readonly=0 bin/console workerman:build:phar # Build a standalone binary (requires phpmicro.sfx) $ php -d phar.readonly=0 bin/console workerman:build:bin # Options $ php -d phar.readonly=0 bin/console workerman:build:phar --help $ php -d phar.readonly=0 bin/console workerman:build:bin --help
See docs/build-packaging.md for full documentation, build configuration options, and known limitations.
For an overview of all documentation files, see docs/.
For security-related documentation including Host-header protection and trusted hosts configuration, see docs/security.md.
For long-running worker gotchas, state pollution, stale DB connections, blocking I/O, and other common issues, see docs/troubleshooting.md.
License
This bundle is open-sourced software licensed under the MIT license.