WinterWebSwooleApplication
Recommended for production. Starts a Swoole HTTP server with multiple worker processes. Supports #[Async], #[Scheduled], daemon threads, and the local KV/Queue stores. Requires the swoole PHP extension.
Winter Boot applications can be shipped in several ways depending on your infrastructure: as a self-contained Phar archive for bare-metal hosts, as a Docker image for containerised deployments, or via standard PHP-FPM for environments that already manage PHP processes. The framework ships with a sample init.d script and Docker base image to get you started quickly. A fully working example, including a Dockerfile and a box.json build manifest, is available in the suvera/winter-example-service repository.
Before building, choose the runner that matches your deployment target. Each runner starts the application in a different mode.
WinterWebSwooleApplication
Recommended for production. Starts a Swoole HTTP server with multiple worker processes. Supports #[Async], #[Scheduled], daemon threads, and the local KV/Queue stores. Requires the swoole PHP extension.
WinterWebApplication
Traditional PHP-FPM / CGI runner. Each request is a new process invocation — no persistent workers. Use this when Swoole is unavailable or when integrating with an existing PHP-FPM pool.
WinterCliApplication
Command-line runner. Boots the application context and fires the ApplicationReady event, then exits. Useful for batch jobs, migrations, and one-off administrative scripts.
// Swoole HTTP server (recommended for production)(new WinterWebSwooleApplication())->run(MyApplication::class);
// PHP-FPM / traditional(new WinterWebApplication())->run(MyApplication::class);
// CLI / batch(new WinterCliApplication())->run(MyApplication::class);Use Box to compile your application and all its Composer dependencies into a single, self-contained Phar archive.
Install dependencies
composer install --no-dev --optimize-autoloaderInstall Box
composer global require humbug/boxVerify the installation:
box --versionCreate box.json
Add a box.json configuration file to your project root:
{ "output": "target/my-app.phar", "main": "bin/app.php", "directories": ["src", "config"], "compression": "GZ", "chmod": "0755"}Compile the Phar
box compileOn success, the output file is a standalone executable:
php target/my-app.phar -c /etc/my-app/configWinter Boot ships a base Dockerfile at build/docker/Dockerfile that extends the official php:8.5-cli image and pre-installs the extensions most modules require:
###################################################################################### WinterBoot PHP Image - Run below command## docker build . -t suvera/winter-boot:latest -f ./build/docker/Dockerfile######################################################################################FROM php:8.5-cli
RUN apt-get update \ && apt-get install -y librdkafka-dev libzip-dev procps libssl-dev libcurl4-openssl-dev \ && pecl install redis \ && pecl install rdkafka \ && pecl install swoole-6.2.2 \ && pecl install zip \ && docker-php-ext-enable redis rdkafka swoole zipBuild your application image on top of the base image:
FROM suvera/winter-boot:latest
WORKDIR /app
COPY composer.json composer.lock ./RUN composer install --no-dev --optimize-autoloader
COPY src/ src/COPY config/ config/
EXPOSE 8080
CMD ["php", "src/MyApplication.php", "-c", "config/"]docker build -t my-winter-service:latest .docker run -p 8080:8080 my-winter-service:latestWinter Boot requires PHP 8.4 or higher. The base image ships PHP 8.5-cli.
Install via pecl install swoole for the WinterWebSwooleApplication runner. The base image already includes it.
Run composer install --no-dev --optimize-autoloader during the docker build step, not at container start. Installing at start adds latency to every container launch.
Mount your application.yml at a known path and pass it with -c /config at container start. Avoid baking environment-specific config into the image layer.
When deploying with SQL migrations, run the migrator as a Kubernetes init container so the schema is up-to-date before any application pod starts:
initContainers: - name: db-migrate image: my-winter-service:latest command: ["php", "target/winter-migrations-app.phar", "-c", "/config"] volumeMounts: - name: config mountPath: /configFor traditional host-based deployments, build a Phar archive and manage the process with the provided init.d sample script.
Start the application with an explicit config directory:
php target/my-app.phar -c /etc/my-app/config/The -c flag points to the directory containing your application.yml (and any additional config files such as logger.yml).
Winter Boot ships a ready-to-use init.d template at build/init.d.sample.sh. Copy it and register it with your init system:
cp build/init.d.sample.sh /etc/init.d/my-winter-servicechmod +x /etc/init.d/my-winter-serviceEdit the variables at the top of the file to match your environment:
USER=www-dataSERVICE_NAME=my-winter-serviceSERVICE="target/my-app.phar"CONFIG_DIR="/etc/my-app/config"ADMIN_PORT="9090"ADMIN_TOKEN_FILE="/etc/my-app/admin.token"LOG_FILE="/var/log/my-winter-service/app.log"PID_FILE="/var/run/my-winter-service.pid"PHP_BINARY="php"Then control the service with standard commands:
service my-winter-service startservice my-winter-service stopservice my-winter-service restartservice my-winter-service statusTo use systemd instead, create a native unit file:
[Unit]Description=My Winter Boot ServiceAfter=network.target
[Service]Type=simpleUser=www-dataExecStart=/usr/bin/php /var/www/my-app/target/my-app.phar -c /etc/my-app/configRestart=on-failureStandardOutput=journalStandardError=journal
[Install]WantedBy=multi-user.targetReload systemd and enable the service:
systemctl daemon-reloadsystemctl enable my-winter-servicesystemctl start my-winter-serviceWhen using WinterWebApplication (without Swoole), point your web server’s FastCGI configuration at your application entry point:
location / { fastcgi_pass unix:/run/php/php8.4-fpm.sock; fastcgi_param SCRIPT_FILENAME /var/www/my-app/bin/app.php; include fastcgi_params;}The suvera/winter-example-service repository demonstrates a complete Winter Boot microservice with a production-ready setup:
Dockerfile
A production-ready multi-stage Dockerfile built on the Winter Boot base image.
box.json manifest
A box.json build manifest for Phar packaging, suitable for CI/CD pipelines.
Migration init container
SQL migration setup using the Kubernetes init container pattern.