CLI · Winter Console

The cfg command

cfg sets up and maintains a project’s configuration: the .env file, the WINTER_KEY secret, the Docker scaffolding and shell completion. It is the first thing that runs when a project is created, and the thing you come back to when setting an environment up.

Subcommands init · key · env · docker · completionFirst run cfg init

What cfg is and why

cfg is the project-configuration command.

The problem. A new project has to be brought into working shape: create the .env, generate a secret key and, if you want them, the Docker files and shell completion. Doing that by hand makes a forgotten step easy.

The solution. cfg gathers those operations into subcommands, and cfg init performs the basic setup in one go. That is what this page is about.

Subcommands

Subcommand Purpose
init Patches composer.json, creates .env, generates the key, drops in the stub meta
key Manages WINTER_KEY
env Manages the .env file
docker Generates the Docker files
completion Installs or prints the shell completion

cfg init

Brings the project into working shape (called automatically on composer create-project):

bash
php call cfg init

The sequence: patch composer.json (rewrite name and description, clear authors/keywords) → create .env → generate WINTER_KEY.

cfg key — the secret key

Flag Action
key -g Generate or regenerate the key (64 hex = 32 bytes) and write it into .env
key -s Show the current key
bash
php call cfg key -g   # a new WINTER_KEY

It needs a .env

key -g warns and stops when .env is missing — create it first (cfg env -i).

cfg env — the environment file

Flag Action
env -i Create .env from the template (skipped when it exists)
env -s Print the loaded $_ENV
env -s --file Print the raw contents of .env

cfg docker — the Docker scaffolding

bash
php call cfg docker

Creates a Dockerfile, a docker-compose.yml, a .dockerignore and a docker/ directory with a startup script and PHP settings. The command has no options — there is one image, for Swoole, and the mode is picked with a variable at startup:

Startup Mode
docker compose up Production: opcache on, no watcher
DEV=true docker compose up Development: restart on file change, opcache off

PHP extensions and database drivers

These are installed by separate scripts in docker/dependencies/, not by editing the Dockerfile. The build runs them in numeric-prefix order; four ship with the template:

Script Installs
10-bcmath.sh bcmath — exact arithmetic (money, Number)
20-pgsql.sh pdo_pgsql + pgsql — PostgreSQL
30-mysql.sh pdo_mysql — MySQL / MariaDB
40-redis.sh phpredis — the Redis client

Delete the ones you do not need: what is not in the directory does not end up in the image.

Every script is self-contained — it installs whatever the build needs and removes it again. So it can be copied into another project or run by hand, and your own is written to the same pattern:

docker/dependencies/50-intl.sh
#!/bin/sh
set -e

# intl — date and number formatting, locale-aware collation.
if php -m | grep -qi '^intl$'; then
  echo "intl already present — skip"
else
  apk add --no-cache icu-libs \
      && apk add --no-cache --virtual .intl-deps $PHPIZE_DEPS icu-dev \
      && docker-php-ext-install -j"$(nproc)" intl \
      && apk del .intl-deps
fi

Three things there matter:

  • The php -m check — the extension may already be in the base image, in which case the script does nothing and costs no build time.
  • --virtual — the compiler and the headers are installed under one name, .intl-deps, and removed in a single command, so they never reach the final image. Only the runtime library stays (icu-libs), without which the extension will not load.
  • $PHPIZE_DEPS — the extension-building toolchain the PHP base image defines (compiler, make, autoconf, re2c). No need to list the packages by hand.

A failing script stops the build

An error in any of the scripts fails the image build — deliberately. Otherwise you would get a green image with the extension missing and find out on the first query to the database, in production.

cfg completion — shell completion

Flag Action
(no flag) Print the script to stdout
-i Install it
-if Install it, overwriting
bash
php call cfg completion -i

The shell is detected from $SHELL: zsh → ~/.zsh/completions/_call (an fpath line is added to ~/.zshrc), otherwise bash → ~/.bash_completion.d/call.

Next