decorative image for blog on linux php images
April 20, 2023

The Importance of Easy-To-Use PHP Linux Images

PHP Development

Working with community PHP Linux images can be a headache. Luckily, there are other options available.

In this blog, I'll walk through the reality of working with PHP Linux images today, the impact that user-friendly images can have, and walk through how to get started with Zend PHP Linux images.

Back to top

The Reality of Working With PHP Linux Images Today

In today's Docker ecosystem, you generally have two choices of PHP Linux images: 

  • the official PHP images from Docker Hub    
  • creation of your own images using the OS of your choice and community PHP packages 

"Official" PHP Images

The official PHP Linux images are difficult to configure. They have an incredibly minimal installation by default, which means a number of core extensions you may be accustomed to then need to be configured, compiled and installed:

docker-php-ext-configure {extension name} {any ./configure flags/options} 
docker-php-ext-install -j$(nproc) {extension name} 

Any PECL extensions need to be installed using PECL (which often does not work on PHP 8 versions), with the addition of then requiring an enablement step to ensure that the php.ini finds and enables the extension.

pecl install {extension name and optionally version} 
docker-php-ext-enable {extension name} 

Making this more convoluted is the fact that these steps are done using scripts specific to the container images, and which contain little documentation, nor good reporting when errors occur.

On top of that, there are some additional issues to consider:

  • In order to compile extensions, whether core or from PECL, you will need to know what system libraries are required, and what packages to install to provide them.
  • Compilation tools are always installed by default in these images, which you likely do not want for production. As such, you will need to uninstall compilers and shared library development packages manually in your Dockerfile. If you can find them, that is.

There's another limitation: the official Docker images for PHP only come for two operating systems: Alpine and Debian. This also means that for variants of the images that provide Apache, the configuration location for Apache will vary from image to image. If your organization or business has expertise in other distributions, you're on your own.

Building Your Own PHP Images

Which brings us to creating your own images.

A common practice we've observed is using an OS base image, and then using a community distribution such as the Remi repository for RPM-based distributions or the Sury repository for Debian-based distributions. Any version of PHP present in these distributions can then be installed, and they offer the benefit of providing packages for a large array of PHP extensions as well.

The issues here are as follows:

  • Many of the PHP versions available in these package repositories are not receiving security patches, which means your images may be vulnerable to a variety of security exploits.
  • You become responsible for maintaining your image and its dependencies.
  • The image size when using a standard Linux distribution can be quite large, leading to larger storage requirements and increased startup times.

For some operating systems, there is no equivalent of the Remi or Sury repositories. For instance, on Alpine, you get one PHP version at a time, and there are no community builds of other PHP versions.

Another issue that presents to those building their own images is that if they decide later to switch to a different operating system, or update their OS to a new version, they often will have to completely rewrite their images. Package names change, configuration locations move, and more. And if any custom extensions are being compiled, the packages for library dependencies will likely have changed as well.

The reality is that containerized PHP is difficult to manage and secure. 

Back to top

The Impact of Easy-to-Use Linux PHP Container Images

What if there were a way to make this simpler? What would that look like? 

  • There would be support for multiple operating systems and versions.
  • All PHP versions provided would be receiving security updates.
  • There would be tooling provided that made installing extensions the same across operating systems and OS versions.
  • There would be standard tooling for compiling PECL extensions across operating systems and OS versions.
  • There would be a standard location for configuration, both for PHP and for Apache (if provided).
  • The images should have logic for cleaning up and removing compilation tools once setup.
  • Ideally, the images should have at least some minimal security tooling to help prevent container escape, such as s6-overlay

 There will always be some caveats: you'll still need to know what library dependency packages to install when compiling extensions. However, the above items should provide consistency.

What would having these guarantees in place do for you and your team?

First, you get security. You would know that the PHP version you deploy has the latest security patches present, and that you have tooling in place in the image to prevent container escape should an attacker still find a vector that gives them privilege escalation or remote code execution capabilities. Without compilation tooling present, an attacker has an even more limited set of tools to work with should they gain access.

Second, you get true portability. You can choose which OS and OS version you want to use in your organization, and not then have to either choose between the official images or building your own. You keep control of which PHP version you use, and which operating system and version you use.

Because of this portability, you can swap out the base OS and version, and generally things would still work, giving you greater confidence and flexibility in updating your images to take advantage of new OS versions, which in turn helps you continue to keep your application more secure.

Sound too good to be true? It's not. We provide it with ZendPHP

Back to top

How to Get Started With Zend PHP Linux Images

Zend provides a container registry at cr.zend.com. This registry contains primarily ZendPHP images, but also some Zend Server images.

All ZendPHP images have the following naming convention:

cr.zend.com/zendphp/{PHP minor version}:{os}-{os version}-{PHP SAPI}(-arm)

(NOTE: The "-arm" suffix is optional, and only should be used if you are deploying on ARM architecture.) 

Additionally, all ZendPHP containers contain our zendphpctl command line tool, which allows you to script the installation of extensions and enablement of PHP SAPIs in a distribution-agnostic way. You get the benefits of OS-specific binary packages, with an OS-agnostic tool. As an example, to enable FPM and install the mysqli, intl, and redis extensions, you would use the following commands regardless of the operating system:

zendphpctl fpm install 
zendphpctl ext install mysqli intl redis 

(In reality, you will likely choose a base container image for PHP-FPM from the outset!)

To make things even easier, we provide a re-usable custom Dockerfile that utilizes Docker build arguments in order to customize the image. It has build arguments for specifying additional system packages to install, PHP extensions to install and/or build, whether or not to include Composer in the image, the location of a post-build script to run, PHP-FPM options (user to run the PHP-FPM pool as, application root), and even mechanisms for including Apache configuration (if using Apache). This means you can use the same Dockerfile within orchestration configuration to build multiple different images. As a quick docker-compose.yml services definitions example: 

api: 
  build: 
   context: . 
   dockerfile: php.Dockerfile 
   args: 
     ZEND_EXTENSIONS_LIST:'bcmath bz2 curl intl mbstring mysqli pdo_mysql 

xml xsl zip' 
     OS:'alpine' 
     OS_VERSION:'3.16' 
     ZENDPHP_VERSION:'8.1' 
     BASE_IMAGE:'fpm' 
     TIMEZONE:'UTC' 
worker: 
  build: 
    context: . 
    dockerfile: php.Dockerfile 
    args: 
      ZEND_EXTENSIONS_LIST:'bcmath bz2 curl intl mbstring mysqli pdo_mysql readline tidy xml xsl zip' 
      OS:'ubuntu' 
      OS_VERSION:'22.04' 
      ZENDPHP_VERSION:'8.2' 
      BASE_IMAGE:'cli' 
      TIMEZONE:'UTC' 
      INSTALL_COMPOSER:1

Two different use cases, different PHP versions, different extensions, even different operating systems, all from the same Dockerfile. This level and ease of customization helps your DevOps teams be more productive, make decisions based on technical needs and use cases versus OS limitations, and provides the flexibility to change PHP versions, operating systems, and more in a way that will be more robust and fault tolerant.

Back to top

Final Thoughts

There are plenty of challenges DevOps teams can expect when containerizing their PHP applications, but the unexpected difficulty of working with community images can serve as an early and painful roadblock.

As shown above, there are alternatives to community images. And while some will still want to build their own images, Zend PHP Linux images will offer a much more user-friendly and adaptable solution than community images. 

Get Started With Zend PHP Linux Images

Ready to see how easy-to-use PHP Linux images from Zend can help your team? Get started today via the links below.

Try ZendPHP for FreeVisit the Zend Container Registry

Additional Resources

Back to top