Docker Official Image packaging for PHP
MIT License
3282
283
1982

I want my container to run Apache and process PHP scripts using FastCGI / mod_fcgid (not mod_php).

I can start from a debian Docker image and apt-install all the thing (apache2, libapache2-mod-fcgid, php-cgi) but the php:<version>-apache variant has all the integrated tooling to run Apache in a Docker container so it would be a shame not to use it :)

Basically I need php:<version>-apache image with the cgi-fcgi binary (php-cgi Debian package).

So I tried staring from php:<version>-apache with a2enmod fcgid && a2dismod php7 but I can't get the php-cgi binary (only tried using the php-cgi Debian package).

Removing the /etc/apt/preferences.d/no-debian-php file as documented allows the install of php-cgi package but also brings the other php-* Debian packages, even the one already installed with install-php-extensions which I am pretty sure is not recommended…

Is there a solution in the php:<version>-apache Docker image or should I go for:

  • php:<version>-cli variant, apt-install Apache and get a copy of the /usr/local/bin/docker-php-entrypoint?
  • or even from httpd Docker image and apt-get install the PHP stuff?

Following the documentation merged with #1000 to set a custom APACHE_DOCUMENT_ROOT, I can't seem to get it to work. Dockerfile:

FROM php:7.1-apache

ENV APACHE_DOCUMENT_ROOT /var/www/html/subfolder

RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf

This is the exact example from the documentation under Changing DocumentRoot (or other Apache configuration). However, when I start it with the following command:

docker run --rm -it -p 8082:80 -v /user/magiclegend/codebase:/var/www/html/subfolder e785 /bin/bash
e785 being the start of the hash from the container

This results in the following:

root@9d9c344ec804:/var/www/html# service apache2 status
[FAIL] apache2 is not running ... failed!
root@9d9c344ec804:/var/www/html# service apache2 restart
[....] Restarting Apache httpd web server: apache2[Mon Nov 09 12:33:30.914062 2020] [core:warn] [pid 51] AH00111: Config variable ${APACHE_DOCUMENT_ROOT} is not defined
[Mon Nov 09 12:33:30.914235 2020] [core:warn] [pid 51] AH00111: Config variable ${APACHE_DOCUMENT_ROOT} is not defined
[Mon Nov 09 12:33:30.914410 2020] [core:warn] [pid 51] AH00111: Config variable ${APACHE_DOCUMENT_ROOT} is not defined
AH00112: Warning: DocumentRoot [/etc/apache2/${APACHE_DOCUMENT_ROOT}] does not exist
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Mon Nov 09 12:33:30.926900 2020] [core:warn] [pid 51] AH00111: Config variable ${APACHE_DOCUMENT_ROOT} is not defined
[Mon Nov 09 12:33:30.927007 2020] [core:warn] [pid 51] AH00111: Config variable ${APACHE_DOCUMENT_ROOT} is not defined
[Mon Nov 09 12:33:30.927151 2020] [core:warn] [pid 51] AH00111: Config variable ${APACHE_DOCUMENT_ROOT} is not defined
. ok 
root@9d9c344ec804:/var/www/html# echo $APACHE_DOCUMENT_ROOT
/var/www/html/subfolder/

Is this documentation (or the example) incorrect? It states that the variable "can then be modified at container runtime as well". However, reading up on apache2 configuration, apache does not read runtime variables (without any trickery). Source

How is this supposed to function? Is this documentation outdated/broken?

I have previously put this issue in the global docker docs repo, my bad. I had not noticed that I had switched repos.

Since the PHP 8.1.9 update, i'm encountering errors where the pool user (www-data) cannot write the error_log to /proc/self/fd/2 anymore.
This problem does not occur with PHP 8.1.8

We have our PHP base image, that uses php:8.1-fpm-alpine, we set our pool user to www-data in the correct configuration file.
We also set error_log to /proc/self/fd/2.

This image works without any problems.

Now we want to build a project specific image that uses our own PHP base image, with the difference that we change the user ID of www-data from 1000 to 1001.
After this we chown some log and project files, but that's it.
In this new container PHP-FPM cannot start anymore, because of write permissions to /proc/self/fd/2

Again, this problem does not occur with PHP 8.1.8

