Size the PHP-FPM pool
$ grim tune --auto
Under load the app answers slowly while the server still has memory to spare, or the opposite: the box starts swapping because PHP was allowed more workers than it has room for. Both come down to one number, how many PHP-FPM workers may run at once, and the right value depends on the machine you rent, not on the project.
grim tune writes that number, and the few that go with it, into a small config file the production stack mounts into the app container. With --auto it measures the server first.
Usage
$ grim tune --auto # measure the server, save the values, write the file
$ grim tune # write the file from grim.json, or from the defaultsRun it from the project directory. --auto connects as the deploy user to the project's server, so the project must already be registered there.
Arguments and options
Generate PHP-FPM performance config for production
Usage
grim tune [--auto]Options
| Option | Description |
|---|---|
--auto |
Auto-detect optimal values from server specs via SSH |
What it actually does
- Collects the values. Without
--autothey are the defaults, overlaid with whatever theperformanceblock ofgrim.jsonsets. - With
--auto, measures the server. CPU cores fromnproc, available memory fromfree -m, and the current memory use of the app container when it is running. It prints all three. - With
--auto, calculates the pool.pm.max_childrenis 70 % of the available memory divided by 50 MB per worker, kept between 5 and 100.pm.start_serversis a quarter of that,pm.min_spare_serversan eighth,pm.max_spare_serversa half. The result is saved as theperformanceblock ofgrim.json. - Writes
docker/php-fpm-production.conf. A[www]pool withpm, the four worker counts andpm.max_requests. The file says not to edit it by hand, because the next run replaces it. - Prints a summary of the values and the file name.
The values
Key in performance |
Default | Reaches the config file |
|---|---|---|
pm |
dynamic |
Yes |
pm.max_children |
20 | Yes |
pm.start_servers |
5 | Yes |
pm.min_spare_servers |
3 | Yes |
pm.max_spare_servers |
10 | Yes |
pm.max_requests |
500 | Yes |
memory_limit |
512M |
No, shown in the summary only |
opcache.memory_consumption |
256 | No, shown in the summary only |
opcache.jit_buffer_size |
128M |
No, shown in the summary only |
The last three are fixed in the production image. Changing them in grim.json changes what the summary prints and nothing else.
Pitfalls
The file does not travel with a deploy
The production stack mounts ./docker/php-fpm-production.conf from the project's directory on the server. It is not inside the image, and grim deploy uploads the compose file and the nginx config but not this one. The summary's Next row names build and deploy; neither delivers the file. Copy it yourself and restart the app container.
$ scp docker/php-fpm-production.conf deploy@203.0.113.10:/opt/shop/docker/
$ grim remote:exec docker compose restart app--auto rewrites the whole block
It saves the defaults plus the five values it calculated. A pm mode, a memory_limit or any other key you had set by hand in performance is replaced by its default. Look at git diff grim.json afterwards.
--auto measures the default environment
The host is deploy.host from grim.json, or else the project's default environment in ~/.grim/servers.json. There is no argument for another one. No deploy host configured. means neither exists; register the project with grim server:add-project first.
Available memory is a snapshot
The calculation uses what was free at the moment you ran it, with the app's own workers counted as used. Measure at a quiet hour, and on a server shared by several projects expect a lower number than the machine's size suggests.
After it finishes
Commit grim.json and the generated file, get the file onto the server as shown above, and check that PHP-FPM took it.
$ grim remote:exec docker compose exec -T app php-fpm -ttRelated spells
grim build
Forge the production image
Build the project's production Docker image, tag it with the next version, and push it to GHCR when asked.
grim deploy
Send an image to a server
Roll a pushed image tag out to one environment over SSH, verify the app answers, and fall back to the previous tag when it does not.
grim release
Ship in one pass
Test, build, push and deploy the project to an environment with a single command and a single tag.
grim remote:exec
Run a command on the server
Run one shell command on the server, in the deployed project's directory, without opening an SSH session yourself.
grim server:status
Look over a server
List the servers you have registered, or look at one of them: its containers, its disk, Traefik and its projects.