Git Product home page Git Product logo

docker-images-php's Introduction

Docker PHP Images GitHub workflow

General purpose PHP images for Docker

This repository contains a set of developer-friendly, general purpose PHP images for Docker.

  • You can enable or disable the extensions using environment variables.
  • You can also modify the php.ini settings using environment variables.
  • 2 types available: slim (no extensions preloaded) or fat (most common PHP extensions are built-in)
  • 3 variants available: CLI, apache and fpm
  • Fat images are bundled with Supercronic which is a Cron compatible task runner. Cron jobs can be configured using environment variables
  • Fat images come with Composer and Prestissimo installed
  • All variants can be installed with or without NodeJS (if you need to build your static assets).
  • Everything is done to limit file permission issues that often arise when using Docker. The image is actively tested on Linux, Windows and MacOS

Images

Name PHP version type variant NodeJS version Size
thecodingmachine/php:8.3-v4-apache 8.3.x fat apache N/A
thecodingmachine/php:8.3-v4-apache-node10 8.3.x fat apache 10.x(2)
thecodingmachine/php:8.3-v4-apache-node12 8.3.x fat apache 12.x
thecodingmachine/php:8.3-v4-apache-node14 8.3.x fat apache 14.x
thecodingmachine/php:8.3-v4-apache-node16 8.3.x fat apache 16.x
thecodingmachine/php:8.3-v4-apache-node18 8.3.x fat apache 18.x
thecodingmachine/php:8.3-v4-apache-node20 8.3.x fat apache 20.x
thecodingmachine/php:8.3-v4-fpm 8.3.x fat fpm N/A
thecodingmachine/php:8.3-v4-fpm-node10 8.3.x fat fpm 10.x(2)
thecodingmachine/php:8.3-v4-fpm-node12 8.3.x fat fpm 12.x
thecodingmachine/php:8.3-v4-fpm-node14 8.3.x fat fpm 14.x
thecodingmachine/php:8.3-v4-fpm-node16 8.3.x fat fpm 16.x
thecodingmachine/php:8.3-v4-fpm-node18 8.3.x fat fpm 18.x
thecodingmachine/php:8.3-v4-fpm-node20 8.3.x fat fpm 20.x
thecodingmachine/php:8.3-v4-cli 8.3.x fat cli N/A
thecodingmachine/php:8.3-v4-cli-node10 8.3.x fat cli 10.x(2)
thecodingmachine/php:8.3-v4-cli-node12 8.3.x fat cli 12.x
thecodingmachine/php:8.3-v4-cli-node14 8.3.x fat cli 14.x
thecodingmachine/php:8.3-v4-cli-node16 8.3.x fat cli 16.x
thecodingmachine/php:8.3-v4-cli-node18 8.3.x fat cli 18.x
thecodingmachine/php:8.3-v4-cli-node20 8.3.x fat cli 20.x
thecodingmachine/php:8.3-v4-slim-apache 8.3.x slim apache N/A
thecodingmachine/php:8.3-v4-slim-fpm 8.3.x slim fpm N/A
thecodingmachine/php:8.3-v4-slim-cli 8.3.x slim cli N/A
thecodingmachine/php:8.2-v4-apache 8.2.x fat apache N/A
thecodingmachine/php:8.2-v4-apache-node10 8.2.x fat apache 10.x(2)
thecodingmachine/php:8.2-v4-apache-node12 8.2.x fat apache 12.x
thecodingmachine/php:8.2-v4-apache-node14 8.2.x fat apache 14.x
thecodingmachine/php:8.2-v4-apache-node16 8.2.x fat apache 16.x
thecodingmachine/php:8.2-v4-apache-node18 8.2.x fat apache 18.x
thecodingmachine/php:8.2-v4-apache-node20 8.2.x fat apache 20.x
thecodingmachine/php:8.2-v4-fpm 8.2.x fat fpm N/A
thecodingmachine/php:8.2-v4-fpm-node10 8.2.x fat fpm 10.x(2)
thecodingmachine/php:8.2-v4-fpm-node12 8.2.x fat fpm 12.x
thecodingmachine/php:8.2-v4-fpm-node14 8.2.x fat fpm 14.x
thecodingmachine/php:8.2-v4-fpm-node16 8.2.x fat fpm 16.x
thecodingmachine/php:8.2-v4-fpm-node18 8.2.x fat fpm 18.x
thecodingmachine/php:8.2-v4-fpm-node20 8.2.x fat fpm 20.x
thecodingmachine/php:8.2-v4-cli 8.2.x fat cli N/A
thecodingmachine/php:8.2-v4-cli-node10 8.2.x fat cli 10.x(2)
thecodingmachine/php:8.2-v4-cli-node12 8.2.x fat cli 12.x
thecodingmachine/php:8.2-v4-cli-node14 8.2.x fat cli 14.x
thecodingmachine/php:8.2-v4-cli-node16 8.2.x fat cli 16.x
thecodingmachine/php:8.2-v4-cli-node18 8.2.x fat cli 18.x
thecodingmachine/php:8.2-v4-cli-node20 8.2.x fat cli 20.x
thecodingmachine/php:8.2-v4-slim-apache 8.2.x slim apache N/A
thecodingmachine/php:8.2-v4-slim-fpm 8.2.x slim fpm N/A
thecodingmachine/php:8.2-v4-slim-cli 8.2.x slim cli N/A
thecodingmachine/php:8.1-v4-apache 8.1.x fat apache N/A
thecodingmachine/php:8.1-v4-apache-node10 8.1.x fat apache 10.x(2)
thecodingmachine/php:8.1-v4-apache-node12 8.1.x fat apache 12.x
thecodingmachine/php:8.1-v4-apache-node14 8.1.x fat apache 14.x
thecodingmachine/php:8.1-v4-apache-node16 8.1.x fat apache 16.x
thecodingmachine/php:8.1-v4-apache-node18 8.1.x fat apache 18.x
thecodingmachine/php:8.1-v4-apache-node20 8.1.x fat apache 20.x
thecodingmachine/php:8.1-v4-fpm 8.1.x fat fpm N/A
thecodingmachine/php:8.1-v4-fpm-node10 8.1.x fat fpm 10.x(2)
thecodingmachine/php:8.1-v4-fpm-node12 8.1.x fat fpm 12.x
thecodingmachine/php:8.1-v4-fpm-node14 8.1.x fat fpm 14.x
thecodingmachine/php:8.1-v4-fpm-node16 8.1.x fat fpm 16.x
thecodingmachine/php:8.1-v4-fpm-node18 8.1.x fat fpm 18.x
thecodingmachine/php:8.1-v4-fpm-node20 8.1.x fat fpm 20.x
thecodingmachine/php:8.1-v4-cli 8.1.x fat cli N/A
thecodingmachine/php:8.1-v4-cli-node10 8.1.x fat cli 10.x(2)
thecodingmachine/php:8.1-v4-cli-node12 8.1.x fat cli 12.x
thecodingmachine/php:8.1-v4-cli-node14 8.1.x fat cli 14.x
thecodingmachine/php:8.1-v4-cli-node16 8.1.x fat cli 16.x
thecodingmachine/php:8.1-v4-cli-node18 8.1.x fat cli 18.x
thecodingmachine/php:8.1-v4-cli-node20 8.1.x fat cli 20.x
thecodingmachine/php:8.1-v4-slim-apache 8.1.x slim apache N/A
thecodingmachine/php:8.1-v4-slim-fpm 8.1.x slim fpm N/A
thecodingmachine/php:8.1-v4-slim-cli 8.1.x slim cli N/A
thecodingmachine/php:8.0-v4-apache 8.0.x fat apache N/A
thecodingmachine/php:8.0-v4-apache-node10 8.0.x fat apache 10.x(2)
thecodingmachine/php:8.0-v4-apache-node12 8.0.x fat apache 12.x
thecodingmachine/php:8.0-v4-apache-node14 8.0.x fat apache 14.x
thecodingmachine/php:8.0-v4-apache-node16 8.0.x fat apache 16.x
thecodingmachine/php:8.0-v4-apache-node18 8.0.x fat apache 18.x
thecodingmachine/php:8.0-v4-apache-node20 8.0.x fat apache 20.x
thecodingmachine/php:8.0-v4-fpm 8.0.x fat fpm N/A
thecodingmachine/php:8.0-v4-fpm-node10 8.0.x fat fpm 10.x(2)
thecodingmachine/php:8.0-v4-fpm-node12 8.0.x fat fpm 12.x
thecodingmachine/php:8.0-v4-fpm-node14 8.0.x fat fpm 14.x
thecodingmachine/php:8.0-v4-fpm-node16 8.0.x fat fpm 16.x
thecodingmachine/php:8.0-v4-fpm-node18 8.0.x fat fpm 18.x
thecodingmachine/php:8.0-v4-fpm-node20 8.0.x fat fpm 20.x
thecodingmachine/php:8.0-v4-cli 8.0.x fat cli N/A
thecodingmachine/php:8.0-v4-cli-node10 8.0.x fat cli 10.x(2)
thecodingmachine/php:8.0-v4-cli-node12 8.0.x fat cli 12.x
thecodingmachine/php:8.0-v4-cli-node14 8.0.x fat cli 14.x
thecodingmachine/php:8.0-v4-cli-node16 8.0.x fat cli 16.x
thecodingmachine/php:8.0-v4-cli-node18 8.0.x fat cli 18.x
thecodingmachine/php:8.0-v4-cli-node20 8.0.x fat cli 20.x
thecodingmachine/php:8.0-v4-slim-apache 8.0.x slim apache N/A
thecodingmachine/php:8.0-v4-slim-fpm 8.0.x slim fpm N/A
thecodingmachine/php:8.0-v4-slim-cli 8.0.x slim cli N/A
thecodingmachine/php:7.4-v4-apache 7.4.x fat apache N/A
thecodingmachine/php:7.4-v4-apache-node10 7.4.x fat apache 10.x(2)
thecodingmachine/php:7.4-v4-apache-node12 7.4.x fat apache 12.x
thecodingmachine/php:7.4-v4-apache-node14 7.4.x fat apache 14.x
thecodingmachine/php:7.4-v4-apache-node16 7.4.x fat apache 16.x
thecodingmachine/php:7.4-v4-apache-node18 7.4.x fat apache 18.x
thecodingmachine/php:7.4-v4-apache-node20 7.4.x fat apache 20.x
thecodingmachine/php:7.4-v4-fpm 7.4.x fat fpm N/A
thecodingmachine/php:7.4-v4-fpm-node10 7.4.x fat fpm 10.x(2)
thecodingmachine/php:7.4-v4-fpm-node12 7.4.x fat fpm 12.x
thecodingmachine/php:7.4-v4-fpm-node14 7.4.x fat fpm 14.x
thecodingmachine/php:7.4-v4-fpm-node16 7.4.x fat fpm 16.x
thecodingmachine/php:7.4-v4-fpm-node18 7.4.x fat fpm 18.x
thecodingmachine/php:7.4-v4-fpm-node20 7.4.x fat fpm 20.x
thecodingmachine/php:7.4-v4-cli 7.4.x fat cli N/A
thecodingmachine/php:7.4-v4-cli-node10 7.4.x fat cli 10.x(2)
thecodingmachine/php:7.4-v4-cli-node12 7.4.x fat cli 12.x
thecodingmachine/php:7.4-v4-cli-node14 7.4.x fat cli 14.x
thecodingmachine/php:7.4-v4-cli-node16 7.4.x fat cli 16.x
thecodingmachine/php:7.4-v4-cli-node18 7.4.x fat cli 18.x
thecodingmachine/php:7.4-v4-cli-node20 7.4.x fat cli 20.x
thecodingmachine/php:7.4-v4-slim-apache 7.4.x slim apache N/A
thecodingmachine/php:7.4-v4-slim-fpm 7.4.x slim fpm N/A
thecodingmachine/php:7.4-v4-slim-cli 7.4.x slim cli N/A
thecodingmachine/php:7.3-v4-apache 7.3.x(1) fat apache N/A
thecodingmachine/php:7.3-v4-apache-node10 7.3.x(1) fat apache 10.x(2)
thecodingmachine/php:7.3-v4-apache-node12 7.3.x(1) fat apache 12.x
thecodingmachine/php:7.3-v4-apache-node14 7.3.x(1) fat apache 14.x
thecodingmachine/php:7.3-v4-apache-node16 7.3.x(1) fat apache 16.x
thecodingmachine/php:7.3-v4-apache-node18 7.3.x(1) fat apache 18.x
thecodingmachine/php:7.3-v4-apache-node20 7.3.x(1) fat apache 20.x
thecodingmachine/php:7.3-v4-fpm 7.3.x(1) fat fpm N/A
thecodingmachine/php:7.3-v4-fpm-node10 7.3.x(1) fat fpm 10.x(2)
thecodingmachine/php:7.3-v4-fpm-node12 7.3.x(1) fat fpm 12.x
thecodingmachine/php:7.3-v4-fpm-node14 7.3.x(1) fat fpm 14.x
thecodingmachine/php:7.3-v4-fpm-node16 7.3.x(1) fat fpm 16.x
thecodingmachine/php:7.3-v4-fpm-node18 7.3.x(1) fat fpm 18.x
thecodingmachine/php:7.3-v4-fpm-node20 7.3.x(1) fat fpm 20.x
thecodingmachine/php:7.3-v4-cli 7.3.x(1) fat cli N/A
thecodingmachine/php:7.3-v4-cli-node10 7.3.x(1) fat cli 10.x(2)
thecodingmachine/php:7.3-v4-cli-node12 7.3.x(1) fat cli 12.x
thecodingmachine/php:7.3-v4-cli-node14 7.3.x(1) fat cli 14.x
thecodingmachine/php:7.3-v4-cli-node16 7.3.x(1) fat cli 16.x
thecodingmachine/php:7.3-v4-cli-node18 7.3.x(1) fat cli 18.x
thecodingmachine/php:7.3-v4-cli-node20 7.3.x(1) fat cli 20.x
thecodingmachine/php:7.3-v4-slim-apache 7.3.x(1) slim apache N/A
thecodingmachine/php:7.3-v4-slim-fpm 7.3.x(1) slim fpm N/A
thecodingmachine/php:7.3-v4-slim-cli 7.3.x(1) slim cli N/A
thecodingmachine/php:7.2-v4-apache 7.2.x(1) fat apache N/A
thecodingmachine/php:7.2-v4-apache-node10 7.2.x(1) fat apache 10.x(2)
thecodingmachine/php:7.2-v4-apache-node12 7.2.x(1) fat apache 12.x
thecodingmachine/php:7.2-v4-apache-node14 7.2.x(1) fat apache 14.x
thecodingmachine/php:7.2-v4-apache-node16 7.2.x(1) fat apache 16.x
thecodingmachine/php:7.2-v4-apache-node18 7.2.x(1) fat apache 18.x
thecodingmachine/php:7.2-v4-apache-node20 7.2.x(1) fat apache 20.x
thecodingmachine/php:7.2-v4-fpm 7.2.x(1) fat fpm N/A
thecodingmachine/php:7.2-v4-fpm-node10 7.2.x(1) fat fpm 10.x(2)
thecodingmachine/php:7.2-v4-fpm-node12 7.2.x(1) fat fpm 12.x
thecodingmachine/php:7.2-v4-fpm-node14 7.2.x(1) fat fpm 14.x
thecodingmachine/php:7.2-v4-fpm-node16 7.2.x(1) fat fpm 16.x
thecodingmachine/php:7.2-v4-fpm-node18 7.2.x(1) fat fpm 18.x
thecodingmachine/php:7.2-v4-fpm-node20 7.2.x(1) fat fpm 20.x
thecodingmachine/php:7.2-v4-cli 7.2.x(1) fat cli N/A
thecodingmachine/php:7.2-v4-cli-node10 7.2.x(1) fat cli 10.x(2)
thecodingmachine/php:7.2-v4-cli-node12 7.2.x(1) fat cli 12.x
thecodingmachine/php:7.2-v4-cli-node14 7.2.x(1) fat cli 14.x
thecodingmachine/php:7.2-v4-cli-node16 7.2.x(1) fat cli 16.x
thecodingmachine/php:7.2-v4-cli-node18 7.2.x(1) fat cli 18.x
thecodingmachine/php:7.2-v4-cli-node20 7.2.x(1) fat cli 20.x
thecodingmachine/php:7.2-v4-slim-apache 7.2.x(1) slim apache N/A
thecodingmachine/php:7.2-v4-slim-fpm 7.2.x(1) slim fpm N/A
thecodingmachine/php:7.2-v4-slim-cli 7.2.x(1) slim cli N/A

