Skip to content

Draft for new Structure

DracoBlue edited this page Jan 4, 2023 · 78 revisions

We want to create a new version of this at a new location (under endavas organization).

Todo List for the Draft

Simplifications

Some simplifications (to decrease compatibility issues):

  1. only has to look good for 8.x upwards
  2. does not need to be without breaking changes compared to exozet/php-fpm docker image
  3. xdebug3 can be activated with XDEBUG_MODE, so no tag with -xdebug necessary anymore
  4. remove composer version 1

Wishes

  1. an alpine and debian based image ✅
  2. the possibility to run php-fpm in combination with nginx (like we do so far) ✅
  3. the possibility to run nunit https://docs.nunit.org/
  4. start-cron binary for docker-compose like setups for cronjobs ✅
  5. non-sudo/non-root version with www-data user ✅
  6. sudo version with www-data user and sudo rights ✅
  7. root version with root user ✅
  8. use environment variables to configure php.ini values ✅
  9. arm64/amd64 image ✅
  10. use dependabot or similar feature:
  • for automatic PR creation to upgrade to new minor versions (does work only for FROM images, not for apk packages)
  • daily security scanning
  1. the php ini ability to set via environment variable could be pulled and generated for every .ini configuration via (-n for ignoring .ini files!)
php -n -r 'foreach (ini_get_all(null, true) as $key => $value) echo "$key=$value[global_value];\n";'
  1. autogenerate the extensions versions for the README.md (e.g. https://github.com/exozet/draft-docker-php/releases/tag/8.1.13)
$extensionNames = get_loaded_extensions();
sort($extensionNames);

foreach ($extensionNames as $extensionName) {
	$ext = new ReflectionExtension($extensionName);
	echo " o $extensionName " . $ext->getVersion() . PHP_EOL;
}

Tag Structure

Proposal for the Tag-Structure for one Version 8.1.12:

  • endava/php:8.1.12
  • endava/php:8.1.12-alpine
  • endava/php:8.1.12-root-alpine
  • endava/php:8.1.12-sudo-alpine

Entrypoint

  • bash (default)
  • start-cron
  • unitd (for nginx unit)
  • httpd (for apache2)
  • php-fpm

Dockerfile Version

We can use latest version in FROM to make it possible for dependabot to see if we are on latest:

FROM php:8.1.0-fpm-alpine AS base

Dockerfile Template

We could use a Dockerfile in like this way:

FROM php:8.1.0-fpm-alpine AS base

# IF $SUDO == "true"
RUN apk add --no-cache sudo
RUN sed -i 's/\/home\/www-data:\/sbin\/nologin/\/home\/www-data:\/bin\/bash/' /etc/passwd
RUN echo "www-data ALL = NOPASSWD: ALL" > /etc/sudoers.d/www-data'
# ENDIF

and when we are building the Dockerfile as a whole we generate the Dockerfile-sudo, Dockerfile-root from this. And dependabot can use the Dockerfile itself to see updates.

Repo Structure

Approach #1 folder based

  • a folder 8.1 with a Dockerfile

Approach #2 branch based)

  • branch for each minor version (e.g. release/8.1)
  • includes a Dockerfile

Proposal to go for #2 Branch Based:

  • we use the branch based approach
  • the Dockerfile can be significant different
  • we can make branches stale as soon as EOL of the php version is reached
  • main branch shall be used to document the availability in each of the branches and it's current state

Base for the Image

We figured 3 different ways to create a base for the image:

  • PHPBASE: Base debian+alpine version on the official one at https://hub.docker.com/_/php/
  • PHPBASECOMPILEEMBED: Base debian+alpine version on the official one at https://hub.docker.com/_/php/ but patch the alpine build for -embed support
    • Advantages
      • makes nginx unit variant possible
    • Disadvantages
      • custom compilation
  • ALPINEPACKAGES: Base it on official alpine repository and packages
    • Advantages
      • docker-php-ext-configure + docker-php-ext-install and so on are not necessary anymore
      • apache2 and nginx unit exist as package
      • latest unit:
        • 1.29.0-r0 in edge
        • 1.28.0-r0 in 3.17
        • 1.26.1-r3 in 3.16
        • 1.26.1-r0 in 3.15
        • 1.23.0-r1 in 3.14
        • 1.22.0-r0 in 3.13
        • 1.17.0-r2 in 3.12
        • 1.12.0-r1 in 3.11
        • 1.8.0-r3 in 3.10
        • 1.6-r0 in 3.9
        • 1.2-r0 in 3.8
      • latest unit-php7 (starting 3.8 until 3.15)
      • latest unit-php8 (only in 3.16)
      • latest unit-php81 (starting 3.17)
      • latest php82 (8.2.0-r0 in edge)
      • latest php81 (8.1.13-r0 in 3.16)
      • latest php8 (8.0.26-r0 in 3.16, 8.0.25-r0 in 3.15, 8.0.24-r0 in 3.14, 8.0.13-r0 in 3.13)
      • latest php7 (7.4.33-r0 in 3.15, 7.4.26-r0 in 3.14, 7.3.33-r0 in 3.12, 7.3.22-r0 in 3.11, 7.3.14-r0 in 3.10, 7.2.33-r0 in 3.9, 7.2.26-r0 in 3.8, 7.1.33-r0 in 3.7, 7.1.17-r0 in 3.6, 7.0.33-r0 in 3.5)
      • latest php5 (5.6.40-r0 in 3.6, 5.6.40-r0 in 3.5, 5.6.36-r0 in 3.4)
      • latest php82-pecl-protobuf (3.21.12-r0 in edge community)
      • latest php81-pecl-protobuf (starting 3.17)
      • latest php8-pecl-protobuf (starting in 3.15 until 3.16)
      • latest php7-pecl-protobuf (starting in 3.10 until 3.16)
      • latest php82-pecl-grpc+php81-pecl-grpc+php8-pecl-grpc+php7-pecl-grpc (1.51.1-r0 in edge testing)
    • Disadvantages
      • different to the official debian / alpine image
      • alpine repositories have old patch versions of x.y.PATCH available (only latest!)

scan images for sbom

$ trivy image --format cyclonedx --output result.json endava/php:8.1.12

stopsignal directive

The signal for shutting down the process is depend on the process type. Thus we might need to define which of them fits best.

command SIGQUIT SIGTERM SIGINT SIGWINCH Link
php-fpm graceful immediate immediate https://github.com/php/php-src/blob/17baa87faddc2550def3ae7314236826bc1b1398/sapi/fpm/php-fpm.8.in#L163
apache2 immediate graceful https://httpd.apache.org/docs/2.4/en/stopping.html
unitd graceful immediate immediate https://github.com/nginx/unit/blob/f67a01b88fd7c7057767e18a3dd06c24e94c8aa8/src/nxt_main_process.c#L66

Thoughts

Thoughts on realization of this topic:

  1. there is a basic image for nginx unit php based on ubuntu at https://github.com/nginx/unit/blob/master/pkg/docker/Dockerfile.php8.1 (but non for alpine)
  2. there is a nginx unit package at https://pkgs.alpinelinux.org/package/edge/community/x86/unit for alpine, with php support
  3. alpine version of nginx unit depends on https://github.com/docker-library/php/pull/1355 to have embed api also available in cli
  4. we could use abuild https://wiki.alpinelinux.org/wiki/Creating_an_Alpine_package and inspire by https://git.alpinelinux.org/aports/tree/community/unit/APKBUILD?id=0e1eed69c61637ff09c8d5756886dc4dac7f2fa6 for unit package and https://git.alpinelinux.org/aports/tree/community/php81/APKBUILD?id=0e1eed69c61637ff09c8d5756886dc4dac7f2fa6 for php81-embed
  5. https://github.com/docker/build-push-action can be used for multi build
  6. release schedule alpine and end of life https://alpinelinux.org/releases/
  7. release schedule and end of life php https://www.php.net/supported-versions.php
Clone this wiki locally