Running the Apache HTTP Server with PHP inside Docker
Running the Apache HTTP Server (“httpd”) with PHP inside Docker is easy. So easy that, in case you’re using httpd and PHP, you actually have no reasons not to do it. Here’s a short guide about how to do that.
1 A Vanilla Prototype
To run the Apache HTTP Server with PHP in Docker on your, say,
htdocs/ directory, on port 8082, you can run the following command:
That’s it! If you try this, and it works for you, you’re done!
The command does the following:
- If the Docker image
php:apacheis not present in your machine’s local Docker registry, it will be downloaded from Docker hub.
- It creates a new container based on the image
- It maps port
80from the container to port
8082on your host machine.
- It mounts the directory
htdocs/from your host machine to
/var/www/htmlin the container.
If you’re lucky, you can now access http://localhost:8082/ and see your web pages hosted from an Apache HTTP Server with PHP in a Docker container.
1.1 Things that didn’t work for me
For me, this didn’t work, for the following reasons:
- I override a lot of configuration in
- I need a modified PHP configuration.
- I use Apache HTTP Server modules which are not enabled by default.
So I created my own
Dockerfile to cope with the changes that I need.
The standard image does not serve all purposes. Things you might want to change are:
- Enable additional Apache HTTP Server modules.
- Allow overriding specific directives in
- Add a PHP configuration.
FROM php:apacheselects the latest version of PHP with the latest version of the Apache HTTP Server. I do not use this image in production, otherwise I would pin down the version.
SHELLline changes the shell command for the subsequent
RUNcommands to be
/bin/bash -cinstead of
/bin/sh -c. I do this to get brace expansion.
RUN lncommand enables the Apache HTTP Server modules. I could’ve used
RUN a2enmodinstead, but since I know what I’m doing,
lnis simpler and faster for me than
a2enmod. There’s a caveat: If the way how Debian handles Apache HTTP Server modules changes, my
Dockerfilemight fail. If I would use
Dockerfilewould still work. Refer to [man:a2enmod] for more information about
RUN sedcommand replaces
AllowOverride Allfor the directory
/var/www/. I have a lot of configuration in my
.htaccessfile which needs this.
COPYcommand copies my
php.inifile to the desired location in the docker image. My PHP configuration has a lot of modifications.
For more information what these
Dockerfile commands mean and how they work, refer to [Dockerfile].
To use and run this image, you need a few
docker build -t my/apache-php .
- This command builds your Apache PHP Docker image from the
Dockerfileand stores it in your local registry under the name
docker run --name apache -d 8082:80 --mount type=bind,source="$(pwd)"/htdocs,target=/var/www/html my/apache-php
- This command runs your docker image
my/apache-phpin a docker container. The Docker container is named
apachefor further reference. Port
80inside the container, which is where the Apache HTTP Server is running, is mapped to port
8082on the host. So you can access this with http://localhost:8082/. The option
--mount type=bind,source="$(pwd)"/htdocs,target=/var/www/htmlcreates a bind mount of the
htdocsdirectory of the host to
/var/www/htmlin the container. If your web pages are in a different directory, adjust the
docker stop apache
- Stops your docker container.
docker rm apache
- Removes your docker container.
docker container logs apache
- Prints the logs of the Apache HTTP Server inside the container.
docker exec -it apache bash
- Logs into the Apache PHP container using a bash shell.
docker ps -f name=apache
- Shows the status of the Apache PHP container.
Makefile serves as a more convenient way to wrap the docker commands needed to deal with the container. The things you want to do:
- (Create and) start the container.
- Stop (and remove) the container.
- Print the logs of the container.
- Login to the container.
Makefile offers the following commands:
- Builds and starts the container. Docker is incremental. In case the
Dockerfilewas not changed, the container image will actually not be rebuilt. The Apache HTTP Server will be bound to port
8082. If you want a different port, for example, port
9000, you can run it like this:
make start PORT=9000.
- Stops and removes the container. Because the container does not store any data, it can safely be removed.
- Prints the logs of the container, in case you want to inspect the logs.
- Login to the container with a root bash, in case you want to inspect something inside the container.