Note: we also tag patch releases of PHP versions. So you can specify a specific patch release using thecodingmachine/php:8.0.2-v4-cli for instance. However, unless you have a very specific need (for instance if the latest patch release of PHP introduced regressions), believe you have no valid reason to ask explicitly for 8.0.2 for instance. When 8.0.3 is out, you certainly want to upgrade automatically to this patch release since patch releases contain only bugfixes. Also, we automatically rebuild X.Y images every week, but only the latest X.Y.Z patch release gets a rebuild. The other patch releases are frozen in time and will contain bugs and security issues. So use those with great care.

[Major].[minor] images are automatically updated when a new patch version of PHP is released, so the PHP 7.4 image will always contain the most up-to-date version of the PHP 7.4.x branch.

Usage

These images are based on the official PHP image.

Example with CLI:

$ docker run -it --rm --name my-running-script -v "$PWD":/usr/src/app thecodingmachine/php:8.3-v4-cli php your-script.php

Example with Apache:

$ docker run -p 80:80 --rm --name my-apache-php-app -v "$PWD":/var/www/html thecodingmachine/php:8.3-v4-apache

Example with PHP-FPM:

$ docker run -p 9000:9000 --rm --name my-php-fpm -v "$PWD":/var/www/html thecodingmachine/php:8.3-v4-fpm

