CLI · Winter Console

The run command

run starts not “a server” but the whole application — everything declared with #[Enable*] attributes on the application class. The web server, background processes, daemons and the scheduler come up with one command and share one lifecycle.

Runtime SwooleDevelopment run devNo web headless

What exactly starts

The composition is determined by the attributes — the command decides nothing for you:

Attribute What comes up
#[EnableWeb] The Swoole HTTP server — the main process
#[EnableProcess(...)] A process tied to the application’s lifecycle
#[EnableDaemon(...)] A daemon under a supervisor
#[EnableScheduler] The scheduler for #[Scheduled] tasks

Without #[EnableWeb] the application comes up headless — no HTTP, background components only. That is a legitimate and common mode: a queue, a scheduler and a set of handlers without a single open port.

bash
php call run

What those attributes declare is covered on the Application components page.

Development mode

bash
php call run dev
php call run -w          # the same thing, as a flag
php call run --watcher   # and as an option

There is exactly one difference from a normal start — the watcher is switched on: it follows the project’s files and restarts the application on a change, and keeps an eye on memory along the way.

`dev` is the same Swoole

There is no separate “PHP built-in server” here: run and run dev both bring up the same Swoole server. Only the watcher differs.

So the swoole extension is needed for development too — it is installed once (pecl install swoole) or is already in the image cfg docker creates.

In a container the mode is switched with a variable; the image does not need rebuilding:

bash
docker compose up            # production mode
DEV=true docker compose up   # development: watcher on, opcache off

Address and port

Option What it sets Default
--host= The bind address 0.0.0.0
--port= The port 8000
bash
php call run --port=9000
php call run dev --host=127.0.0.1 --port=9000   # locally only

0.0.0.0 means “on every interface” — that is how a container is visible from outside. For local development, when the server should not be reachable over the network, set --host=127.0.0.1 explicitly.

The other server parameters are not flags

The worker count, request limits, timeouts and memory are not set on the command line: they live in the SERVER_* variables and in the web layer’s configuration class.

That way they are the same however you start — from a terminal, from compose, from a supervisor — and are not lost when the command is copied. See Web layer configuration and Configuration.

At startup

Before the first request the project is walked, the container is assembled and the route table is built; then a banner is printed with the application’s composition and address. To remove the banner, set WINTER_BANNER=off.

After that the master process forks the workers. What exactly you will see in ps and which process does what is covered in the Console overview and in Key concepts.

Stopping

Ctrl+C or SIGTERM — Swoole shuts the workers down cleanly, letting them finish their current requests. In a container the signal reaches the master directly because it is PID 1; no special wrapper is needed for that.

Next