Skip to content

[TASK] Move useful checks into the CI tests, remove dead tests and leftovers - #599

Merged
Kanti merged 17 commits into
webdevops:masterfrom
andersundsehr:chore/move-tests-and-cleanup
Nov 9, 2026
Merged

Kanti merged 17 commits into
webdevops:masterfrom
andersundsehr:chore/move-tests-and-cleanup

Conversation

@Kanti

@Kanti Kanti commented Nov 8, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Follow-up to #598. It first moves the checks from unused tests that still apply into the tests the CI runs. Then it removes the tests that never run, five unused template macros, Makefile targets that do not work, the image graph generation, PHP 5 leftovers and other dead settings in provisioning.

One change in behaviour: Nginx and PHP-FPM now also start in a container without IPv6. With IPv6 the images behave as before.

Changes

  • 5ba93445 + 75433327, checks moved into the CI tests. The CI picks one serverspec file per image (spec/docker/<image>_spec.rb) and the structure-test suites for the tags it builds. The checks below were only in suites for old tags or in serverspec examples that nothing included:

    Image Check Was only in
    base-app bzip2 for all tags (structure test); sponge (moreutils) on Debian and Ubuntu (serverspec, by OS family, so it does not depend on the tag name) the alpine and debian-7 suites, base-app::packages
    base netstat and sed for all tags the alpine suite, which the old Debian/Ubuntu tags linked to
    bootstrap PATH for all tags the per-distribution suites
    all (serverspec) docker-image-info dist-codename matches /etc/os-release on Debian and Ubuntu; the templates use it at build time the per-distribution bootstrap suites
    PHP images (serverspec) syslog-ng is installed base::syslog-ng

    The alpine suites of base and base-app and the PATH check in bootstrap/alpine are covered by the common test.yaml now. build.yaml is regenerated for the new suite paths.

  • d3950529, tests that never run, removed:

    • apache-dev_spec.rb: there is no such image.
    • php-official_spec.rb: a copy of php_spec.rb; the php job publishes php-official.
    • The unused examples base-app::packages, php::pear, python::toolchain, misc::graphviz, misc::letsencrypt and collection::bootstrap::upstream-image.
    • tests/testinfra, conftest.py and tests/__init__.py: the only testinfra test was for webdevops/liquibase.
  • 4b89e187: removes docker.add, docker.volume, environment.mailbox, provision.registerRole and provision.runRoleInline. Nothing calls them.

  • b7e7e52e + f07ec1b8, Makefile:

    • Kept: list (still the default), provision, structure-test, and setup, which the dockerfile-build-env image runs while it is built. graph and graph-full are removed in f2df52f1.
    • Removed: full, all, build, push, test, and the image groups for images that no longer exist (hhvm, varnish, certbot, typo3, …).
    • README, AGENTS.md and the build-tools known issue describe the remaining targets.
  • f2df52f1, image graph generation removed. Since [TASK] Consolidate documentation into README and docs/ #596 the docs show how the images build on each other as a Mermaid diagram; nothing uses the Graphviz image anymore. Removed:

    • conf/diagram.yml, bin/command/generate_graph_command.py and its registration in bin/console
    • the Makefile targets graph and graph-full
    • imagePath and graph.label in conf/console.yml, and imagePath in the path list of bin/console and the defaults of bin/webdevops/Configuration.py
    • graphviz in bin/requirements.txt and in docker/dockerfile-build-env (template and generated Dockerfile)
    • /graph in .gitignore

    README, AGENTS.md and the build-tools known issue name make provision as the only Python 2 target.

  • f85924a4, PHP 5 leftovers in provisioning:

    • 20-php-module-blackfire.sh only deleted files under /etc/php5.
    • logrotate.d/php5-fpm rotated /var/log/php5-fpm/*, which does not exist.
    • 10-php.sh (dev) and 20-setup-php-fpm.sh had branches for PHP older than 5.6.
  • ec6bac19, dead PHP-FPM and opcache settings:

    • 20-setup-php-fpm.sh removed the literal file PHP_MAIN_CONF instead of $PHP_MAIN_CONF. The branch only runs if php-fpm.conf already exists, and ln -sf replaced the file anyway, so the result does not change.
    • clear_env exists in all supported PHP versions: the workaround for PHP-FPM without it (PHP_CLEAR_ENV_AVAILABLE, 11-clear-env.sh) is gone.
    • PHP_VERSION in 10-php-init.sh was not used; 30-setup-ioncube.sh sets its own.
    • opcache.fast_shutdown does not exist since PHP 7.2. It was set in php.webdevops.ini of every PHP image, not only in the development settings; both are removed.
    • The structure tests name what 10-php-init.sh and 11-php-conf.sh do.
    • .editorconfig no longer has sections for DOCKER_REPOSITORY and DOCKER_TAG_LATEST, which do not exist.
    • make (target list) no longer prints No rule to make target 'no_targets__' on stderr.
  • IPv6 (e35bc7ac, 93bc20e6, 39bd2401, 1e4a19ce): Nginx listens on [::]:80 and [::]:443, PHP-FPM in php, php-dev, php-nginx-dev and php-apache-dev listened on [::]:9000. Without IPv6 in the kernel both failed with Address family not supported by protocol, and supervisord restarted them over and over.

    • PHP-FPM listens on the port only, listen = 9000 (20-setup-php-fpm.sh, dev 10-php.sh). PHP-FPM then binds to :: itself and falls back to 0.0.0.0 without IPv6 (fpm_sockets.c in PHP 8.2 and 8.5), so there is no rewrite at start. With IPv6 the socket is the same as with [::]:9000: both forms bind :: through the same code, and neither sets IPV6_V6ONLY. A host with net.ipv6.bindv6only=1, as reported for Podman, makes both forms IPv6-only.
    • Nginx has no such fallback: listen [::] fails without IPv6, also with ipv6only=off (Nginx 1.30 and 1.16). The two listen [::] directives of the default vhost now live in vhost.ipv6/listen-80.conf and vhost.ipv6/listen-443.conf; vhost.conf includes them with a wildcard, so missing files are fine. Without IPv6 (/proc/net/if_inet6 missing), entrypoint.d/20-nginx.sh deletes these two files and nothing else. A file of one's own with listen [::] keeps Nginx from starting without IPv6, as before. If /opt/docker/etc/nginx/ is mounted as a whole, the two files are deleted on the host too.
    • With IPv6 nothing changes.
    • Docs: the known issue is removed; docs/images/{php,php-nginx,nginx,php-apache}.md say how the services listen; docs/customization.md lists vhost.ipv6/ and says when it is deleted.
  • 9655c6f4 + 3795e88c, make structure-test and sponge:

    • tests/structure-test/run.sh tests every directory with a test.yaml, but only the tags that the CI builds (the -t "webdevops/..." lines in build.yaml), so old local tags no longer fail the run.
    • It exits non-zero if a test fails, if docker cannot list the images or if no image was tested. Before, the last two cases ended with exit code 0.
    • 3795e88c: a tag that is the same image as one already tested with the same suites, such as latest and ubuntu-22.04, is tested once. The error message lists the suites without an unquoted $(ls …) (shellcheck SC2046).
    • base-app::moreutils also runs on Debian, so the Debian PHP images check sponge too.
    • The build-tools known issue names which images the CI tests and shows make structure-test as the local check; AGENTS.md describes the new behaviour.

Not added to the CI tests, because they do not apply anymore or test something the images do not promise:

  • nano: not installed.
  • openssh-server, dnsmasq, postfix preinstalled in base-app: they are installed on docker-service enable, which base::services::additional tests.
  • pear: comes from the official PHP image and is not documented.
  • Python in dockerfile-build-env: that image has no spec and goes away with the Python tooling; graphviz is removed in f2df52f1.
  • certbot, liquibase: the images are gone.

bin/, conf/console.yml and bin/requirements.txt still reference testinfra. They go away with the Python tooling.

How it was verified

Serverspec and container-structure-test ran locally the same way as in the CI: inside webdevops/dockerfile-build-env with the Docker socket mounted, with each job's spec configuration taken from build.yaml, and with the CI's test Dockerfile (FROM <image> + COPY conf/ /). The test environment has no IPv6 at all (/proc/net/if_inet6 is missing, socket(AF_INET6) fails), which is exactly the case the IPv6 fix is for. The IPv6 case itself is covered by the CI.

A full PHP image build is not possible in the test environment: PIE cannot download mongodb/mongodb-extension from GitHub through the proxy. The changes were therefore checked like this:

  • Build-time scripts: docker/php-official/8.5 and 8.5-alpine built up to the step that runs the bootstrap scripts, once with the old and once with the new conf/.
  • Start scripts: test images FROM the published 8.5 images with the new 20-nginx.sh, vhost.conf, vhost.ipv6/ and the listen lines of the new build; no other changes.
Check Result
Bootstrap result old vs. new, php:8.5 and php:8.5-alpine /opt/docker and /usr/local/etc differ only in listen = [::]:9000 → listen = 9000 (application.conf, docker.conf), the removed opcache.fast_shutdown and the build timestamp. entrypoint.d/20-php-fpm.sh is the same as on master
php-dev bootstrap old vs. new on the new php.webdevops.ini the old script adds opcache.fast_shutdown = 1 again, the new one does not; ini_get("opcache.fast_shutdown") is false in PHP 8.5
Containers without IPv6, old images php-nginx, php-nginx-dev, nginx:alpine: Nginx restarts in a loop, no HTTP. php, php-dev, php-nginx-dev, php-apache-dev: PHP-FPM restarts in a loop (exit 78), Apache answers 503
Containers without IPv6, new images php, php-dev, php-nginx, php-nginx-dev, php-apache, php-apache-dev 8.5 and 8.5-alpine, nginx:alpine: no restarts. Nginx on 0.0.0.0:80/443. PHP-FPM with listen = 9000 logs once NOTICE: Failed implicitly binding to ::, retrying with 0.0.0.0 and listens on 0.0.0.0:9000 (127.0.0.1:9000 in php-nginx/php-apache). index.php answers with HTTP 200
php:8.5, php:8.5-alpine, php-dev:8.5 behind Nginx in a second container (WEB_PHP_SOCKET=fpm:9000) PHP answers through the network
vhost.ipv6/ files replaced by listen 8081 and listen 8443 ssl in a running container, php-nginx 8.5 and 8.5-alpine, nginx:alpine 8081 answers HTTP 200; 8443 answers HTTPS 200 and plain HTTP 400. The includes sit in the right server blocks
Mounts without IPv6, php-nginx:8.5-alpine own vhost.conf with listen [::], mounted read-write: unchanged on the host, Nginx does not start (as before, documented). Copy of the new vhost.conf, mounted: HTTP 200. vhost.ipv6/ mounted :ro: rm reports the error, the container keeps running, Nginx does not start. /opt/docker/etc/nginx/ mounted as a whole: the two files are deleted on the host, HTTP 200
Nginx snippet of 20-nginx.sh under errexit/nounset/pipefail, Debian and Alpine 3.11 with a fake /proc/net/if_inet6 both files stay; without it both are deleted; a second run exits with 0
Container started with php -r … instead of supervisord nothing on stderr
README quick start without IPv6 and without a workaround serves PHP 8.5.12
Serverspec without IPv6 and without a workaround, final images php:8.5 898 (2 more than before: sponge on Debian), php:8.5-alpine 881, php-dev:8.5 911, php-dev:8.5-alpine 894, php-nginx:8.5 1151, php-nginx:8.5-alpine 1134, php-nginx-dev:8.5 1159, php-nginx-dev:8.5-alpine 1142, php-apache-dev:8.5 1200, php-apache-dev:8.5-alpine 1183, nginx:alpine 804 examples, all 0 failures. After 1e4a19ce again: php-nginx:8.5 1151, php-nginx:8.5-alpine 1134, php-nginx-dev:8.5 1159, php-nginx-dev:8.5-alpine 1142, nginx:alpine 804, all 0 failures. php-apache (127.0.0.1:9000, no [::]) was green in the earlier run: 1192 and 1175
Serverspec with the new checks (earlier commits) bootstrap:ubuntu-22.04 207, bootstrap:alpine 205, base-app:ubuntu-22.04 225 (3 codename and 2 sponge checks added), base-app:alpine 210 (sponge skipped), base:ubuntu-22.04 656 examples, all 0 failures. The codename check expects jammy and bookworm; the syslog-ng check runs in all PHP images
Serverspec after removing the dead tests Same example counts, 0 failures, so none of the removed examples ran
make structure-test With the new images of php, php-dev and php-nginx 8.5 and latest tagged to the same images as ubuntu-22.04: 15 images tested, all pass, php-nginx included (it failed 3 checks without IPv6 before). bootstrap, base and base-app ubuntu-22.04 are skipped as the same image as latest. After 1e4a19ce again with the new php-nginx images: 15 images, all pass. Earlier run of 9655c6f4: a local webdevops/php:7.4 is skipped; a broken webdevops/php:8.3 (an image without PHP) fails 26 checks and makes the run exit non-zero, although the tags after it pass
make structure-test without Docker socket / with no matching image new: ERROR: docker images failed / ERROR: no image was tested. Build at least one tag of these images first: base-app base bootstrap php-dev php-nginx php, exit code 2 from make; old run.sh: exit code 0 in both cases
shellcheck 0.10.0 on run.sh, 20-nginx.sh, 20-setup-php-fpm.sh, dev 10-php.sh no findings (before: SC2046, SC2012, SC2035 in run.sh)
make lists list, provision, requirements, setup, structure-test; nothing on stderr
Graph removal (f2df52f1) no reference to the graph, conf/diagram.yml, imagePath or graph.label is left; the Graphviz output was last referenced before #596. make graph: No rule to make target. bin/console list has no generate:graph, the other commands are there. In dockerfile-build-env with graphviz removed (apt would remove only graphviz itself, so nothing depends on it; pip package uninstalled), make provision still works. make provision changes only the generated build-env Dockerfile
make provision, ci/console github:generate-ci docker/ and build.yaml match the sources
Doc checks Links and anchors resolve, README tag lists match build.yaml, no link to the removed known issue is left

Kanti added 17 commits November 8, 2026 11:40
The CI picks structure-test suites per built tag, so the suites for
old tags no longer ran, and some serverspec examples were never
included. Their checks that still apply now run for every tag:

- base-app: bzip2 for all tags; sponge (moreutils) for ubuntu-22.04
- base: netstat and sed for all tags
- bootstrap: PATH for all tags
- serverspec: docker-image-info dist-codename matches os-release on
  Debian and Ubuntu (the templates use it at build time)
- serverspec: syslog-ng is installed in all PHP images

The alpine suites of base and base-app are now covered by the common
test.yaml. build.yaml is regenerated for the new suite paths.
- serverspec: apache-dev_spec.rb (no such image), php-official_spec.rb
  (copy of php_spec.rb; the php job publishes php-official), and the
  unused examples base-app::packages, php::pear, python::toolchain,
  misc::graphviz, misc::letsencrypt, collection::bootstrap::upstream-image
- testinfra: the only test was for webdevops/liquibase; also remove
  conftest.py and tests/__init__.py
docker.add, docker.volume, environment.mailbox, provision.registerRole
and provision.runRoleInline are not called anywhere. Generated
Dockerfiles are unchanged.
Keep provision, graph and graph-full (Python 2, inside
dockerfile-build-env), structure-test and setup, which the
dockerfile-build-env image runs while it is built. Remove list, full,
all, build, push, test and the image groups, which point to images
that no longer exist. Drop webdevops/ansible from conf/diagram.yml.
README, AGENTS.md and the build-tools known issue describe the
remaining targets.
- Move the sponge check from the ubuntu-22.04 structure-test suite to
  serverspec, conditional on Ubuntu, so it does not depend on the tag
  name. build.yaml is regenerated.
- Remove the PATH check from the bootstrap alpine suite; the common
  test.yaml has it.
- tests/structure-test/run.sh: test every directory with a test.yaml
  (php-dev and php-nginx were missing) and exit non-zero if any image
  fails, not only the last one.
- 20-php-module-blackfire.sh only deleted files under /etc/php5.
- logrotate.d/php5-fpm rotated /var/log/php5-fpm/*, which does not
  exist.
- 10-php.sh (dev) and 20-setup-php-fpm.sh: drop the branches for PHP
  older than 5.6; the [::]:9000 listen line now runs unconditionally,
  as it already did for every built image.
- Keep list as the first target, so a bare make lists the targets
  instead of running setup.
- README, AGENTS.md and the build-tools known issue name graph-full,
  AGENTS.md says which images make structure-test and the CI test.
- 20-setup-php-fpm.sh removed the literal file "PHP_MAIN_CONF" instead
  of $PHP_MAIN_CONF.
- clear_env exists in all supported PHP versions, so the workaround for
  PHP-FPM without it (PHP_CLEAR_ENV_AVAILABLE, 11-clear-env.sh) is gone.
- PHP_VERSION in 10-php-init.sh was not used; 30-setup-ioncube.sh sets
  its own.
- opcache.fast_shutdown no longer exists since PHP 7.2; it is removed
  from php.webdevops.ini and from the development settings.
- The structure tests name what 10-php-init.sh and 11-php-conf.sh do.
- .editorconfig no longer has sections for DOCKER_REPOSITORY and
  DOCKER_TAG_LATEST, which do not exist.
- `make` no longer prints "No rule to make target 'no_targets__'".
Nginx listens on [::]:80 and [::]:443, PHP-FPM in php, php-dev,
php-nginx-dev and php-apache-dev on [::]:9000. Without IPv6 in the
container both failed with "Address family not supported by protocol"
and supervisord restarted them over and over.

If /proc/net/if_inet6 does not exist, the start scripts now remove the
listen [::] lines from the Nginx files and let PHP-FPM listen on
0.0.0.0 instead of [::]. With IPv6 nothing changes. A file that cannot
be changed, for example one mounted read-only, gets a warning instead
of stopping the container.

The known issue is removed; the image pages say how Nginx and PHP-FPM
listen, and the configuration file section mentions read-only Nginx
files with listen [::].
- tests/structure-test/run.sh tests only the tags that the CI builds
  (the -t "webdevops/..." lines in build.yaml), so old local tags no
  longer fail the run. It fails if docker cannot list the images or if
  no image was tested, instead of exiting 0.
- base-app::moreutils also runs on Debian, so the PHP images on Debian
  check sponge as well.
- The build tools known issue names which images the CI tests and shows
  make structure-test as the local check; AGENTS.md describes the new
  behaviour.
sed -i writes a temporary file and renames it over the original. For a
single file mounted read-write, for example ./vhost.conf mounted to
/opt/docker/etc/nginx/vhost.conf, the rename fails with "Device or
resource busy", so Nginx still did not start without IPv6. A file in a
mounted directory was replaced by a new file.

The start scripts now write the result back into the same file, as
go-replace does for the placeholders. In a read-write mount the listen
lines change on the host as well; a file mounted :ro still gets the
warning, and Nginx or PHP-FPM does not start.
PHP-FPM listens on the port only (listen = 9000) instead of [::]:9000.
PHP-FPM then binds to :: itself and falls back to 0.0.0.0 if the
container has no IPv6, so the rewrite at start is gone. With IPv6 the
socket is the same as before: neither form sets IPV6_V6ONLY.

Without IPv6, the Nginx start script now changes only files in the
container's own file system, such as the image's vhost.conf and files
added with COPY. Mounted files (bind mounts, volumes, ConfigMaps) are
never changed, so a developer without IPv6 does not lose the listen [::]
lines in the project; a warning names the file instead. Warnings go to
stderr, because the provisioning output is discarded unless the
container runs supervisord or noop.

The loop reads find -print0 with its own variable names instead of
overwriting FILE of includeScriptDir, follows symlinks (ConfigMaps), and
skips hidden directories such as ..data, so every file is handled once.
latest and ubuntu-22.04 of bootstrap, base and base-app are the same
image; run.sh tested them twice when both tags existed locally. A tag
whose image and suites were already tested is now skipped with a note.

The error message for "no image tested" lists the suites from an array
instead of an unquoted $(ls ...) (shellcheck SC2046).
Since webdevops#596 the documentation shows how the images build on each other
as a Mermaid diagram; nothing uses the Graphviz image anymore.

Removed: conf/diagram.yml, the generate:graph command and its
registration in bin/console, the Makefile targets graph and graph-full,
imagePath and graph.label in conf/console.yml (and imagePath in the path
list of bin/console and the defaults of Configuration.py), graphviz in
bin/requirements.txt and in the dockerfile-build-env image, and /graph
in .gitignore. README, AGENTS.md and the build tools known issue name
make provision as the only Python 2 target.
Nginx has no fallback like PHP-FPM: listen [::] fails without IPv6, also
with ipv6only=off. Instead of searching all configuration files and
leaving mounted ones alone, the two listen [::] directives of the
default vhost now live in vhost.ipv6/listen-80.conf and listen-443.conf.
vhost.conf includes them with a wildcard, so missing files are fine,
and the start script only deletes these files if the container has no
IPv6. No other file is changed; a file of one's own with listen [::]
keeps nginx from starting without IPv6, as before.
serverspec now checks the vhost.ipv6 directory, that vhost.conf
includes listen-80.conf and listen-443.conf, and the two files with
their listen [::] directives, so the CI notices if they are missing in
an image. The start script deletes the files if the kernel has no IPv6;
serverspec runs on the Docker host, which shares its kernel with the
container, so without IPv6 the test expects the files to be gone.
run.sh uses declare -A and mapfile, which need Bash 4. With the Bash
3.2 of macOS, make structure-test failed with "declare: -A: invalid
option" and "mapfile: command not found". The script now checks the
version first and points to webdevops/dockerfile-build-env, and it runs
the first bash in PATH instead of /bin/bash.
@sonarqubecloud

sonarqubecloud Bot commented Nov 8, 2026

Copy link
Copy Markdown

@Kanti
Kanti marked this pull request as ready for review November 9, 2026 06:26
@Kanti
Kanti merged commit 2887b7b into webdevops:master Nov 9, 2026
177 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

Development

Successfully merging this pull request may close these issues.

1 participant