Example with Apache + Node 14.x in a Dockerfile:

Dockerfile

FROM thecodingmachine/php:8.3-v4-apache-node14

COPY src/ /var/www/html/
RUN composer install
RUN npm install
RUN npm run build

Extensions available

This image comes with 2 "types": the slim and the fat image.

These extensions are enabled by default in slim image: calendar ctype curl date dom exif fileinfo filter ftp gettext iconv json mbstring opcache openssl pcntl pcre PDO Phar posix readline shmop Reflection session shmop SimpleXML sockets sodium SPL sysvmsg sysvsem sysvshm tokenizer xml xmlreader xmlwriter xsl zip

This list can be outdated, you can verify by executing : docker run --rm -it thecodingmachine/php:8.3-v4-slim-cli php -m

The slim image provides a simple way to install the other extensions. You would typically use the "slim" image in a Dockerfile when building your own custom image.

The fat image contains the most commonly used extensions. You would typically use it in a local or CI environment.

Fat image

Below is a list of extensions available in this image:

Enabled by default (in addition to extensions enabled in Slim image): apcu, hash, iconv, igbinary, mysqli, mysqlnd, redis, soap, xsl, zlib and all enabled in slim.

Available (can be enabled using environment variables): amqp ast bcmath blackfire bz2 dba ds enchant ev event exif ffi mailparse msgpack gd gettext gmp gnupg grpc igbinary imagick imap intl ldap mcrypt memcached mongodb pcov pdo_dblib pdo_pgsql pdo_sqlite pgsql pspell shmop snmp sockets sqlite3 swoole tidy uploadprogress uuid weakref(-beta) xdebug xmlrpc xsl yaml

This list can be outdated, you can verify by executing : docker run --rm -it thecodingmachine/php:8.3-v4-cli php -m

