Alpine variants of PHP and Apache/httpd in Docker
Solution 1
Running Apache/NGINX and PHP with FCGI
If you want to run Apache and PHP in separate containers, you'll need to use a PHP-FPM container (like for example, using the php:7-fpm
or php:7-fpm-alpine
image) and then use FCGI to connect the two. By default, the official PHP-FPM images expose the TCP port 9000 for this, which should be sufficient for most cases.
For PHP-FPM, the official PHP image should do fine (regarding size, the 7.0.14-fpm-alpine
tag is only 31M in size). Regarding Apache, I've come to like the webdevops/apache
image (I'm not affiliated in any way). It also comes with an Alpine-based version that is only 38M in size and works well together with PHP-FPM.
Here's how you start separate PHP-FPM and Apache containers, linked together using FCGI:
$ docker run -d \
-v /path/to/data:/var/www/html \
--name fpm \
php:fpm-7.0.14-alpine
$ docker run -d \
-v /path/to/data:/var/www/html \
--name apache \
--link fpm \
-e WEB_PHP_SOCKET=fpm:9000 \
-e WEB_DOCUMENT_ROOT=/var/www/html \
webdevops/apache:alpine-3
For using Nginx instead, simply substitute the webdevops/apache
image with webdevops/nginx
.
Adding custom extensions
Since you've also asked about adding additional PHP extensions to your image: this is covered in the official PHP image's documentation. You can add custom PHP extensions to the PHP base image by running docker-php-ext-install
in a custom Dockerfile:
FROM php:7.0.14-fpm-alpine
RUN docker-php-ext-install pdo_mysql
This allows you to build your custom image based on one of the PHP-FPM base images, adding all extensions that you require in the Dockerfile
.
Solution 2
Running official Apache and PHP with FCGI
In addition to helmberts proposed solution which worked for me I was fiddling around with the official httpd:2.4-alpine
image. I want to add some more information and caveats I stumbled upon while working on this.
- The Apache configuration was slightly more difficult since it is a lighter version with no usual vhost data structure, no
a2en*
and noa2dis*
scripts. - There is no generic folder structure in
/etc/apache2
. Everything is in/usr/local/apache2
and you have your globalhttpd.conf
in/usr/local/apache2/conf/
. In this file you have to uncomment the module lines manually to load them as well as further configuration files likehttpd-vhosts.conf
which is stored in/usr/local/apache2/conf/extra/
. - I used the
httpd-vhosts.conf
to setup the basic options for my testing:
<VirtualHost *:80>
DocumentRoot /usr/local/apache2/htdocs
<Directory /usr/local/apache2/htdocs>
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride All
Require all granted
</Directory>
ErrorLog /usr/local/apache2/main-error.log
LogLevel warn
CustomLog /usr/local/apache2/main-access.log combined
</VirtualHost>
- For the FCGI server I had to uncomment the following two lines:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_fcgi_module modules/mod_proxy_fcgi.so
- Everytime to change something in the configuration you have to
./bin/apachectl restart
as usual assuming you are in/usr/local/apache2
. - Since I use
nano
I had to install it manually usingapk --no-cache add nano
. This can be done in an interactive session or globally using aDockerfile
to fork the base image. - I had an error when opening
nano
- in my case I had toexport TERM=xterm
in an interactive shell orENV TERM xterm
in theDockerfile
. - It turned out that
php-fpm
has to have access to the very same files - this is something I didn't actually notice in the proposed solution at first. This means as well that I had the source files mounted at two different paths (/usr/local/apache2/htdocs
in thehttpd
image and/var/www/html
in thephp-fpm
image) and had to forward calls properly. I used the following line in thehttpd.conf
.
ProxyPassMatch "^/(.*\.php)$" "fcgi://fpm:9000/var/www/html/$1"
- The
fpm
name in the FCGI link is the name of my container that is linked tohttpd
using--link fpm
and automatically added to the/etc/hosts
. - So far I managed to achieve want I want by interactively doing all these changes. I am going to add all the changes to my
Dockerfile
using eitherCOPY
commands or applying basicsed
calls. - I know there is the possibility to use unix sockets via the command
SetHandler "proxy:unix:/var/run/php7-fpm.sock|fcgi://fpm/"
but I don't know if that is useful or not.
Christian Ivicevic
Updated on June 22, 2022Comments
-
Christian Ivicevic almost 2 years
I am experimenting with Docker and want to move from a local MAMP stack to Docker. Of course I stumbled upon the official
php:7.0
image but I want to use Apache as well so it seems as ifphp:7.0-apache
is the way to go. However I saw that there is an image calledphp:7.0-alpine
which is much slimmer while there are two versions for Apache as well namelyhttpd:2.4
andhttpd:2.4-alpine
.Is there any suggested combination to use both Apache and PHP (either separated or combined) while still having small image sizes? Furthermore I would like to know where I can review the available modules in the images since I want to use MariaDB and mod_rewrite as well which could possibly have more dependencies which have been omitted to keep the size small.
Information on implementing the desired infrastructure with nginx
I came across this very detailed and awesome tutorial on how to split up nginx and PHP as well as MySQL into different containers but attach PHP to nginx using FCGI. This implies that I can use all the different alpine-based images of the tools and link them using FCGI. Unfortunately I have never heard of or worked with FCGI but I guess some more research will yield information on how to implement this infrastructure using Apache.
-
Christian Ivicevic over 7 yearsIf you're interested to know more about using the official Apache image please refer to my own answer. Yours has helped me out A LOT to get started in the first place :)
-
ltdev about 2 yearsHi, I ve tried to add ProxyPassMatch setting on my configuration, but still didn't manage to make it work properly. See here for ref stackoverflow.com/questions/71079174/…