Skip to main content

Command Palette

Search for a command to run...

Creating an apache-php-composer docker container for development

Published
4 min read

So I'm in need of a repeatable environment setup for developing PHP projects. I've seen package setups like XAMPP and MAMP, but I'd like to be closer to the production environment which uses Docker containers for all services.

Requirements

  • The base VM is Ubuntu 20.04.1 LTS

  • Docker-CE version 20.10.16 installed

Pull the base image

The base container image is the php:8.0-apache image from Docker Hub. As the name and tag imply, the image runs the apache web server and has php 8.0 installed and configured.

~$ docker pull php:8.0-apache 
8.0-apache: Pulling from library/php
a603fa5e3b41: Pull complete 
c428f1a49423: Pull complete 
156740b07ef8: Pull complete 
fb5a4c8af82f: Pull complete 
25f85b498fd5: Pull complete 
9b233e420ac7: Pull complete 
fe42347c4ecf: Pull complete 
9a7bf1523229: Pull complete 
a0b541d575c5: Pull complete 
c0e75b0cc4dc: Pull complete 
a97a86207955: Pull complete 
f88820a52a78: Pull complete 
81ebcb8aedf6: Pull complete 
Digest: sha256:2fd39b3d456959fa399e6dc3db28ccfbb518e6ca5727cd6f2553f338ba8a8847
Status: Downloaded newer image for php:8.0-apache
docker.io/library/php:8.0-apache
~$

Install Composer

Now that we have our base container we need to install Composer for managing PHP dependancies. We need the following Dockerfile for building our new image. The RUN commands come from the Composer download page.

FROM php:8.0-apache

RUN cd /var/tmp && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN cd /var/tmp && php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
RUN cd /var/tmp && php composer-setup.php
RUN cd /var/tmp && php -r "unlink('composer-setup.php');"
RUN cd /var/tmp && mv composer.phar /usr/local/bin/composer

The new image is built with the docker build command. Let's give it the tag 8.0-apache-composer.

~/tmp$ docker build -t php:8.0-apache-composer . 
Sending build context to Docker daemon   2.56kB
Step 1/6 : FROM php:8.0-apache
 ---> b6af81e9f77f
Step 2/6 : RUN cd /var/tmp && php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
 ---> Running in f910ad74f689
Removing intermediate container f910ad74f689
 ---> f210701f81b3
Step 3/6 : RUN cd /var/tmp && php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
 ---> Running in 80e4dec0b876
Installer verified
Removing intermediate container 80e4dec0b876
 ---> f09bf1368b59
Step 4/6 : RUN cd /var/tmp && php composer-setup.php
 ---> Running in c05e8dff581c
All settings correct for using Composer
Downloading...

Composer (version 2.4.4) successfully installed to: /var/tmp/composer.phar
Use it: php composer.phar

Removing intermediate container c05e8dff581c
 ---> 6922990b4d30
Step 5/6 : RUN cd /var/tmp && php -r "unlink('composer-setup.php');"
 ---> Running in 6354ff1806e4
Removing intermediate container 6354ff1806e4
 ---> af37f1ef5ea2
Step 6/6 : RUN cd /var/tmp && mv composer.phar /usr/local/bin/composer
 ---> Running in b15ea6a61156
Removing intermediate container b15ea6a61156
 ---> 6554b5c2ae90
Successfully built 6554b5c2ae90
Successfully tagged php:8.0-apache-composer
~/tmp$

Now we can see we have our new container image with docker images:

~/tmp$ docker images
REPOSITORY   TAG                   IMAGE ID       CREATED          SIZE
php          8.0-apache-composer   6554b5c2ae90   48 seconds ago   461MB
php          8.0-apache            b6af81e9f77f   5 days ago       455MB
~/tmp$

Verify Composer is installed

Let's start a container and run the composer command to verify composer is installed. The --rm flag tells docker to delete the container once we have exited from it.

~/tmp$ docker run --rm -it php:8.0-apache-composer bash 
root@426a49724a79:/var/www/html# composer --version 
Composer version 2.4.4 2022-10-27 14:39:29
root@426a49724a79:/var/www/html# exit
exit
~/tmp$

or more simply:

~/tmp$ docker run --rm php:8.0-apache-composer composer --version 
Composer version 2.4.4 2022-10-27 14:39:29
~/tmp$

Setup the new project

The php container is configured to use /var/www/html as the apache DocumentRoot. To keep the project files persistent we will mount this directory to a project directory on the host. This is also the second project being developed on this host so port 81 will be mapped to the container port 80.

~$ mkdir ~/project2-site-query-app 
~$ docker run -d --name php-site-query -v ~/project2-site-query-app:/var/www/html -p 81:80 php:8.0-apache-composer  
9ce71bb3f5a9bb86de046a9ab1c853b6961e56f59a53cf05090272b36ce00bf9
~$ docker ps
CONTAINER ID   IMAGE                     COMMAND                  CREATED         STATUS         PORTS                               NAMES
9ce71bb3f5a9   php:8.0-apache-composer   "docker-php-entrypoi…"   8 seconds ago   Up 7 seconds   0.0.0.0:81->80/tcp, :::81->80/tcp   php-site-query
643e59316cc0   php:8.0-apache            "docker-php-entrypoi…"   21 hours ago   Up 21 hours   0.0.0.0:80->80/tcp, :::80->80/tcp   php-stock-quotes
~$

Verify the container is serving PHP

Finally, add a simple PHP file to the project directory and get data from it.

~$ cd project2-site-query-app/
rob@xubuntu2004:~/project2-site-query-app$ echo '<?php phpinfo(); ?>' >index.php  
~/project2-site-query-app$
~/project2-site-query-app$ curl http://localhost:81 2>/dev/null  | grep "</td>" | grep 'PHP Version'
<tr><td class="e">PHP Version </td><td class="v">8.0.26 </td></tr>
~/project2-site-query-app$

Or verify with a browser if you'd like.

469 views