Series Part III — Optimizing My Alpine Docker Image for Use With Drupal 8.x and PHP 7.3 — adding mbstring and opcache

Callback Insanity
7 min readJan 3, 2020
Photo by Daniel von Appen on Unsplash

In the first part of this series I my Alpine Docker container for PHP FPM on a dependency diet and brought it down to a manageable 29.5MB megabytes.

In the second part of the series I updated Composer and Drush containers to use the container I created in the first story as a base, then proceeded to use the Drush container to successfully download the latest stable version of Drupal 8 without any warnings or errors.

At the end of the second story I proceed to install Drupal using the web GUI, because, why not? The web installation, however, was not free of errors, and so I left it to a next story to address those. That next story is this story.

Welcome to the third part of this series on Optimizing My Alpine Docker Image for Use With Drupal 8.x and PHP 7.3.

On today’s story I will addressing the warnings or errors I encountered in part II:

  • Drupal installer complains that opcode cache PHP extension is missing.
  • Drupal installer complains that mbstring PHP extension is missing.
  • Missing styles in installed Drupal site, probably due to permissions, Nginx configuration, or both.

The first items are piece of cake, so I’ll take care of the low hanging fruit first then I’ll take care of optimizing Nginx for Drupal 8 in a separate story.

I can’t: containers are part of religion…

Adding opcache for performance and mbstring for compliance

What is opcache? From php.net:

OPcache improves PHP performance by storing precompiled script bytecode in shared memory, thereby removing the need for PHP to load and parse scripts on each request.

These two articles contain more background information on PHP’s opcode cache if you’re interested:

For reference, here’s the warning from the Drupal installer complaining that opcache is missing from the list of PHP extensions, as well as mbstring:

Please install opcode and mbstring, pretty please?

The purpose of writing about adding these two extensions will be not about their background history or detailed benchmark statistics, but rather how will adding them to my Alpine Docker image affect it’s size. Adding these two PHP extensions to my Docker image would only take seconds if I wasn’t writing about it. However I feel it is both compelling and fruitful to produce a story about the finer details of my profession. Compelling because it is, or at least meant to be relatable. Fruitful because it captures not only the technical reasoning behind each optimization, but most important it’s consequences.

In the second part of my series I added mbstring to the Composer Docker image because Composer was refusing to be installed without php7-mbstring present on the system.

However, adding mbstring to Composer will do me no good if Drupal requires it as well, since Drupal is being served by the PHP FPM service, not by Composer. PHP FPM does the job of actually parsing the Drupal code and serving Drupal web pages, Composer and Drush don’t — they’re command line tools for installing stuff using … the command line. Therefore I need to add both mbstring and opcode to the PHP FPM container. I’ll remove them from the command line tools containers because since they are built from the PHP FPM image, they will inherit both PHP extensions.

Without further ado, let’s proceed:

Removing php7-mbstring from the Composer Docker image

And here’s adding them to the base php-fpm Docker image, from which the Composer and Drush images are built as well:

Added php7-mbstring and php7-opcache extesions to php-fpm Alpine Docker image

With the editing side of business complete, it’s time to rebuild the php-fpm, Composer, and Drush images.

This is the php-fpm image before the being rebuilt (29.5MB ):

Build command:

# Build PHP-FPM base image and Composer and Drush child images.
docker-compose -f ./build/php-fpm/docker-compose.yml build \
&& docker-compose -f ./build/php-cli/docker-compose.yml build
php7-mbstring and php7-opcache added during Docker build

And the survey says …

Rebuilt php-fpm image (highlighted) with both mbstring+opcode extensions added

So the PHP FPM image went from 29.5MB megabytes to 31.4MB megabytes. That’s not bad at all! I was expecting a larger negative impact on the size of the image, but both extensions only added a combined 1.9MB megabytes in total. Amazing! And that’s why I ❤ Alpine Linux.

Because I am using three new sets of images (PHP-FPM, Composer, Drush), I have to tear down docker-compose down and recreate docker-compose up -d my stack again:

Tear it up; Then Bring ‘Er Up

With the rebuild complete, I can proceed to re-test the web-based Drupal install — both warnings about opcode and mbstring should be gone. Since last time the Unami Food Magazine Drupal install profile was giving some warnings about a missing profile module, I’m going to skip it and just use the standard install profile:

Using the Standard install profile

At the height of the install procedure, docker stats seems to tell the story of a Docker stack that is humming along:

Docker on Windows is just … cruising

With php-fpm doing most of the heavy lifting (35% assigned CPU), and the total memory usage at %1.25 percent of the total assigned 7.786GiB gigabytes, I’m impressed how smooth the whole stack is behaving.

Maybe the opcode cache has kicked in now that it has been installed. But memcached is definitely not yet configured to be used by Drupal (even though it is available and running on the Docker stack).

In the sites/default/settings.php I can see that the Drupal web installer has written a new configuration setting for the new database name I selected d8_standard . I’ve changed my database user to docker as well from the last Drupal install story I wrote:

Fresh new settings written by Drupal.

During the install procedure the GUI install wizard did not complain about any missing extensions. So I log in and head to the admin/reports/dblog page to scour for any errors or warnings that might have occurred during the install.

Successful install is successful.
Nginx needs to be optimzed for Drupal 8 now.
path/install.php/argument not found

According to some preliminary reading I’ve done, this error is probably related to Nginx virtual host configuration.

Let’s see what the rest of Drupal’s diagnostic tooling says. A diagnostics overview can be found at admin/reports/status . Mainly I am interested in seeing what’s PHP’s status about the opcache being present and enabled in the system.

Drupal Diagnostics Page admin/reports/status

Two errors, 1 warning. Along with some general system information, very well presented. The presentation on this page is definitely an upgrade from Drupal 6.x and 7.x.

Here’s the 2 errors and warnings:

Nothing to see here. Move on.

This is a development Docker stack meant for development on localhost only, so I’m not concerned about access to update.php, Trusted Host settings, or update notifications.

About that opcode cache PHP extension:

Install successful, extension recognized.

The status page says PHP OPcode is enabled. If you click on the link that says more information, right next to the PHP version (7.3.13), it takes you to PHP’s own status page, which is generated by the phpinfo() function:

And … it is enabled. OPCode, that is.

About the mbstring PHP extension, it shows up under Zend Multibyte Support. Sounds like something from the future:

mbstring is enabled by default when installed on Alpine as well

And that concludes today’s story. Remember that on the next and fourth part of this series I will be documenting my journey through optimizing the Nginx Docker container for use with this version of Drupal 8.

Thank you for reading my series about Alpine Docker, Drupal 8.x, PHP 7.x., and if you enjoyed, make sure to subscribe or clap !!!

Until next time.

--

--

Callback Insanity

Organic, fair-sourced DevOps and Full-Stack things. This is a BYOB Establishment — Bring Your Own hipster Beard.