Note:

  • mcrypt is not available anymore in PHP 7.3+
  • weakref is not compatible with PHP 7.3+ (but weak references were added to the PHP core in PHP 7.4)
  • event, gnupg are not available in PHP 8.0+
  • gettext, ev, swoole are not available in PHP 8.1+
  • ev, rdkafka, snmp, swoole are not available in all ARM64 images (build time is too long : it's possible to install manually as required)
  • ffi is only available in PHP 7.4+

Enabling/disabling extensions in the fat image

You can enable/disable extensions using the PHP_EXTENSION_[extension_name] environment variable.

For instance:

version: '3'
services:
  my_app:
    image: thecodingmachine/php:8.3-v4-apache-node16
    environment:
      # Enable the PostgreSQL extension
      PHP_EXTENSION_PGSQL: 1
      # Disable the Mysqli extension (otherwise it is enabled by default)
      PHP_EXTENSION_MYSQLI: 0

As an alternative, you can use the PHP_EXTENSIONS global variable:

PHP_EXTENSIONS=pgsql gettext imap

Compiling extensions in the slim image

If you are using the slim image, you can automatically compile the extensions using the PHP_EXTENSIONS ARG in your Dockerfile.

ARG PHP_EXTENSIONS="apcu mysqli pdo_mysql redis soap"
FROM thecodingmachine/php:8.3-v4-slim-apache
# The build will automatically trigger the download and compilation
# of the extensions (thanks to a ONBUILD hook in the slim image)

Beware :

  • The ARG PHP_EXTENSIONS command must be written before the FROM. This is not a typo.
  • ARG PHP_EXTENSIONS="" it's not the same as ENV PHP_EXTENSIONS=""
  • You can't use ARG PHP_EXTENSION_MYEXT="" like the fat image.
  • Heads up: if you are using multistage builds, the "ARG" variable must be put at the very top of the file (before the first FROM):
# The PHP_EXTENSIONS ARG will apply to the "slim" image
ARG PHP_EXTENSIONS="apcu mysqli pdo_mysql soap"

FROM thecodingmachine/php:8.3-v4-apache-node16 AS builder

COPY --chown=docker:docker sources/web .
RUN composer install &&\
    yarn install &&\
    yarn build

# The slim image will automatically build the extensions from the list provided at the very top of the file.
FROM thecodingmachine/php:7.2-v4-slim-apache

ENV APP_ENV=prod \
    APACHE_DOCUMENT_ROOT=public/

COPY --from=builder /var/www/html .

In the sample above, we use the fat image to perform a "yarn build", but copy the result in a slim image that does not contain Node, and contains only required extensions.

Setting parameters in php.ini

By default, the base php.ini file used is the development php.ini file that comes with PHP.

You can use the production php.ini file using the TEMPLATE_PHP_INI environment variable:

# Use the production php.ini file as a base
TEMPLATE_PHP_INI=production

You can override parameters in php.ini using the PHP_INI_XXX environment variables:

version: '3'
services:
  my_app:
    image: thecodingmachine/php:8.3-v4-apache-node16
    environment:
      # set the parameter memory_limit=1g
      PHP_INI_MEMORY_LIMIT: 1g
      # set the parameter error_reporting=EALL
      PHP_INI_ERROR_REPORTING: E_ALL

Absolutely all php.ini parameters can be set.

Internally, the image will map all environment variables starting with PHP_INI_.

If your php.ini parameter contains a dot ("."), you can replace it with a double underscore ("__").

For instance:

# Will set the parameter xdebug.remote_autostart=1
PHP_INI_XDEBUG__REMOTE_AUTOSTART=1

Default working directory

The working directory (the directory in which you should mount/copy your application) depends on the image variant you are using:

Variant Working directory
cli /usr/src/app
apache /var/www/html
fpm /var/www/html

Changing Apache document root

For the apache variant, you can change the document root of Apache (i.e. your "public" directory) by using the APACHE_DOCUMENT_ROOT variable:

# The root of your website is in the "public" directory:
APACHE_DOCUMENT_ROOT=public/

If the APACHE_DOCUMENT_ROOT starts with a "/", it will be considered an absolute path. If the APACHE_DOCUMENT_ROOT does not starts with a "/", it will be a path relative to "/var/www/html".

# These 2 variables are identical
APACHE_DOCUMENT_ROOT=public/
APACHE_DOCUMENT_ROOT=/var/www/html/public

Enabling/disabling Apache extensions

You can enable/disable Apache extensions using the APACHE_EXTENSION_[extension_name] environment variable.

For instance:

version: '3'
services:
  my_app:
    image: thecodingmachine/php:8.3-v4-apache-node16
    environment:
      # Enable the DAV extension for Apache
      APACHE_EXTENSION_DAV: 1
      # Enable the SSL extension for Apache
      APACHE_EXTENSION_SSL: 1

As an alternative, you can use the APACHE_EXTENSIONS global variable:

APACHE_EXTENSIONS="dav ssl"

Apache modules enabled by default: access_compat alias auth_basic authn_core authn_file authz_core authz_host authz_user autoindex deflate dir env expires filter mime mpm_prefork negotiation php8.0 (depend of your active version) reqtimeout rewrite setenvif status

Apache modules available: access_compat actions alias allowmethods asis auth_basic auth_digest auth_form authn_anon authn_core authn_dbd authn_dbm authn_file authn_socache authnz_fcgi authnz_ldap authz_core authz_dbd authz_dbm authz_groupfile authz_host authz_owner authz_user autoindex brotli buffer cache cache_disk cache_socache cern_meta cgi cgid charset_lite data dav dav_fs dav_lock dbd deflate dialup dir dump_io echo env ext_filter expires file_cache filter headers heartbeat heartmonitor http2 ident imagemap include info lbmethod_bybusyness lbmethod_byrequests lbmethod_bytraffic lbmethod_heartbeat ldap log_debug log_forensic lua macro md mime mime_magic mpm_event mpm_prefork mpm_worker negotiation php8.0 (depend of your active version) proxy proxy_ajp proxy_balancer proxy_connect proxy_express proxy_fcgi proxy_fdpass proxy_ftp proxy_hcheck proxy_html proxy_http proxy_http2 proxy_scgi proxy_wstunnel ratelimit reflector remoteip reqtimeout request rewrite sed session session_cookie session_crypto session_dbd setenvif slotmem_plain slotmem_shm socache_dbm socache_memcache socache_redis socache_shmcb speling ssl status substitute suexec unique_id userdir usertrack vhost_alias xml2enc

This list can be outdated, you can verify by executing : docker run --rm -it thecodingmachine/php:8.3-v4-slim-apache a2enmod

Debugging

To enable XDebug you simply have to set the environment variable:

PHP_EXTENSION_XDEBUG=1

If you enable XDebug, the image will do its best to configure the xdebug.client_host to point back to your Docker host.

Behind the scenes, the image will:

  • set the parameter xdebug.mode=debug
  • if you are using a Linux machine, the xdebug.client_host IP will point to your Docker gateway
  • if you are using a Windows or MaxOS machine, the xdebug.client_host IP will point to host.docker.internal or docker.for.mac.localhost

If you want to debug directly inside your container (for example if you're using VSCode devcontainers) you can overwrite the xdebug.client_host value by setting the following environment variable:

XDEBUG_CLIENT_HOST=127.0.0.1

In that case the manually set value takes precedence over the mentioned ones above.

NodeJS

The fat images come with a Node variant. You can use Node 10, 12, 14 or 16. If you need a Node 8 variant, use thecodingmachine/php v3 images. If you need a Node 6 variant, use thecodingmachine/php v1 images.

If you use the slim images, you can install a NodeJS version with a simple ARG during the build:

ARG NODE_VERSION=14
FROM thecodingmachine/php:8.3-v4-slim-apache
# The build will automatically trigger the download of Node 14
# (thanks to a ONBUILD hook in the slim image)

Beware! The ARG NODE_VERSION command must be written before the FROM. This is not a typo.

NODE_VERSION can take any valid node versions (from 6 to 11 at the time of writing this README)

Permissions

Ever faced file permission issues with Docker? Good news, this is a thing of the past!

If you are used to running Docker containers with the base PHP image, you probably noticed that when running commands (like composer install) within the container, files are associated to the root user. This is because the base user of the image is "root".

When you mount your project directory into /var/www/html, it would be great if the default user used by Docker could be your current host user.

The problem with Docker is that the container and the host do not share the same list of users. For instance, you might be logged in on your host computer as superdev (ID: 1000), and the container has no user whose ID is 1000.

The thecodingmachine/php images solve this issue with a bit of black magic:

The image contains a user named docker. On container startup, the startup script will look at the owner of the working directory (/var/www/html for Apache/PHP-FPM, or /usr/src/app for CLI). The script will then assume that you want to run commands as this user. So it will dynamically change the ID of the docker user to match the ID of the current working directory user.

Furthermore, the image is changing the Apache default user/group to be docker/docker (instead if www-data/www-data). So Apache will run with the same rights as the user on your host.

The direct result is that, in development:

  • Your PHP application can edit any file
  • Your container can edit any file
  • You can still edit any file created by Apache or by the container in CLI

Using this image in production

By changing the Apache user to be docker:docker, we are lowering the security. This is OK for a development environment, but this should be avoided in production. Indeed, in production, Apache should not be allowed to edit PHP files of your application. If for some reason, an attacker manages to change PHP files using a security hole, he could then run any PHP script by editing the PHP files of your application.

In production, you want to change back the Apache user to www-data.

This can be done easily:

Dockerfile

FROM thecodingmachine/php:8.3-v4-apache

# ...

# Change back Apache user and group to www-data
ENV APACHE_RUN_USER=www-data \
    APACHE_RUN_GROUP=www-data

Setting up CRON jobs

You can set up CRON jobs using environment variables too.

To do this, you need to configure 3 variables:

# configure the user that will run cron (defaults to root)
CRON_USER=root
# configure the schedule for the cron job (here: run every minute)
CRON_SCHEDULE=* * * * *
# last but not least, configure the command
CRON_COMMAND=vendor/bin/console do:stuff

By default, CRON output will be redirected to Docker output.

If you have more than one job to run, you can suffix your environment variable with the same string. For instance:

CRON_USER_1=root
CRON_SCHEDULE_1=* * * * *
CRON_COMMAND_1=vendor/bin/console do:stuff

CRON_USER_2=www-data
CRON_SCHEDULE_2=0 3 * * *
CRON_COMMAND_2=vendor/bin/console other:stuff

Cron is installed by default in the fat images. If you are using the "slim" images, you need to install it by passing a single argument before the "FROM" clause in your Dockerfile:

ARG INSTALL_CRON=1
FROM thecodingmachine/php:8.3-v4-slim-apache
# The build triggers automatically the installation of Cron

Important: The cron runner we use is "Supercronic" and not the orginial "cron" that has a number of issues with containers. Even with Supercronic, the architecture of cron was never designed with Docker in mind (Cron is way older than Docker). It will run correctly on your container. If at some point you want to scale and add more containers, it will run on all your containers. At that point, if you only want to run a Cron task once for your application (and not once per container), you might want to have a look at alternative solutions like Tasker or use the native features of your orchestrator (if you use Kubernetes, you have a native task runner available), or one of the many other alternatives.

Please notice that by default, containers are running in the UTC timezone. So your CRONs will run at UTC time. If you want to change a timezone in a container, you can use the TZ environment variable.

# Run this cron at 1 am, Paris time
TZ=Europe/Paris
CRON_SCHEDULE_1=0 1 * * *
CRON_COMMAND_1=vendor/bin/console do:stuff

Supercronic options

To specify Supercronic options you can set the SUPERCRONIC_OPTIONS environment variable.

This can be used to enable duplicate jobs. Per default, Supercronic will wait for a given job to finish before that job is scheduled again.
With the option -overlapping Supercronic will run duplicate instances of the jobs instead of waiting for them.

SUPERCRONIC_OPTIONS=-overlapping

# Or multiple options
SUPERCRONIC_OPTIONS=-overlapping -debug

For more options see see the Supercronic Documentation.

Launching commands on container startup

You can launch commands on container startup using the STARTUP_COMMAND_XXX environment variables. This can be very helpful to install dependencies or apply database patches for instance:

STARTUP_COMMAND_1=composer install
STARTUP_COMMAND_2=vendor/bin/doctrine orm:schema-tool:update 

As an alternative, the images will look into the container for an executable file named /etc/container/startup.sh.

If such a file is mounted in the image, it will be executed on container startup.

docker run -it --rm --name my-running-script -v "$PWD":/usr/src/myapp -w /usr/src/myapp \ 
       -v $PWD/my-startup-script.sh:/etc/container/startup.sh thecodingmachine/php:8.3-v4-cli php your-script.php 

Using the CLI variant

The CLI images (thecodingmachine/php:8.3-v4-cli) expect a command to be passed in parameter. You should override the Docker "command".

Important! You should not override the Docker "entrypoint".

Usage in a Dockerfile:

FROM thecodingmachine/php:8.3-v4-cli

CMD ["php", "myprogram.php", "some_param"]

Usage with Docker compose:

docker-compose.yml

version: '3'
services:
  my_app:
    image: thecodingmachine/php:8.3-v4-cli
    command: php myprogram.php some_param

Registering SSH private keys

If your PHP project as a dependency on a package stored in a private GIT repository, your composer install commands will not work unless you register your private key in the container.

You have several options to do this.

Option 1: mount your keys in the container directly

This option is the easiest way to go if you are using the image on a development environment.

docker-compose.yml

version: '3'
services:
  my_app:
    image: thecodingmachine/php:8.3-v4-apache-node16
    volumes:
      - ~/.ssh:/home/docker/.ssh

Option 2: store the keys from environment variables or build arguments

Look at this option if you are building a Dockerfile from this image.

The first thing to do is to get the signature of the server you want to connect to.

$ ssh-keyscan myserver.com

Copy the output and put it in an environment variable. We assume the content is stored in $SSH_KNOWN_HOSTS.

Now, let's write a Dockerfile.

Dockerfile

FROM thecodingmachine/php:8.3-v4-apache

ARG SSH_PRIVATE_KEY
ARG SSH_KNOWN_HOSTS

# Let's register the private key
RUN ssh-add <(echo "$SSH_PRIVATE_KEY")
# Let's add the server to the list of known hosts.
RUN echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts

Finally, when triggering the build, you must pass the 2 variables as build arguments:

$ docker build -t my_image --build-arg SSH_PRIVATE_KEY="$SSH_PRIVATE_KEY" --build-arg SSH_KNOWN_HOSTS="$SSH_KNOWN_HOSTS" .

Usage in Kubernetes

If you plan to use this image in Kubernetes, please be aware that the image internally uses sudo. This is because the default user (docker) needs to be able to edit php config files as root.

Kubernetes has a security setting (allowPrivilegeEscalation) that can disallow the use of sudo. The use of this flag breaks the image and in the logs, you will find the message:

sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?

Please be sure that this option is never set to false:

apiVersion: v1
kind: Pod
# ...
spec:
  containers:
  - name: foobar
    image: thecodingmachine/php:8.3-v4-apache
    securityContext:
      allowPrivilegeEscalation: true # never use "false" here.

Profiling with Blackfire

This image comes with the Blackfire PHP probe. You can install it using:

PHP_EXTENSION_BLACKFIRE=1

By default, the image expects that the blackfire agent is started in another container.

Your docker-compose.yml file will typically look like this:

docker-compose.yml

version: '3.3'
services:
  php:
    image: thecodingmachine/php:8.3-v4-apache
    ports:
      - "80:80"
    environment:
      PHP_EXTENSION_BLACKFIRE: 1
  blackfire:
    image: blackfire/blackfire
    environment:
        # Exposes the host BLACKFIRE_SERVER_ID and TOKEN environment variables.
        - BLACKFIRE_SERVER_ID
        - BLACKFIRE_SERVER_TOKEN
        # You can also use global environment credentials :
        # BLACKFIRE_SERVER_ID: SERVER-ID
        # BLACKFIRE_SERVER_TOKEN: SERVER-TOKEN

See Blackfire Docker documentation for more information.

The image assumes that the Blackfire agent is accessible via the blackfire URL (like in the exemple above). If for some reason, the container name is not "blackfire", you can customize the agent URL with the BLACKFIRE_AGENT environment variable:

docker-compose.yml

version: '3.3'
services:
  php:
    image: thecodingmachine/php:8.3-v4-apache
    environment:
      PHP_EXTENSION_BLACKFIRE: 1
      BLACKFIRE_AGENT: myblackfire
    # ...
  myblackfire:
    image: blackfire/blackfire
    environment:
        # ...

Migrating from older image versions

Check the migration notes.

Contributing

There is one branch per minor PHP version and version of the image.

Please submit your pull requests to the lowest branch where is applies.

The Dockerfiles and the README are generated from a template using Orbit.

If you want to modify a Dockerfile or the README, you should instead edit the utils/Dockerfile.blueprint or utils/README.blueprint.md and then run the command:

$ orbit run generate

This command will generate all the files from the "blueprint" templates.

You can then test your changes using the build-and-test.sh command:

PHP_VERSION=8.3 BRANCH=v4 VARIANT=apache ./build-and-test.sh

Additional environment in build-and-test.sh

  • BUILDER: either build or buildx depending on your configuration. Defaults to build
  • BLACKFIRE_VERSION: defaults to 1. You can install v2 if you're feeling adventurous by specifying 2 as a value.
  • PLATFORM: Docker will default to your architecture for building images. However, if you have QEMU set up in your machine, you can try building for another architecture like linux/arm64

Only one platform at a time is supported during the build and test script execution.

APPLE SILICON CONSIDERATIONS

Filesystem management works differently in Apple's macOS, so, if you're trying to build a linux/arm64 image (that is best suited for using in a M1/M2 Mac than a linux/amd64 one), there's a high likelihood that the filesystem user and permissions with busybox are going to fail.

Although the test fails, when using the built image, everything works as expected.

Run a virtual machine with linux/arm64 with Docker installed in it and, then, build and test the image. You'll take advantage of the ARM speed and will also be able to run the unit tests properly.

Adding additional images

To add a new version (php, node, apache, ...), please edit the following files :

  • utils/README.blueprint.md
    • Add your image in this section: Images
  • orbit.yml: Your image in generation task
  • .travis.yml: To check the new image
  • build-and-test.sh: Add your image in test

Special thanks

These images have been strongly inspired by tetraweb/php.

docker-images-php's People

Contributors

andersonpem avatar astridx avatar bastnic avatar dsavina avatar dylanbr avatar erichao22 avatar gulien avatar guoard avatar hw-rjuzak avatar iquito avatar jeremygreaux avatar kermorgant avatar mbrodala avatar mhemrg avatar mistraloz avatar moufmouf avatar mrmage avatar nguyenk avatar ollyollyollyltd avatar pdelre avatar qkdreyer avatar r0wi avatar todeveni avatar vaidiep avatar vuongxuongminh avatar windaishi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

docker-images-php's Issues

CRON STDOUT

STDOUT not working for the cron. > /proc/1/fd/1 2>/proc/1/fd/2 in file generate_cron.php

Can't use volume to map /var/www/html

Hi

I am using

version: '3'
services:
  my_app:
    image: thecodingmachine/php:7.3-v2-apache-node10
    environment:
      # Enable the PostgreSQL extension
      PHP_EXTENSION_PGSQL: 1
      # Disable the Mysqli extension (otherwise it is enabled by default)
      PHP_EXTENSION_MYSQLI: 0
      #APACHE_DOCUMENT_ROOT: /var/www/html
    ports:
      - "2080:80"  

    volumes:
      - /media/var/www/html:/var/www/html

However I cant seem to be able to acces any of the webapps under /media/var/www/html I am not sure what I am missing here.

"GET /webapp/ HTTP/1.1" 404 506 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0

I am using Docker on Debian Buster x64
thanks

Cron job not running

Thanks for sharing this. I wanted to try this out for a project but I am having problems getting cron jobs working.

Expected Behavior

When I set CRON_COMMAND and CRON_SCHEDULE I expect the command to be executed as define by the schedule.

Current Behavior

When these commands are set the /etc/cron.d/generated_crontab file seems to be generated as expected but as far as I can tell the command is not executed.

I cannot tell why. Some form of logging might be helpful if possible.

Steps to Reproduce (for bugs)

  1. Create a docker-compose.yml file:
version: '3'
services:
  my_app:
    image: thecodingmachine/php:7.2-v1-apache
    environment:
      CRON_SCHEDULE: '* * * * *'
      CRON_COMMAND: 'php -r "echo time();"'
  1. Start the service docker-compose up
  2. Notice the output from Apache startup sequence in the output as expected
22:42 $ docker-compose up
Creating network "tmp_default" with the default driver
Creating tmp_my_app_1 ... done
Attaching to tmp_my_app_1
my_app_1  | [Fri Apr 27 20:42:16.690672 2018] [mpm_prefork:notice] [pid 8] AH00163: Apache/2.4.25 (Debian) PHP/7.2.4 configured -- resuming normal operations
my_app_1  | [Fri Apr 27 20:42:16.690749 2018] [core:notice] [pid 8] AH00094: Command line: 'apache2 -D FOREGROUND'
  1. I had expected there to be timestamps from the cron job in the output
  2. In another terminal run docker-compose exec my_app cat /etc/cron.d/generated_crontab. Output seems sensible enough

* * * * * root (php -r "echo time();") | sed -e 's/^/[Cron] /' > /proc/7/fd/1 2>/proc/7/fd/2

Your Environment

  • Version used: php:7.2-v1-apache and php:7.2-v1-cli
  • Operating System and version: OSX 10.13.4 + Docker for Mac 18.03.0-ce-mac60 (23751)

Xdebug remote host

Expected Behavior

When enabling the Xdebug extension with PHP_EXTENSION_XDEBUG=1, the Xdebug remote host should be set automatically.

Current Behavior

The variable xdebug.remote_host is empty

Possible Solution

More a workaround, but we are able to temporary fix this by using PHP_INI_XDEBUG__REMOTE_HOST=ip/docker.for.mac.localhost

Steps to Reproduce (for bugs)

  • Enable Xdebug with PHP_EXTENSION_XDEBUG=1
  • Restart the container
  • Run php -i in the container

Your Environment

  • Version used: PHP-Apache 7.1
  • Operating System and version: Linux / MacOS

Curl SSL certificate missing?

Expected Behavior

PHP Curl requests to HTTPS URLs should succeed

Current Behavior

Requests are failing

Possible Solution

Looks like it's something to do with cacert.pem not being found
https://docs.bolt.cm/3.6/howto/curl-ca-certificates

Steps to Reproduce (for bugs)

  • Using image thecodingmachine/php:7.2-v2-fpm
  • In a PHP script, use Curl to request an HTTPS url
  • See error SSL certificate problem: unable to get local issuer certificate when the curl request fails.

Docker 18.09.5 is on Linux Mint 19

Memcached issue

Hello,

When enabling the memcached PHP extension, I get the following error:

PHP Warning:  PHP Startup: Unable to load dynamic library 'memcached.so' (tried: /usr/local/lib/php/extensions/no-debug-non-zts-20170718/memcached.so (libmemcached.so.11: cannot open shared object file: No such file or directory), /usr/local/lib/php/extensions/no-debug-non-zts-20170718/memcached.so.so (/usr/local/lib/php/extensions/no-debug-non-zts-20170718/memcached.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0

My service:

front:
    image: thecodingmachine/php:7.2-v1-apache-node8
    working_dir: /var/www/html/front
    labels:
      - traefik.enable=true
      - traefik.backend=front
      - traefik.frontend.rule=Host:foo.localhost
    environment:
      APACHE_DOCUMENT_ROOT: front/
      PHP_INI_MEMORY_LIMIT: 1g
      PHP_EXTENSION_XDEBUG: 1
      PHP_EXTENSION_BCMATH: 1
      PHP_EXTENSION_INTL: 1
      PHP_EXTENSION_GD: 1
      PHP_EXTENSION_MEMCACHED: 1
      STARTUP_COMMAND_1: composer install
      STARTUP_COMMAND_2: yarn install
      STARTUP_COMMAND_3: gulp js less css
    env_file:
      - .env
    volumes:
      - .:/var/www/html:rw

Extensions not installed when running Composer in Dockerfile

FROM thecodingmachine/php:7.1-v1-cli
ENV PHP_EXTENSION_GD=1
RUN composer install

If the composer.lock contains a package that requires "gd" to be enabled, "gd" will not be yet available (because it is enabled at container startup time only).

We should overwrite "composer" executable to make sure we enable the extensions before composer startup.

PHP-FPM versions is not works

Hi there!

When I use the fpm version, the php-fpm process does not start and the container shutdown without any errors but with the output of sudo usages. In scripts that run automatically when the container starts, there are no commands to run the php-fpm process. Also, there is no launch of the php-fpm process in the Dockerfile.fpm file. I fixed it but your Dockerfile.fpm is not correct.

user@host:~ $ docker run -p 9000:9000 -v /home/user/code:/var/www/html thecodingmachine/php:7.2-v1-fpm

usage: sudo -h | -K | -k | -V
usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]
usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user]
            [command]
usage: sudo [-AbEHknPS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p
            prompt] [-u user] [VAR=value] [-i|-s] [<command>]
usage: sudo -e [-AknS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p
            prompt] [-u user] file ...

user@host:~ $

/var/www/html directory is owned by root on Php:7.2-v2-fpm image (Windows)

Expected Behavior

When I get inside the php-fpm container, my volume mounted in /var/www/html should be owned by "docker" user.

Current Behavior

It's owned by "root" user instead.
Executing a chown docker:docker /var/www/html doesn't work, neither from the Dockerfile, nor from inside the container itself.

Steps to Reproduce (for bugs)

Here is my Dockerfile :

FROM thecodingmachine/php:7.2-v2-fpm

COPY ["./conf/log.conf", "/usr/local/etc/php-fpm.d/zz-log.conf"]

USER root

# pre-req
RUN apt-get update
RUN apt-get install --no-install-recommends -y \
    zip \
    locales \
    libicu-dev \
    apt-transport-https \
    libpng-dev \
    libzip-dev \
    libxml2-dev \
    libpng-dev
RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
RUN locale-gen

# ssl 1.0.0
RUN echo 'deb http://httpredir.debian.org/debian jessie main contrib non-free' >> /etc/apt/sources.list.d/jessie.list \
    && echo 'deb-src http://httpredir.debian.org/debian jessie main contrib non-free' >> /etc/apt/sources.list.d/jessie.list \
    && echo 'deb http://security.debian.org/ jessie/updates main contrib non-free' >> /etc/apt/sources.list.d/jessie.list \
    && echo 'deb-src http://security.debian.org/ jessie/updates main contrib non-free' >> /etc/apt/sources.list.d/jessie.list \
    && apt-get update
RUN apt-get install libssl1.0.0

# sqlsrv pre-req
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - \
    && curl https://packages.microsoft.com/config/debian/8/prod.list > /etc/apt/sources.list.d/mssql-release.list \
    && apt-get update
RUN ACCEPT_EULA=Y apt-get install -y \
    unixodbc \
    unixodbc-dev \
    libgss3 \
    odbcinst \
    msodbcsql \
    msodbcsql17 \
    mssql-tools
RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc

# install php ext
RUN pecl install sqlsrv pdo_sqlsrv
RUN docker-php-ext-enable sqlsrv pdo_sqlsrv

# spring cleaning
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*

USER docker

WORKDIR /var/www/html

And the "php" service in my docker-compose.yml :

php:
    build:
      context: .
      dockerfile: dockerfile-php
    container_name: php
    env_file:
      - .env
    environment:
      PHP_EXTENSION_INTL: 1
      PHP_EXTENSION_GD: 1
      PHP_EXTENSION_XDEBUG: $DEBUG
      STARTUP_COMMAND_1: composer install
    volumes:
      - ./code/backend:/var/www/html
    networks:
      - net

Also, I'm working on Windows 10 (Professionnal), with Docker for Windows (Linux containers).

XDEBUG remote host detection fails in V2

The 'host' command use to define xdebug configuration doesn't exists in the image.
So, ```DOCKER_HOST_INTERNAL=`host -t A host.docker.internal | awk '/has address/ { print $4 }'```` can't be proceed.

Cron php not found

In cron configuration, I try to apply php -v but php is not found by default.

Install Blackfire

That would be awesome if Blackfire was preinstalled in the Docker images. That would allow to profile PHP scripts very easily.

To make that happen the following needs to be done in the Docker images:

Users not using Blackfire should not be impacted because the extension will not do anything. (it could also be possible to make the extension opt-in through an environment variable, that would be even cleaner)

Users using Blackfire will need to:

Dynamic PHP_EXTENSIONS

Hi, great job ๐Ÿ‘
I want to set PHP_EXTENSIONS variable dynamically in my Dockerfile.

ONBUILD ENV PHP_EXTENSIONS=$(cat /var/www/html/exts.txt)

But Docker doesn't allow it. Can you please help me to do it?

Slim Image, ARG not working in multistage build

Using this Dockerfile:

FROM thecodingmachine/php:7.2-v2-apache-node10 AS builder

COPY --chown=docker:docker sources/web .

ENV APP_ENV=prod \
    APACHE_DOCUMENT_ROOT=/public

RUN composer install &&\
    yarn install &&\
    yarn build

ARG PHP_EXTENSIONS="apcu mysqli opcache pdo pdo_mysql zip soap"
FROM thecodingmachine/php:7.2-v2-slim-apache

ENV APP_ENV=prod \
    APACHE_DOCUMENT_ROOT=/public

COPY --from=builder /var/www/html .

No errors, but the process says:

*** Installing extensions ***
array(0) {
}
No extensions installed in ONBUILD hook.
`
``

XDebug Extension Not Loading

Expected Behavior

XDebug extension is enabled

Current Behavior

XDebug extension is not enabled

Steps to Reproduce (for bugs)

Use this docker-compose.yml:

version: '3.3'

services:
     php:
          image: thecodingmachine/php:7.2-v2-apache
          ports:
               - "8080:80"
          volumes:
               - ./:/var/www/html
          environment:
               PHP_EXTENSION_XDEBUG: 1
               PHP_INI_XDEBUG__REMOTE_ENABLE: 1
               PHP_INI_XDEBUG__REMOTE_AUTOSTART: 1

image

Crons are not executed as correct user if there is a ";" in the command

Expected Behavior

CRON_COMMAND_1: id; id
CRON_USER_1: docker

There are 2 "id" commands run. They should both execute as the "docker" user.

Current Behavior

First id is executed by "docker", second by "root".

This is because the command executed is:

/bin/sh -c sudo -E -u docker id; id

Extensions isnt compiled and added when using Dockerfile.7.3.slim.fpm

Hi,

Ive been struggling with this for a while now, I cant understand what Iam doing wrong.

Im using Dockerfile.7.3.slim.fpm with this structure:
/php-slim/Dockerfile
/php-slim/extensions
/php-slim/utils

And ive added ARG PHP_EXTENSION at the top of the Dockerfile:
ARG PHP_EXTENSIONS="gettext apcu opcache pdo pdo_mysql zip soap intl"
ARG INSTALL_CRON=1
FROM php:7.3-fpm-stretch

None of the extensions gets compiled/installed when i build. If I add this manually below line 16:
RUN cd /usr/local/lib/thecodingmachine-php/extensions/current/gettext && ./install.sh
RUN cd /usr/local/lib/thecodingmachine-php/extensions/current/intl && ./install.sh

Those (two) extensions gets installed & compiled as intended. What am I doing wrong? Ive cleaned my cache, downloaded the image from scratch and gets same result each time. Using Dockerfile.7.3.fpm (fat) as Dockerfile works with the extensions.

Redis module does not seem to load with default values

Your issue may already be reported!
Please search on the issue tracker before creating one.

Expected Behavior

Redis module should be loading by default

Current Behavior

Redis module does not load

Possible Solution

Steps to Reproduce (for bugs)

  1. Run docker image with echo php modules php -m
    Returns: php modules [PHP Modules] bcmath bz2 calendar Core ctype curl date dba dom exif fileinfo filter ftp gd gettext gmp gnupg hash iconv imagick imap intl json ldap libxml mbstring mcrypt mongodb mysqli mysqlnd odbc openssl pcntl pcre PDO pdo_mysql PDO_ODBC pdo_pgsql pdo_sqlite pgsql Phar posix readline recode Reflection session shmop SimpleXML snmp soap sockets SPL sqlite3 standard sysvmsg sysvsem sysvshm tidy tokenizer wddx xml xmlreader xmlrpc xmlwriter xsl Zend OPcache zip zlib [Zend Modules] Zend OPcache

Context

Your Environment

  • Version used: 7.2-v1
  • Operating System and version:
  • Link to your project:

Feature Request: Cloud9 IDE

First off, I want to say this is by far the best docker environment I've ever seen around. Super dynamic, easy to use and very extensive. I was just wondering if you would consider adding a dev image that includes the Cloud9 IDE. If this was a possibility then I could trow out my PC forever:

2019-01-07-06-38-05-html-Cloud9

I can understand you might not want to add C9 to your dev images. But if anyone of the team is interested in it, I'd love to work together to create a sub-image with them.

Let me know if there's any team members that are into exploring the idea. If there's absolutely no interest you can close this issue and I'll explore it myself.

Here's an installation example of C9 (it does add +/- 400 MB to the image):

Dockerfile
FROM thecodingmachine/php:7.2-v2-cli-node10

USER root

RUN buildDeps='make build-essential g++ gcc python2.7' && softDeps="tmux locales" \
&& apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y $buildDeps $softDeps --no-install-recommends \
&& locale-gen en_US.UTF-8 \
&& localedef -f UTF-8 -i en_US en_US.UTF-8

user docker

RUN git clone --depth 1 https://github.com/c9/core.git /home/docker/cloud9
WORKDIR /home/docker/cloud9
RUN git pull origin master\
&& NO_PULL=1 scripts/install-sdk.sh \
&& git reset --hard

USER root

RUN apt-get purge -y --auto-remove $buildDeps \
&& apt-get autoremove -y \
&& apt-get autoclean -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

USER root

RUN npm cache clean --force

USER docker
EXPOSE 8080
WORKDIR /var/www/html

CMD /usr/bin/node /home/docker/cloud9/server.js -l 0.0.0.0 -p 8080 -w /var/www/html -a :

Best regards,
Alex

Modules lost in CI

In a CI environment, if a project runs:

sudo composer install

all custom PHP settings are lost (!)

This is because "sudo" loses all environment variables and because "composer" actually points to a script that will first regenerate php.ini conf (because we need to generate conf for "composer install" if run inside a Docker build where conf has not been generated yet)

We need to find a way to make sure the conf is regenerated when composer is called ONLY if we are in a Dockerfile and not when we are in a container running.

Missing mysql-client on fat image

Expected Behavior

I was expecting to see mysql-client on the fat image since mysql is the default database extension.

Current Behavior

Unable to make cli mysql database connections.

Possible Solution

apt-get install mysql-client

Steps to Reproduce

  1. which mysql

Context

You probably have a reason for not including mysql-client. But I wanted to ask anyway. I have no problem adding this to my own sub-image. But maybe you are open to installing it on the fat base images.

Your Environment

  • Version used: thecodingmachine/php:7.2-v2-apache-node10
  • Operating System and version: Linux 350f1de01c97 4.15.0-42-generic #45-Ubuntu SMP Thu Nov 15 19:32:57 UTC 2018 x86_64 GNU/Linux
  • Link to your project: https://github.com/verbruggenalex/php-c9

Installing PHP Image Magick

How can I install image magick into this for use with PHP?

Maybe something like this?

RUN apt-get update && apt-get install -y \
        libmagickwand-dev --no-install-recommends \
    && pecl install imagick-beta \
     && docker-php-ext-enable imagick \
    # Clean Up \
    && rm -rf /var/lib/apt/lists/*

Version: thecodingmachine/php:7.2-v1-apache-node10

Or should I do it as a start-up command or make my own dockerfile that inherits from yours?

To test if loaded a php file like this should output available formats.

<?php
if(extension_loaded('imagick')) {
    $imagick = new Imagick();
    print_r($imagick->queryFormats());
}
else {
    echo 'ImageMagick is not available.';
}

The environment variable way

STARTUP_COMMAND_1: "sudo apt-get update && sudo apt-get install -y php-imagick"

Gives me this error.
E: Package 'php-imagick' has no installation candidate

Image does not work on Bitbucket Pipelines

Expected Behavior

When I add PHP_EXTENSION_INTL=1 to my bitbucket pipelines env variables, I expect the intl extension to be loaded.

Current Behavior

Currently, it is not loaded. When I run echo $PHP_EXTENSION_INTL, it outputs 1.

Possible Solution

I think bitbucket only injects the user configured env variables after it has booted the container.

Amend documentation about CMD / ENTRYPOINT for CLI

When using the CLI images, it is implied that you should set a CMD (and this is shown in the one CLI example via command line), but it would help if at least one docker compose example and/or Dockerfile example showed this explicitely - it could be a CLI example running phpunit, which would be a common use case.

I tried setting up an ENTRYPOINT instead of a CMD, which overwrote the ENTRYPOINT of the image and lead to unexpected results (like php.ini settings not being set up), so a warning not to use ENTRYPOINT in a Dockerfile might also help, as most docker tutorials advise on using ENTRYPOINT instead of CMD, or using both together for executable containers.

Add support for php.ini variables containing special chars

My php container that connects to redis (with password)

api:
    image: thecodingmachine/php:7.1-v1-apache
    ...
    environment:
      ...
      PHP_INI_SESSION__SAVE_HANDLER: redis
      PHP_INI_SESSION__SAVE_PATH: "tcp://redis:6379?auth=123"

When I try to access redis session store, I get the following error :
session_start(): open(tcp://redis:6379?auth/sess_p6rqfk7phj43d477k37d3iecb4, O_RDWR) failed: No such file or directory

It seems that the the variable has been stripped after the equal sign.

Enabling amqp extension results in a broken setup

Expected Behavior

I expect that my configuration of a container:

  php-cli:
    image: 'thecodingmachine/php:7.2-v1-cli'
    volumes:
      - './:/usr/src/app:delegated'
    environment:
      PHP_EXTENSION_AMQP: 1

is correct and creates a container with amqp extension enabled.

Current Behavior

I'm running docker-compose up with the config above.
and see

php-cli_1   | PHP Warning:  PHP Startup: Unable to load dynamic library 'amqp.so' (tried: /usr/local/lib/php/extensions/no-debug-non-zts-20170718/amqp.so (librabbitmq.so.4: cannot open shared object file: No such file or directory), /usr/local/lib/php/extensions/no-debug-non-zts-20170718/amqp.so.so (/usr/local/lib/php/extensions/no-debug-non-zts-20170718/amqp.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
php-cli_1   | time="2018-10-20T21:19:29Z" level=info msg="read crontab: /tmp/generated_crontab"
php-cli_1   | time="2018-10-20T21:19:29Z" level=fatal msg="bad crontab line: Warning: PHP Startup: Unable to load dynamic library 'amqp.so' (tried: /usr/local/lib/php/extensions/no-debug-non-zts-20170718/amqp.so (librabbitmq.so.4: cannot open shared object file: No such file or directory), /usr/local/lib/php/extensions/no-debug-non-zts-20170718/amqp.so.so (/usr/local/lib/php/extensions/no-debug-non-zts-20170718/amqp.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0"
php-cli_1   | PHP Warning:  PHP Startup: Unable to load dynamic library 'amqp.so' (tried: /usr/local/lib/php/extensions/no-debug-non-zts-20170718/amqp.so (librabbitmq.so.4: cannot open shared object file: No such file or directory), /usr/local/lib/php/extensions/no-debug-non-zts-20170718/amqp.so.so (/usr/local/lib/php/extensions/no-debug-non-zts-20170718/amqp.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0
php-cli_1   | bash: line 2: syntax error near unexpected token `('
php-cli_1   | bash: line 2: `Warning: PHP Startup: Unable to load dynamic library 'amqp.so' (tried: /usr/local/lib/php/extensions/no-debug-non-zts-20170718/amqp.so (librabbitmq.so.4: cannot open shared object file: No such file or directory), /usr/local/lib/php/extensions/no-debug-non-zts-20170718/amqp.so.so (/usr/local/lib/php/extensions/no-debug-non-zts-20170718/amqp.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0'

and non-working container.

Your Environment

  • Version used: php:7.2-v1-cli
  • Operating System and version: macOS High Sierra

ZipArchive::setEncryptionName is not defined (ziplib is not up to date)

ZipArchive::setEncryptionName should have been available since PHP 7.2. However, I get the error Call to undefined method ZipArchive::setEncryptionName() when using the function.

When checking out phpinfo, I see that libzip version 1.1.2 is used. Research indicates that this must be increased to version 1.2.0.

Expected Behavior

ZipArchive::setEncryptionName() should be defined.

Current Behavior

ZipArchive::setEncryptionName() is not defined.

Possible Solution

Update libzip to version 1.2.0 or newer.

Steps to Reproduce (for bugs)

$zip = new ZipArchive();
if ($zip->open('test.zip', ZipArchive::CREATE) === TRUE) {
    $zip->setPassword('secret');
    $zip->addFile('text.txt');
    $zip->setEncryptionName('text.txt', ZipArchive::EM_AES_256);
    $zip->close();
    echo "Ok\n";
} else {
    echo "KO\n";
}

Your Environment

  • Version used: thecodingmachine/php:7.2-v1-apache-node10
  • Operating System and version: Windows 10

Timezone issue with Crons

Crons seems to be triggered at the UTC date (because the default timezone for the container is UTC, whatever the timezone of the host).

We should probably document this and provide guidance on how to set the timezone in a container.

Startup commands issues for some owners on the directory containing docker-compose.yml file

There are issues using STARTUP_COMMAND in docker-compose.yml file (tested on Ubuntu 17.10).

With STARTUP_COMMAND_1: composer install :

sudo: no tty present and no askpass program specified
php_apache_node exited with code 1

With STARTUP_COMMAND_1: npm install :

Error: EACCES: permission denied, mkdir '/home/docker/.npm'

Solution : my directory containing the docker-compose.yml file was owned by www-data:www-data.
Changing owning of the directory to ${USER} solved the issues.

Error with PHP exif extension

I've enabled the exif extension using PHP_EXTENTION_EXIF: 1 and phpinfo() confirms that it is enabled. However, when I call exif_read_data() I get the following error: Call to undefined function exif_read_data().

I've recreated the error on two separate machines. I've even gone as far as to run the code on a XAMPP stack to ensure my code works. I've been able to turn on other extensions--this one is the first time I've had trouble with this.

Running docker on Windows 10. Using the php:7.2-v2-apache-node10 image.

Files ownership problem when running internal commands

Hi there !

It seems that the "black magic" used for permissions has some "dark effects" ๐Ÿ˜„.
When I execute a command whithin the container, the files generated from it belong to root and not to the docker user.

For instance, I have an Angular application in an app folder mapped into /var/www/html. If i run npm install from the host, the owner will be the docker user as expected. But, if I run the command from the container (with the docker user), it will generate a node_modules folder that belongs to root !

Otherwise, it's a hell of a docker image ๐Ÿ‘

Add custom extension

I use the image thecodingmachine/php:7.2-v2-apache (the 7.3 is not on docker hub), and I want to add a custom extension in php. I have a .so, but how can I add automatically in the extension directory and enable it ?

I found the extension directory but the name is /usr/local/lib/php/extensions/no-debug-non-zts-20170718/ and I don't know how can I automatically get it.

Is it possible to add easily a custom .so extension ?

No default command for PHP-CLI

There is no default command for PHP CLI. This leads to weird error message when called with no commands.

$ docker run thecodingmachine/php:7.2-v1-cli

usage: sudo -h | -K | -k | -V
usage: sudo -v [-AknS] [-g group] [-h host] [-p prompt] [-u user]
usage: sudo -l [-AknS] [-g group] [-h host] [-p prompt] [-U user] [-u user]
            [command]
usage: sudo [-AbEHknPS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p
            prompt] [-u user] [VAR=value] [-i|-s] [<command>]
usage: sudo -e [-AknS] [-r role] [-t type] [-C num] [-g group] [-h host] [-p
            prompt] [-u user] file ...

TODO: add a default command (maybe "php -a" ?)

Errors in STARTUP_COMMAND_XXX are not fatal

When an error occurs in STARTUP_COMMAND_XXX, the container does still start.

It would be a better practice to halt the container if any startup command returns an error. Otherwise, the error might go unnoticed.

Imagick for slim image

I noticed that Imagick extension cannot be enabled (it is not on the list of available extensions) when slim container is used. Can that be fixed somehow?

Fat image works fine with this extension

pdo as extension does not exist

In the documentation in almost all examples of building slim images the extension "pdo" is used - an example:

ARG PHP_EXTENSIONS="apcu mysqli opcache pdo pdo_mysql redis zip soap" directly under "Compiling extensions in the slim image".

But "pdo" is not a valid extension when trying to build the container - this is my output (for php 7.2 slim cli, the same with slim fpm):

Building container
Step 1/16 : ARG PHP_EXTENSIONS="opcache pdo pdo_mysql zip"
Step 2/16 : FROM thecodingmachine/php:7.2-v2-slim-cli
# Executing 7 build triggers
 ---> Using cache
 ---> Running in 548c6d0e99cd
Removing intermediate container 548c6d0e99cd
 ---> Running in ca7979a4a321
*** Installing extensions ***
The following extension(s) is not supported: pdo
Supported extensions: amqp, apcu, ast, bcmath, blackfire, bz2, calendar, dba, ds, enchant, ev, event, exif, gd, gettext, gmp, gnupg, igbinary, imagick, imap, intl, ldap, mailparse, mcrypt, memcached, mongodb, mysqli, opcache, pcntl, pcov, pdo_dblib, pdo_mysql, pdo_pgsql, pgsql, pspell, redis, shmop, snmp, soap, sockets, swoole, sysvmsg, sysvsem, sysvshm, tidy, wddx, weakref, xdebug, xmlrpc, xsl, yaml, zip

I suspect this is just a documentation error, but it is in all the examples and in the list of valid extensions, so it is likely people will stumble over it, as I did.

Crontab user must be root

When the user is not root the cron isn't executed.
I try to create a file with this:

echo "oui">/var/www/html/test.txt

This work for root and not for other user.

Permission denied issue when using php's internal web server

Expected Behavior

I'd like to use the php:7.2-v1-cli using php's internal web-server

Current Behavior

Session files (like /usr/src/app/var/sessions/dev/sess_b769a9b5b9f1f3e2b57b739f5788aca9 ) are owned by root, triggering errors

Steps to Reproduce (for bugs)

  1. in a symfony project using the web server bundle, use this docker-compose.yml
services:
    php:
        command: php bin/console server:run 0.0.0.0:8000
        ports:
            - "8000:8000"
        image: thecodingmachine/php:7.2-v1-cli
        volumes:
            - .:/usr/src/app
        environment:
            PHP_INI_MEMORY_LIMIT: -1
            PHP_EXTENSION_GNUPG: 1
  1. execute docker-compose up php
  2. open browser on http://127.0.0.1:8000

The error should happen immediatly

Warning: SessionHandler::read(): open(/usr/src/app/var/sessions/dev/sess_b769a9b5b9f1f3e2b57b739f5788aca9, O_RDWR) failed: Permission denied (13)

Context

I've been using php-cli with php's internal web server like this until now and thought I'd give your image a try using the same approach. Ironically, it was the permission "black magic" that motivated my switch :-)

Your Environment

OS : archlinux
docker 18.06.1-ce

Allow APACHE_DOCUMENT_ROOT to be set outside of /var/www/html

Expected Behavior

I think that APACHE_DOCUMENT_ROOT should be allowed to be set outside of /var/www/html. Since regular Apache configuration allows it.

Current Behavior

Currently you can only set a subfolder of /var/www/html:
https://github.com/thecodingmachine/docker-images-php/blob/v2/Dockerfile.7.2.slim.apache#L77-L80

Possible Solution

The solution would be to set the default to /var/www/html and if the variable is set override the entirety of the default instead. Problem is that I don't see a way that keeps backward compatibility without introducing a secondary variable.

Context

The reason for me requesting this is because on my development environment I'm using Docker in Docker setup to control my environment from inside. When using docker-compose you'd want to have the path be the exact same as on your host system. This allows you to docker-compose ps your docker system.

Missing PECL uploadprogress on fat image

Expected Behavior

When using image for Drupal I expect to see the PECL uploadprogress library on the image.

Current Behavior

Not present. Drupal status report page mentions it not being enabled.

Possible Solution

RUN git clone https://github.com/php/pecl-php-uploadprogress/ /usr/src/php/ext/uploadprogress/ \
&& docker-php-ext-configure uploadprogress \
&& docker-php-ext-install uploadprogress \
&& rm -rf /usr/src/php/ext/uploadprogress

Context

This is really dependent on whether your project requires the uploadprogress library. Just thought I'd share with you my work.

Environment

  • Version used: thecodingmachine/php:7.2-v2-apache-node10
  • Operating System and version: Linux 350f1de01c97 4.15.0-42-generic #45-Ubuntu SMP Thu Nov 15 19:32:57 UTC 2018 x86_64 GNU/Linux
  • Link to your project: https://github.com/verbruggenalex/php-c9

PHP max_execution_time is not respected

docker run -it --rm -e PHP_INI_MAX_EXECUTION_TIME=60 thecodingmachine/php:7.1-v2-cli php -r "phpinfo();" | grep max

Expected Behavior

max_execution_time => 60 => 60

Current Behavior

max_execution_time => 0 => 0

I don't know why is it like that. Any ideas:

lsb_release -a                                                                                                                                                                                                                                                               
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 18.04.1 LTS
Release:	18.04
Codename:	bionic

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.