Zaher Ghaibeh
PHP Backend developer
I've experience in a few PHP Frameworks, such as Laravel, Lumen and Slim (The last two are used for building Microservices/API services).
How to install external PHP Modules in Docker
Published at Wednesday, January 18, 2017 , Categorized under: docker, PHP

Over the time, while you are trying to work with docker, you will like what you see, you will like the idea that you are building one linux distro which can do one thing only, and that's for me a passion ..

And everyday you will have something new to discover, am not going to talk a lot but I'll put the past and the new way that I have found which helped me to install external PHP module (xDebug) without any problem.

Before, when I wanted to include xDebug in any PHP Docker image I build, I'll download the source code, compile it and then try to move the module file xdebug.so to the PHP extension directory ( or use pecl to install it ), which was simple when you are using Ubuntu, but this will also lead to have a big image 500+MB in size and so your Dockerfile will be something like this:

FROM php:7-fpm

RUN apt-get update && apt-get upgrade -y && apt-get autoremove -y   
   && apt-get install -y git libmcrypt-dev libpng12-dev libjpeg-dev libpq-dev mysql-client curl   
   && rm -rf /var/lib/apt/lists/*   
   && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr   
   && docker-php-ext-install mcrypt gd mbstring pdo pdo_mysql zip   
   && pecl install xdebug   
   && rm -rf /tmp/pear   
   && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)\n" >> /usr/local/etc/php/conf.d/xdebug.ini   
   && echo "xdebug.remote_enable=on\n" >> /usr/local/etc/php/conf.d/xdebug.ini   
   && echo "xdebug.remote_autostart=off\n" >> /usr/local/etc/php/conf.d/xdebug.ini   
   && echo "xdebug.remote_port=9000\n" >> /usr/local/etc/php/conf.d/xdebug.ini   
   && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

ADD php.ini /usr/local/etc/php/

USER www-data

WORKDIR /var/www

Please note that in this docker file I also install other internal module, like : mcrypt, gd, mbstring .. etc.

its simple and really can do the trick for me, and I'll have xDebug installed without any problem.

But while I was trying to learn Docker, I came across a nice small footprint linux distro called alpine, and I found out that many people/projects use it, and they use it a lot to create a small images for what they need, so I tried to get familiar with it, I modified my Dockerfile to make sure it will work with alpine and it become like this

FROM php:7.0-fpm-alpine
MAINTAINER Zaher Ghaibeh <z@zah.me>

ENV XDEBUG_VERSION 2.5.0

RUN apk update   
   && apk add  --no-cache libmcrypt  git mysql-client curl wget --virtual .build-deps freetype libxml2-dev   
   libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev libmcrypt-dev   
   make gcc g++ autoconf   
   && docker-php-ext-configure gd --with-png-dir=/usr --with-jpeg-dir=/usr   
   && docker-php-ext-install mcrypt pdo_mysql soap   
   && pecl install xdebug   
   && rm -rf /tmp/pear   
   && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)\n" >> /usr/local/etc/php/conf.d/xdebug.ini   
   && echo "xdebug.remote_enable=on\n" >> /usr/local/etc/php/conf.d/xdebug.ini   
   && echo "xdebug.remote_autostart=off\n" >> /usr/local/etc/php/conf.d/xdebug.ini   
   && echo "xdebug.remote_port=9000\n" >> /usr/local/etc/php/conf.d/xdebug.ini   
   && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer   
   && rm -rf /tmp/*

COPY php.ini /usr/local/etc/php/

USER www-data

WORKDIR /var/www

And I was happy when the build finished and the size of the image was about 300MB I mean I saved 200MB , but when I looked at the logs I noticed that xDebug was not installed correctly, and it always fail to load. So after a big and long journey to find the solution, I found out that I can use a command called docker-php-source  to achieve the best result and the usage of it is simple so we just extract the source, install the module, enable the module and then delete the source, like the following :

    && docker-php-source extract   
   && pecl install xdebug redis   
   && docker-php-ext-enable xdebug redis   
   && docker-php-source delete   

So my final Dockerfile has become like this :

FROM php:7.0-fpm-alpine
MAINTAINER Zaher Ghaibeh <z@zah.me>

RUN apk update   
   && apk add  --no-cache git mysql-client curl libmcrypt libmcrypt-dev   
   libxml2-dev freetype-dev libpng-dev libjpeg-turbo-dev g++ make autoconf   
   && docker-php-source extract   
   && pecl install xdebug redis   
   && docker-php-ext-enable xdebug redis   
   && docker-php-source delete   
   && docker-php-ext-install mcrypt pdo_mysql soap   
   && echo "xdebug.remote_enable=on\n" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini   
   && echo "xdebug.remote_autostart=off\n" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini   
   && echo "xdebug.remote_port=9000\n" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini   
   && echo "xdebug.remote_handler=dbgp\n" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini   
   && echo "xdebug.remote_connect_back=0\n" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini   
   && curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer   
   && rm -rf /tmp/*

USER www-data

WORKDIR /var/www

and the image is now working like a charm with xdebug and redis installed and enabled.

The only sad thing is that I was not able to make the size smaller, because mcrypt need the development libraries which should be always be within the image, without them I can get a smaller image 100MB.

Finally you can find my image on Docker Hub at this address :  https://hub.docker.com/r/zaherg/php-7.0-xdebug-alpine/.

PS: if you find any grammatical or lingual issue please let me know, as English is not my mother language, thanks.