After updating (from non-Docker PHP 5) to PHP 7.4 in Docker, I was experiencing performance problems with resizing images using ImageMagick. (Details: https://serverfault.com/q/1045274/31887.) After some trial-and-error, it seems that some ImageMagick performance issue is present starting in PHP 7.1 when using the Docker image.

Test script & environment

To investigate the issue, I’ve made the following simple script, with a ~2MB JPEG as input, which resizes the image and prints the time taken for each step:

<?php

$image_name = "imgbench.jpeg";
$image_size = 4000;
$image_quality = 50;

echo "PHP version: " . phpversion() . PHP_EOL;

$start = $step = microtime(true);

function bench($msg, $total = false) {
	global $start, $step;
	$prev = $total ? $start : $step;
	$now = microtime(true);
	echo number_format($now - $prev, 2) . " seconds - " . $msg . PHP_EOL;
	$step = $now;
}

$image = new Imagick(); bench("init");
$image->readImage($image_name); bench("read");
$image->stripImage(); bench("strip");
$image->resizeImage($image_size, $image_size, Imagick::FILTER_LANCZOS, 1, true); bench("resize");
$image->setImageCompressionQuality($image_quality); bench("compress");
$image->setInterlaceScheme(Imagick::INTERLACE_JPEG); bench("interlace");
$image_blob = $image->getImageBlob(); bench("blob");
bench("TOTAL", true);

I created a new AWS EC2 t3.medium instance with the Amazon Linux AMI and installed Docker using sudo yum install docker. Then, I built the following Dockerfile (using docker build -t imgbench .; with [version] substituted by some valid version):

FROM php:[version]
COPY --from=mlocati/php-extension-installer /usr/bin/install-php-extensions /usr/bin/
RUN install-php-extensions imagick
COPY ./ ./

Finally, I ran the test script from above using docker run -it imgbench php imgbench.php.

All the files used for this test, can be found here: imgbench.zip.

Results

I obtained the following output/results:

PHP 7.0: ~2s PHP 7.1: ~19s PHP 7.2: ~19s PHP 7.3: ~19s PHP 7.4: ~19s
PHP version: 7.0.33 PHP version: 7.1.33 PHP version: 7.2.34 PHP version: 7.3.25 PHP version: 7.4.13
0.00 seconds - init 0.00 seconds - init 0.00 seconds - init 0.00 seconds - init 0.00 seconds - init
0.25 seconds - read 0.21 seconds - read 0.15 seconds - read 0.16 seconds - read 0.15 seconds - read
0.00 seconds - strip 0.00 seconds - strip 0.00 seconds - strip 0.00 seconds - strip 0.00 seconds - strip
0.94 seconds - resize 18.10 seconds - resize 18.07 seconds - resize 17.99 seconds - resize 18.37 seconds - resize
0.00 seconds - compress 0.00 seconds - compress 0.00 seconds - compress 0.00 seconds - compress 0.00 seconds - compress
0.00 seconds - interlace 0.00 seconds - interlace 0.00 seconds - interlace 0.00 seconds - interlace 0.00 seconds - interlace
0.65 seconds - blob 0.56 seconds - blob 0.56 seconds - blob 0.55 seconds - blob 0.59 seconds - blob
1.84 seconds - TOTAL 18.87 seconds - TOTAL 18.78 seconds - TOTAL 18.71 seconds - TOTAL 19.12 seconds - TOTAL

It is clear that starting from PHP 7.1, something is wrong with the performance of the \Imagick::resizeImage() operation, since it’s approximately 10 times slower than in PHP 7.0.

Other factors

I also ran the test script on the same instance without Docker (using PHP from sudo yum -y install php70-cli php70-common php70-pecl-imagick) for PHP 7.0, 7.1, and 7.2. All versions showed similar (good) performance, indicating that the problem is not related to the PHP version itself, but rather something in the Docker image.

Also, I tried a Dockerfile without using install-php-extensions from mlocati/php-extension-installer, by installing ImageMagick manually in the Dockerfile:

RUN apt-get update \
	&& apt-get install -y libmagickwand-dev \
	&& pecl install imagick-3.4.4 \
	&& docker-php-ext-enable imagick

This yielded similar performance as reported above (i.e., good performance on PHP 7.0, and bad performance on newer versions).

Hi,

1 month ago I reported an issue in Stack Overflow: https://stackoverflow.com/q/72966421

I think this may be an issue in the Docker image (rather than a Debian/Apache issue).

I'm using latest PHP 8.1 alpine image with the following sendmail version:

/magento # sendmail --help
BusyBox v1.34.1 (2022-07-19 20:11:24 UTC) multi-call binary.

The mail function sends headers and body with \r\n line delimiters according to standards and passes this data to sendmail. But sendmail converts all line-endings to \r\r\n making the whole mail broken.

A related issue in the PHP repo: php/php-src#8086 (closed as PHP does everything correctly).

(This is a follow-up of monicahq/docker#109)

I see in a Dockerfile some effort is made to remove unused packages. But inspecting the resulting image, some packages seem questionable for a production image, for example autoconf, make, curl (command-line tool), dpkg-dev, gcc.
Those would be acceptable for an build-stage image where only required stuff would be installed/copied in the production-stage image. Furthermore, cleaning unused packages from a build-stage image would be pointless, so the apt-mark part would not even be needed.

% docker run --rm --entrypoint /bin/sh -it php:8.1-fpm -c "apt-mark showmanual"
autoconf
ca-certificates
curl
dpkg-dev
file
g++
gcc
libargon2-1
libbrotli1
libc6
libc6-dev
libcom-err2
libcurl4
libffi7
libgcc-s1
libgcrypt20
libgmp10
libgnutls30
libgpg-error0
libgssapi-krb5-2
libhogweed6
libicu67
libidn2-0
libk5crypto3
libkeyutils1
libkrb5-3
libkrb5support0
libldap-2.4-2
liblzma5
libnettle8
libnghttp2-14
libonig5
libp11-kit0
libpsl5
libreadline8
librtmp1
libsasl2-2
libsodium23
libsqlite3-0
libssh2-1
libssl1.1
libstdc++6
libtasn1-6
libtinfo6
libunistring2
libxml2
make
pkg-config
re2c
xz-utils
zlib1g

The latest PHP images based on Alpine Linux now use Alpine Linux v3.16.

In v3.16, Alpine Linux has split the ICU package in two: icu-data-en and icu-data-full.

Only the icu-data-en package is now installed by default. The Alpine Linux changelog mentions this as well:

icu-libs only installs icu-data-en. If additional language support is required, icu-data-full needs to be installed manually. 
# apk list | grep -i icu
icu-libs-71.1-r2 x86_64 {icu} (MIT ICU Unicode-TOU) [installed]
icu-data-en-71.1-r2 x86_64 {icu} (MIT ICU Unicode-TOU) [installed]

This results in the following code not working as expected:

<?php

echo locale_get_display_name('ja', 'ja');

This now yields the output Japanese instead the expected 日本語. Other locale-related methods will probably also be affected.

Would the Alpine-based PHP images want to include the icu-data-full package by default? Or is this package expected/intended to be not installed by default?

See

Hello,

I just came across the PR #1259 and the issue #1257 after wondering why the phpdbg has suddenly disappeared from images like php:7.4-fpm-alpine3.14.

While I understand the point of "It is not suitable to debug fpm processes" the images can still be used with the PHP CLI, and thus, having the need for the phpdbg component. In our case we use the production build to run all tests and generate code coverage, and only install dev dependecies on start of the container. We also use the fpm image to run async workers without fpm started)

The use of phpdbg allows faster tests and not having to instal xdebug specifically for this (which would slow drastically any process).

Leaving it will not impact any existing user as it does not provide (AFAIK) any slowness when not used and will save people time, headache, and allow easier testing.

Thanks

Hello everyone.
I'm here to talk about an issue that caused me a big headache for a day.
Curl is not working good with my Mac air with some urls (not all): it goes in segmentation fault.

My pc: MacBook Air with M1 processor.
Dockerimage:

FROM php:7.4.1-apache

USER root

WORKDIR /var/www/html

RUN apt-get update && apt-get install -y \
        libpng-dev \
        zlib1g-dev \
        libxml2-dev \
        libzip-dev \
        libonig-dev \
        zip \
        curl \
        unzip \
    && docker-php-ext-configure gd \
    && docker-php-ext-install -j$(nproc) gd \
    && docker-php-ext-install pdo_mysql \
    && docker-php-ext-install mysqli \
    && docker-php-ext-install zip \
    && docker-php-source delete \
    && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
    && chown -R www-data:www-data /var/www/html \
    && a2enmod rewrite \
    && pecl install grpc \ 
    && docker-php-ext-enable grpc

COPY .docker/vhost.conf /etc/apache2/sites-available/000-default.conf
COPY ../. .
COPY ./startup_script.sh /tmp

WORKDIR /var/www/html/public/template_html

RUN curl -O -L https://github.com/ggiorginogrifo/templateEB/archive/refs/heads/main.zip \
    && unzip main.zip \
    && cp templateEB-main/* -r . \
    && rm  *.zip templateEB-main -rf

RUN useradd -ms /bin/bash www-deploy \ 
&& usermod -aG www-data www-deploy

USER www-deploy
WORKDIR /var/www/html

RUN mkdir -p bootstrap \
    && mkdir -p bootstrap/cache \
    && chmod 775 bootstrap -R \
    && /usr/local/bin/composer i \
    && cp resources/fonts vendor/szymach/c-pchart/resources -r

USER root

ENTRYPOINT ["/tmp/startup_script.sh"]

I tried also to gdb curl call but nothing relevant comes in output.

If I try to call
curl -i -X GET "https://graph.facebook.com/facebook/picture?redirect=false" I get segmentation fault.
It goes instead in success if I call https://www.google.com

Curl -V output:
Schermata 2021-06-29 alle 17 05 04

Also, this is the docker-compose.yml file content:


version: '3.7'
services: 
    db: 
        container_name: mysql_container
        platform: linux/x86_64
        image: mysql
        restart: always
        ports: 
            - 3306:3306
        environment:
            MYSQL_USER: "${DB_USERNAME}"
            MYSQL_PASSWORD: "${DB_PASSWORD}"
            MYSQL_DATABASE: "${DB_DATABASE}"
            MYSQL_ALLOW_EMPTY_PASSWORD: 1
            MYSQL_ROOT_PASSWORD: ""

        volumes:
            - ./db:/var/lib/mysql
        networks:
            - app-network
    app:
        container_name: laravel_container
        build:
            context: .
            dockerfile: .docker/Dockerfile
        ports:
            - 8000:8000
        depends_on:
            - db
        volumes:
            - ./:/var/www/html
        networks:
            - app-network
networks:
    app-network:
        driver: bridge

Could someone help me with this problem?
Also: I've read on docker official site that older libssl could cause segmentation fault, in fact I've tried to create an ubuntu:21.10 based image and the same call works.

P.S.
Sorry if my explanation maybe would be not so clear, ask me anything that could help you.

Hi
I got a collection of docker containers running a variety of versions from php 7.4 to 8.1. I have encountered an intermittent problem where sometimes nginx cannot connect to the fastcgi worker with the error recv() failed (104: Connection reset by peer). The only solution is to restart the container. I am able to bash exec into the container. What debugging steps should I perform next?

I have an error when I use "FROM php:8.1-apache" and try to install oci8 for oracle.

I follow these steps;

  1. download from oracle https://download.oracle.com/otn_software/linux/instantclient/216000/instantclient-basic-linux.x64-21.6.0.0.0dbru.zip and https://download.oracle.com/otn_software/linux/instantclient/216000/instantclient-sdk-linux.x64-21.6.0.0.0dbru.zip
  2. unzip instantclient-basic-linux.x64-21.6.0.0.0dbru.zip and instantclient-sdk-linux.x64-21.6.0.0.0dbru.zip in folder /opt/oracle/instantclient
  3. launch command echo 'instantclient,/opt/oracle/instantclient' | pecl install oci8-3.2.1

After this command there is an error: Fatal error: Uncaught Error: Call to undefined function exec() in /usr/local/lib/php/PEAR/Builder.php:465

[...]
Build complete.
Don't forget to run 'make test'.

running: make INSTALL_ROOT="/tmp/pear/temp/pear-build-defaultuservlzPxQ/install-oci8-3.2.1" install
Installing shared extensions:     /tmp/pear/temp/pear-build-defaultuservlzPxQ/install-oci8-3.2.1/usr/local/lib/php/extensions/no-debug-non-zts-20210902/
running: find "/tmp/pear/temp/pear-build-defaultuservlzPxQ/install-oci8-3.2.1" | xargs ls -dils
4719924   4 drwxr-xr-x 3 root root   4096 Jul 25 14:36 /tmp/pear/temp/pear-build-defaultuservlzPxQ/install-oci8-3.2.1
4719961   4 drwxr-xr-x 3 root root   4096 Jul 25 14:36 /tmp/pear/temp/pear-build-defaultuservlzPxQ/install-oci8-3.2.1/usr
4719962   4 drwxr-xr-x 3 root root   4096 Jul 25 14:36 /tmp/pear/temp/pear-build-defaultuservlzPxQ/install-oci8-3.2.1/usr/local
4719963   4 drwxr-xr-x 3 root root   4096 Jul 25 14:36 /tmp/pear/temp/pear-build-defaultuservlzPxQ/install-oci8-3.2.1/usr/local/lib
4719964   4 drwxr-xr-x 3 root root   4096 Jul 25 14:36 /tmp/pear/temp/pear-build-defaultuservlzPxQ/install-oci8-3.2.1/usr/local/lib/php
4719965   4 drwxr-xr-x 3 root root   4096 Jul 25 14:36 /tmp/pear/temp/pear-build-defaultuservlzPxQ/install-oci8-3.2.1/usr/local/lib/php/extensions
4719966   4 drwxr-xr-x 2 root root   4096 Jul 25 14:36 /tmp/pear/temp/pear-build-defaultuservlzPxQ/install-oci8-3.2.1/usr/local/lib/php/extensions/no-debug-non-zts-20210902
4719960 828 -rwxr-xr-x 1 root root 844024 Jul 25 14:36 /tmp/pear/temp/pear-build-defaultuservlzPxQ/install-oci8-3.2.1/usr/local/lib/php/extensions/no-debug-non-zts-20210902/oci8.so

Fatal error: Uncaught Error: Call to undefined function exec() in /usr/local/lib/php/PEAR/Builder.php:465
Stack trace:
#0 /usr/local/lib/php/PEAR/Installer.php(1521): PEAR_Builder->build('/tmp/pear/temp/...', Array)
#1 /usr/local/lib/php/PEAR/Installer.php(1416): PEAR_Installer->_compileSourceFiles('pecl.php.net', Object(PEAR_PackageFile_v2), '')
#2 /usr/local/lib/php/PEAR/Command/Install.php(718): PEAR_Installer->install('/tmp/pear/downl...', Array)
#3 /usr/local/lib/php/PEAR/Command/Common.php(270): PEAR_Command_Install->doInstall('install', Array, Array)
#4 /usr/local/lib/php/pearcmd.php(310): PEAR_Command_Common->run('install', Array, Array)
#5 /usr/local/lib/php/peclcmd.php(32): require_once('/usr/local/lib/...')
#6 {main}
  thrown in /usr/local/lib/php/PEAR/Builder.php on line 465

The same command with php7.4-apache echo 'instantclient,/opt/oracle/instantclient' | pecl install oci8-2.2.0 works.

Hello,
I have an issue that is unremitting. If you could have please a look.
Using php:7.4.30-apache-buster

<IfModule mod_ssl.c>
	<VirtualHost _default_:443>
		ServerAdmin webmaster@localhost
		DocumentRoot ${LaravelProject}/public

		<Directory />
			Options FollowSymLinks
			AllowOverride All
			Require all granted
		</Directory>

		ErrorLog ${APACHE_LOG_DIR}/error.log
		CustomLog ${APACHE_LOG_DIR}/access.log combined

		SSLEngine on

		SSLCertificateFile /etc/ssl/certs/cert.crt
		SSLCertificateKeyFile /etc/ssl/private/cert.key

		<FilesMatch "\.(cgi|shtml|phtml|php)$">
				SSLOptions +StdEnvVars
		</FilesMatch>
		<Directory /usr/lib/cgi-bin>
				SSLOptions +StdEnvVars
		</Directory>

	</VirtualHost>
</IfModule>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

I pasted the damnable files and checked, they exist. This is Debian there's no SELinux stuff SO talks about. Yet it doesn't work for some reason. It works on Fedora using exactly same code.

Is this something Docker related or smth I am missing?
Thanks

I'd like submit a pr of that,
I want install parallel extension in docker contianer, and find out that the php version of fpm is nts
Also for pthread extension
I can't find any discuss of zts in issues.
If there is no, I will close this issue.

Hi!

There is currently an openssl issue that is fixed in upstream alpine-3.16, but updating the package in later layers won't help because the php build process seems to compile some part of the library in.

Please rebuild your images so this gets fixed.

More generally...

Would it be possible to add a github action to build and push the docker images on a daily basis? That'd automatically pick up any security and bug fixes from upstream.

Thank you!

Hi Team,

Issue: the docker image of php:fpm-alpine3.16 (https://hub.docker.com/layers/php/library/php/fpm-alpine3.16/images/sha256-a35b951f68dfc3183dd7f9451c6cd21ef2ab5de4ab48bb0e4aac15d8c2cba6ff?context=explore) contains a critical CVE vulnerability found in curl-7.83.1-r1, showing in a Prisma scan job.

When are we updating curl to >= 7.84.0 for https://github.com/docker-library/php/blob/master/7.4/alpine3.16/cli/Dockerfile#L25?

  • Steps to reproduce: docker run -it --pull=always --platform=linux/amd64 --rm php:fpm-alpine3.16 apk info curl
  • Output:
fpm-alpine3.16: Pulling from library/php
Digest: sha256:89881cd27b91a91881bc782a29508fbe327ceeb12bff7bdd07c1b5ba9970c838
Status: Image is up to date for php:fpm-alpine3.16
WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.16/main: No such file or directory
WARNING: Ignoring https://dl-cdn.alpinelinux.org/alpine/v3.16/community: No such file or directory
curl-7.83.1-r1 description:
URL retrival utility and library

curl-7.83.1-r1 webpage:
https://curl.se/

curl-7.83.1-r1 installed size:
256 KiB