Using ZendPHP via Docker

This topic describes the procedures for using ZendPHP from a Docker image.

The Docker ecosystem provides a number of tools for container orchestration. Zend by Perforce provides templates for Docker Compose, Docker Swarm/Stack, and Kubernetes (k8s) demonstrating how to set up a session cluster using ZendPHP, a web server, and Redis. You can download these templates from

If you are familiar with using Docker to install or update applications, use the information in the table below to get started; otherwise, continue reading for more detailed information on using ZendPHP from a Docker image.

Zend Container Registry
Login Login first using docker login -u {order-id} before using the pull command
pull command docker pull{PHP_VERSION}:{OS}-{OS_VERSION}-{specialties}

Use a pre-built ZendPHP image

Zend provides some pre-built images for Ubuntu, CentOS, and Debian in our container registry.

  1. Login to Zend's container registry using the credentials provided to you.

    docker login

  2. Pull the image. For example, to pull the FPM specialty for PHP 7.4 on Ubuntu 20.04, use the following command:

    docker pull

    Note Use the docker-ls tool to get a full list of the images Zend provides. If you do not see the one you need, please let us know.

After pulling an image you are now ready to run it. See the Using Docker images section for more information on using images.

Build-argument customizable image

If you would prefer to build your own image, Zend provides a customizable Dockerfile.

  1. Download the customizable Dockerfile or you can copy and paste the file from Custom Dockerfile.

  2. Build the image using the docker build command. The list of build arguments is included at the end. For example:

    docker build -f Dockerfile.Custom -t zendphp-8.0-fpm --build-arg OS=debian \ --build-arg OS_VERSION=10 --build-arg ZENDPHP_VERSION=8.0 --build-arg BASE_IMAGE=fpm \ --build-arg "ZEND_EXTENSIONS_LIST=mysqli pdo pdo-mysql tidy" \ --build-arg .

    Note For this example to work, you MUST have at least one .sh script present for the custom image (due to the COPY *.sh /usr/local/sbin line); either that, or you should omit it if there are no additional tasks.
  3. After building the image, you can use docker run to create the container. For example, to create a container from the image you just built you might use:

    docker run -dp 3000:3000 zendphp

After building an image you are now ready to run it. See the Using Docker images section for more information on using images.

Build arguments

The following build arguments can be used with Zend's custom Dockerfile:

  • OS: Specific OS to use. You can set this to ubuntu, centos, or debian. This is set to ubuntu by default.
  • OS_VERSION: Specific OS version to use. Do not set this as currently Zend only provides one OS version for each OS. The image defaults to correct version for the OS you select.
  • ZENDPHP_VERSION: PHP version to use. Defaults to 7.4.
  • BASE_IMAGE: Either cli or fpm. This is set to fpm by default.
  • TIMEZONE: Timezone to use within the image. This is set to UTC by default.
  • INSTALL_COMPOSER: Select whether or not to add Composer to the image. It is set to false by default. Set it to true if you wish to add Composer to the image.
  • SYSTEM_PACKAGES: Space-separated list of additional system packages to install. This is not set by default.
  • ZEND_EXTENSIONS_LIST: Space-separated list of additional ZendPHP packages to install (e.g., mysqli, pgsql, and so forth). This is not set by default. Do not include any package prefix. (Packages are prefixed based on the OS, and generally follow the format php7.4-zend or php74zend-.)
  • PECL_EXTENSIONS_LIST: Space-separate list of PECL extensions to install using the PECL tool. This is not set by default.
  • POST_BUILD_BASH: Path to a .sh script to run after all other install tasks are complete (the images copy any *.sh scripts in the build context to /usr/local/sbin/ for this purpose). This is not set by default.

Custom Dockerfile

Zend provides you with a customizable Dockerfile you can use to create a custom image. You can download the file from this page or copy it from here:

