Skip to content

Apache ports, Composer version, locales and daemons from environment variables - #420

Merged
mistraloz merged 5 commits into
thecodingmachine:v5from
mistraloz:fix/env-features
Oct 12, 2026
Merged

mistraloz merged 5 commits into
thecodingmachine:v5from
mistraloz:fix/env-features

Conversation

@mistraloz

@mistraloz mistraloz commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

This PR fixes :

  • Bug
  • Feature
  • Breaking changes

Simple features configured with environment variables, one commit per issue.

  1. Add environment variable to change Apache ports #360: Apache ports. APACHE_HTTP_PORT and APACHE_HTTPS_PORT (default 80 and 443), e.g. to use unprivileged
    ports in a Kubernetes cluster.
  2. Be able to specify composer version #351: Composer version. COMPOSER_VERSION takes an exact version (2.4.4) or a channel (1, 2, 2.2).
    It is installed at the container start, or during the build of a slim image with ARG COMPOSER_VERSION.
  3. Feature Request: Install locales through environment variables #212: locales. LOCALES="fr_FR.UTF-8 de_DE.UTF-8" generates these locales at the container start (~1s per
    locale, instant on restart). The locales package is installed in the fat images (~17MB) and with
    ARG INSTALL_LOCALES=1 in the slim images; otherwise the start fails with an explicit message.
  4. [feature request] Add a process manager like supervisord #147: processes along with the main command. One container per process remains the recommended setup, and the
    documentation says so first. When it is not an option, DAEMON_COMMAND_* starts long-running processes (e.g. a
    queue worker), run by the docker user or by the user set in DAEMON_USER_* (name or ID). Nothing is restarted: as soon as one process (or the main
    command) exits, the other ones are stopped and the container stops with its exit code, so that Docker or the
    orchestrator sees the failure. On stop, Apache and PHP-FPM complete the running requests, the other processes
    receive SIGTERM. Supercronic is supervised the same way: the container no longer keeps running without cron
    jobs when Supercronic dies. The supervisor is a small bash script (utils/supervise.sh), only used when there is
    a process to run along with the main command.
  5. Lots of <defunct> processes when using Cron #368: zombie processes of the cron jobs. Not reproducible on v5: sudo, PID 1 of the container, reaps the
    orphaned processes. A test now covers it.

Fixes #360
Fixes #351
Fixes #212
Fixes #147
Fixes #368

Test plan (required)

The test suite passes on PHP 8.2 to 8.5 for the cli, apache and fpm variants. New tests: test_httpPort
(variant-apache.sh), tool-composer-version.sh, tool-locales.sh, tool-daemon.sh (daemon output, default user and
DAEMON_USER, stop when a daemon fails, docker stop) and test_noZombie (tool-supercronic.sh).

Checklist

  • I followed the guidelines in CONTRIBUTING guide
  • I have squashed any insignificant commits
  • This change has comments for package types, values, functions, and non-obvious lines of code

Apache can listen on unprivileged ports, e.g. in a Kubernetes cluster
that forbids binding the ports below 1024.

Closes thecodingmachine#360
The images come with the latest Composer version, which can break a
project (e.g. Composer 2.5 rejects the packages with an invalid lock
file). COMPOSER_VERSION takes an exact version or a channel (1, 2,
2.2): it is installed at the container start, or at the build of a
slim image with an ARG.

Closes thecodingmachine#351
Only the C, C.UTF-8 and POSIX locales were available: generating
another one required a custom Dockerfile. The locales package is
installed in the fat images and with ARG INSTALL_LOCALES=1 in the slim
images.

Closes thecodingmachine#212
One container per process remains the recommended setup, but some
projects need a long-running process (e.g. a queue worker) in the same
container. The processes are not restarted: as soon as one of them, or
the main command, exits, the other ones are stopped and the container
stops with its exit code, so that Docker or the orchestrator sees the
failure. A stop signal is forwarded to the main command (SIGWINCH for
Apache, SIGQUIT for PHP-FPM) and SIGTERM to the other processes.

Supercronic runs the same way: the container no longer keeps running
without cron jobs when Supercronic exits.

Closes thecodingmachine#147
The zombie processes of thecodingmachine#368 (reported on v4) no longer happen on v5:
sudo, PID 1 of the container, reaps the orphaned processes.

Closes thecodingmachine#368
@mistraloz
mistraloz merged commit 6e3c712 into thecodingmachine:v5 Oct 12, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant