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.

Christian Hujer, Software Crafter and CEO / CTO of Nelkinda Software Craft Private Limited
First Published:
by NNelkinda Software Craft Private Limited
Last Modified:
by Christian Hujer
Approximate reading time:
Figure -1: Docker + Apache + PHP

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:

docker run -d -p 8082:80 --mount type=bind,source="$(pwd)/htdocs",target=/var/www/html php:apache
Listing 1-1: Command to run the Apache HTTP Server with PHP in a Docker container

That's it! If you try this, and it works for you, you're done!

The command does the following:

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:

So I created my own Dockerfile to cope with the changes that I need.

2 The Dockerfile

The standard image does not serve all purposes. Things you might want to change are:

FROM php:apache
SHELL ["/bin/bash", "-c"]
RUN ln -s ../mods-available/{expires,headers,rewrite}.load /etc/apache2/mods-enabled/
RUN sed -e '/<Directory \/var\/www\/>/,/<\/Directory>/s/AllowOverride None/AllowOverride All/' -i /etc/apache2/apache2.conf
COPY php.ini /usr/local/etc/php/
Listing 2-1: Dockerfile for building a slightly modified Apache PHP image.

2.1 Explanation

For more information what these Dockerfile commands mean and how they work, refer to [Dockerfile].

3 The docker commands

To use and run this image, you need a few docker commands.

docker build -t my/apache-php .
This command builds your Apache PHP Docker image from the Dockerfile and stores it in your local registry under the name my/apache-php.
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-php in a docker container. The Docker container is named apache for further reference. Port 80 inside the container, which is where the Apache HTTP Server is running, is mapped to port 8082 on the host. So you can access this with http://localhost:8082/. The option --mount type=bind,source="$(pwd)"/htdocs,target=/var/www/html creates a bind mount of the htdocs directory of the host to /var/www/html in the container. If your web pages are in a different directory, adjust the source path accordingly.
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.

4 The Makefile

The Makefile serves as a more convenient way to wrap the docker commands needed to deal with the container. The things you want to do:

So, the Makefile offers the following commands:

make start
Builds and starts the container. Docker is incremental. In case the Dockerfile was 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.
make stop
Stops and removes the container. Because the container does not store any data, it can safely be removed.
make logs
Prints the logs of the container, in case you want to inspect the logs.
make login
Login to the container with a root bash, in case you want to inspect something inside the container.

.PHONY: start
	docker build -t nelkinda/apache-php .
	docker run --name apache -d -p $(PORT):80 --mount type=bind,source="$(CURDIR)"/../htdocs,target=/var/www/html nelkinda/apache-php

.PHONY: stop
	docker stop apache
	docker rm apache

.PHONY: logs
	docker container logs apache

.PHONY: login
	docker exec -it apache bash

.PHONY: status
	docker ps -f name=apache
Listing 4-1: Makefile for wrapping control of the Apache PHP docker container.