# OS=one of ubuntu, centos, or debian ARG OS=ubuntu # OS_VERSION=OS version to use; e.g., 20.04, 8, and 10 ARG OS_VERSION=20.04 # PHP version to use; can be 5.6, 7.1, 7.2, 7.3, 7.4, or 8.0. # Ability to build a version is dependent on having ZendPHP credentials that # authorize use of that version. ARG ZENDPHP_VERSION=7.4 # BASE_IMAGE=cli or fpm ARG BASE_IMAGE=fpm FROM${ZENDPHP_VERSION}:${OS}-${OS_VERSION}-${BASE_IMAGE} # CUSTOMIZATIONS # # TIMEZONE=timezone the OS should use; UTC by default ARG TIMEZONE=UTC # INSTALL_COMPOSER=true or false (whether or not Composer will be installed in # the image) ARG INSTALL_COMPOSER=false # SYSTEM_PACKAGES=list of additional OS-specific packages to install (e.g., # cron, dev libraries for building extensions, etc.) ARG SYSTEM_PACKAGES # ZEND_EXTENSIONS_LIST=list of packaged ZendPHP extensions to install and # enable. These should omit the prefix php{VERSION}-zend (DEB) or # php{VERSION}zend (RPM); e.g., mysqli, pdo-pgsql, etc. ARG ZEND_EXTENSIONS_LIST # PECL_EXTENSIONS_LIST=list of PECL extensions to compile, install, and enable. # You will need to install the dev/devel package for the ZendPHP version you are # using, and any additional devel libraries that may be required. ARG PECL_EXTENSIONS_LIST # POST_BUILD_BASH=name of a bash script to execute following build tasks. These # should be named *.sh in the directory relative to Docker build context, and be # executable. Such scripts can be used to further customize your image. ARG POST_BUILD_BASH ## Prepare tzdata ENV TZ=$TIMEZONE \ YUM_y='-y' RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone ## Customize PHP runtime according ## to the given building arguments COPY *.sh /usr/local/sbin/ RUN

Using ZendPHP Docker images

After building a ZendPHP docker image, you need to run it. In the case of a CLI image, this is a no-op; you need to specify a command in the container to run. For FPM images, running the image starts a php-fpm pool.

Consuming a CLI image

To "consume" a CLI image, run a command, most likely PHP itself, in the container. For instance, you may want to run a script in your current directory using the PHP binary in your CLI image. Do so by mapping your current directory as a volume, specifying it as the working directory, and then invoking the PHP binary on a script in the directory. For example, to run the script test.php in your current directory:

$ docker run -it -v `pwd`:/workdir -w /workdir \ php test.php

You can also use the image to install dependencies. For example, if you create a custom image based off CLI with Composer enabled, you could run it with:

$ docker run -it -v `pwd`:/workdir -w /workdir zendphp-8.0-composer composer install

Consuming an FPM image

By default, Zend's FPM images configure a PHP-FPM pool that runs on port 9000, and the image exposes port 9000. This is true even of images you create using Zend's custom Dockerfile. For this, you need an Apache, nginx, or other webserver sitting in front of your ZendPHP FPM image(s) in order to consume them. These can be their own Docker images or be standalone servers running elsewhere and connecting to your instances.

Via Apache

Your Apache instance needs the mpm_event module enabled (and the mpm_prefork module disabled). Additionally, it requires the proxy and proxy_fcgi modules. Refer to the Apache manual and/or your distribution's tooling for information on how to accomplish these tasks.

From there, create a configuration file in the conf.d subdirectory of your Apache configuration; generally, this is /etc/httpd/conf.d, /etc/apache2/conf-enabled, or similar. Name the file php-fpm.conf and create it with the following contents:

# Allow php to handle Multiviews # AddType text/html .php # Add index.php to the list of files that will be served as directory # indexes. DirectoryIndex index.php # Enable http authorization headers SetEnvIfNoCase ^Authorization$ "(.+)" HTTP_AUTHORIZATION=$1 # Redirect to php-fpm <FilesMatch \.(php|phar)$> SetHandler "proxy:fcgi://{HOSTNAME}:9000" </FilesMatch>

Substitute {HOSTNAME} with the name of the server or container exposing php-fpm.

Once your changes are made, restart your web server, or fire up your container with the Apache instance, and verify that you can reach PHP pages in your application.

Via nginx

In an nginx virtual host definition, you can tell the server to proxy to the php-fpm instance by matching any .php file. As an example:

location ~ \.php$ { include /etc/nginx/fastcgi_params; fastcgi_pass {HOSTNAME}:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }

Substitute {HOSTNAME} with the name of the server or container exposing php-fpm.

Once your changes are made, restart your web server, or fire up your container with the nginx instance, and verify that you can reach PHP pages in your application.