Deploy PHP FPM, Apache httpd, and MySQL with Docker Compose
Posted November 1, 2023
Dive in and learn how to use Docker with Apache httpd and PHP FPM containers to run PHP on Docker Compose alongside MySQL. FPM (FastCGI Process Manager) easily creates pools, runs PHP processes, handles incoming requests, and dispatches them to these pools. It gives PHP-based web applications improved performance and scalability.
Now, you need web servers like Apache httpd server to serve PHP-driven content on the web. Docker and Docker Compose are great to do so.
In this guide, you will package your PHP app and run it with FPM. You will then use Docker to spin up the Apache httpd server and MySQL database using Docker Compose. You will learn:
- The right way to run any PHP version (5.3, 5.4, 5.6, 7.0, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2) with FPM httpd and Docker Compose.
- How to package your PHP FPM app using Dockerfile and bundle a single PHP Docker image.
- Use httpd as the httpd HTTP server to expose a PHP FPM app running on Docker and serve PHP-driven content on the web.
- How to add MySQL container and run PHP FPM scripts with SQL queries. You will also add PhpMyAdmin to access your MySQL databases.
Now, delve into this comprehensive guide and learn how to get Docker Apache PHP FPM running with Docker Compose and MySQL.
- How to Deploy PHP FPM, NGINX, and MySQL with Docker Compose
- Running PHP, Apache, and PostgreSQL with Docker Compose
- Easy Apache PHP Guide with Docker Compose, MySQL and PhpMyAdmin
Prerequisites
Creating a PHP FPM app container with Docker Compose httpd Apache and MySQL is a step-by-step process. Ensure you have:
- Docker installed on your computer.
- Basic knowledge of working with PHP and MySQL will be great.
- Ensure you have the following application structure ready:
apache-php-fpm-app/
βββ Dockerfile
βββ docker-compose.yml
βββ apache/
β β βββ apache.vhost.conf
β β βββ Dockerfile
βββ app/
βββ index.php
This will represent the following:
Dockerfile
contains the configuration needed to spin up PHP with FPM and install required PHP extensions.docker-compose.yml
creates all the services needed to spin up PHP FPM, Apache httpd, and MySQL containers.apache/apache.vhost.conf
will host all Apache configurations you need so Apache httpd can server PHP on the web.apache/Dockerfile
will have all the Docker configurations you need to spin up the Apache httpd server.app/index.php
hosts your PHP app source code.
Once you confirm you have this ready, let’s get the Docker httpd PHP FPM container up and running.
Creating PHP FPM Image using Dockerfile
Dockerfile writes all the instructions you need to build your custom image. This way, you will be able to add adding configurations your container needs. An example is adding the mysqli
extension so PHP can communicate with the MySQL database. This is what the Dockerfile file does. Add the following code for PHP FPM Docker setup:
# Add PHP-FPM base image
FROM php:8.2-fpm
# Install your extensions
# To connect to MySQL add mysqli
RUN docker-php-ext-install mysqli pdo pdo_mysq
Here:
- Docker will pull
php:8.2-fpm
from Docker Hub and create your image. - Note that
php:php:8.2-fpm-fpm
specifies the PHP version you want to use. This means Docker will use PHP version 8.2. You can change this version based on what PHP you want to run. Just replace 8.2 with other versions such as 5.3, 5.4, 5.6, 7.0, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2, etc. - If you want to install any PHP extension with Docker, use the command
docker-php-ext-install
withRUN
.
Creating Apache httpd Image using Dockerfile
Like you create your PHP FPM Dockerfile, you need one to run Apache httpd on Docker.
First, you need the right configuration to run PHP FPM on Apache. This will help you create an Apache Virtual Host configuration to handle PHP files via FPM and serve them to the web.
Go to the apache/apache.vhost.conf
file and add the following VirtualHost
configuration:
# Set the ServerName to localhost
ServerName localhost
# Configure a VirtualHost to handle requests on port 80
<VirtualHost *:80>
# Proxy PHP requests to port 9000 PHP-FPM container
ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://php-fpm:9000/var/www/html/$1
# Set the DocumentRoot for the virtual host
DocumentRoot /var/www/html/
# Directory configuration for the DocumentRoot
<Directory /var/www/html/>
DirectoryIndex index.php
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
# Define the CustomLog and ErrorLog destinations
CustomLog /proc/self/fd/1 common
ErrorLog /proc/self/fd/2
</VirtualHost>
- Your application is running on localhost.
ServerName
should belocalhost
and handle incoming requests on port 80. - Apache will forward requests for PHP files in your container. Note that the container is set as
php-fpm
. This tells you PHP FPM container must be named ‘php-fpm
’. Remember that you will use the name indocker-compose.yml
. /var/www/html/
will be your application’s default directory on Apache. This way, the virtual host will for files to serve to start from/var/www/html/
.- on the
Directory
,DirectoryIndex
is set toindex.php
.index.php
hosts your PHP code and the application entry point. If you used a different file, update your config file correctly. - If you want to debug your app, create
CustomLog
andErrorLog
destinations to manage application logs and those of Docker.
Head over to your apache/Dockerfile
and create your Apache HTTP server using httpd as follows:
# httpd base image
FROM httpd:2.4
# Copy the Apache virtual host configuration file to the container
COPY ./apache/apache.vhost.conf /usr/local/apache2/conf/extra/apache.vhost.conf
# Enable Apache modules to ensure proper functionality
RUN sed -i \
# Uncomment the configuration for mod_deflate to enable compression
-e '/#LoadModule deflate_module/s/^#//g' \
# Uncomment the configuration for mod_proxy to enable proxying capabilities
-e '/#LoadModule proxy_module/s/^#//g' \
# Uncomment the configuration for mod_proxy_fcgi to enable FastCGI proxy module
-e '/#LoadModule proxy_fcgi_module/s/^#//g' \
/usr/local/apache2/conf/httpd.conf
# Include the virtual host configuration file in the main Apache configuration
RUN echo "Include /usr/local/apache2/conf/extra/apache.vhost.conf" >> /usr/local/apache2/conf/httpd.conf
Creating PHP Apache Container with Docker Compose and Serve PHP App
With the Dockerfile ready, Docker will now use Docker Compose to create PHP-FPM and Apache httpd services to spin your app.
You will use the docker-compose.yml
file to:
- Build the PHP and Apache httpd image using the Dockerfile.
- Expose your PHP app container to access it on the web.
First, go to app/index.php
and create a PHP test script. Make sure it is static and not database-related. For example:
<?php
echo "Hello, Docker! PHP is Now Up and Running PHP version: " . phpversion();
?>
<?php
phpinfo();
?>
Now you can create PHP-FPM and Apache httpd services in your docker-compose.yml
file as follows:
version: '3.9'
services:
php-fpm:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./app:/var/www/html
apache-httpd:
build:
context: .
dockerfile: ./apache/Dockerfile
volumes:
- ./app:/var/www/html
ports:
- "8080:80"
depends_on:
- php-fpm
In your root directory, run the following command to start the container:
docker-compose up --build -d
Confirm if these services were created in your Docker Demon:
You can now access your app on http://localhost:8080/
as follows:
phpinfo()
will log the information of the app, its server, and so on:
How to Add MySQL Docker Container to PHP- FPM using Docker Compose
You can now run simple static PHP code. But you need one running on Docker to create a dynamic that uses a database.
Update the docker-compose.yml
file and MySQL as follows:
version: '3.9'
services:
php-fpm:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./app:/var/www/html
depends_on:
- mysql-db
apache-httpd:
build:
context: .
dockerfile: ./apache/Dockerfile
volumes:
- ./app:/var/www/html
ports:
- "8080:80"
depends_on:
- php-fpm
- mysql-db
mysql-db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: test_database
MYSQL_USER: db_user
MYSQL_PASSWORD: password
ports:
- "3306:3306"
In your app/index.php
file, add the following script for database Connection testing:
<?php
$host = 'mysql-db';
$user = 'db_user';
$pass = 'password';
$db = 'test_database';
$conn = new mysqli($host, $user, $pass, $db);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
echo "Connected to MySQL successfully";
$conn->close();
?>
- The Database connection variables must match that of your Docker MySQL container. Note that the host is not
localhost
. Your host will change to MySQL container service,mysql-db
. - Docker will use the
mysqli
you previously installed in your Dockerfile (docker-php-ext-install mysqli) to create a connection to MySQL. - You will get the respective message if the database connection is working.
Run the docker-compose command to rebuild your containers:
docker-compose up --build -d
And PHP can now communicate with MySQL within Docker successfully.
This shows how to run PHP with MySQL, and you update your scripts to perfect different database operations.
Using phpMyAdmin to MySQL PHP-FPM Apache Httpd Server
Even though your database works, you donβt have a GUI to access it. Here is how you will use phpMyAdmin to access it:
- Update the
docker-compose.yml
file with a phpMyAdmin service:
version: '3.9'
services:
php-fpm:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./app:/var/www/html
depends_on:
- mysql-db
apache-httpd:
build:
context: .
dockerfile: ./apache/Dockerfile
volumes:
- ./app:/var/www/html
ports:
- "8080:80"
depends_on:
- php-fpm
- mysql-db
mysql-db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: test_database
MYSQL_USER: db_user
MYSQL_PASSWORD: password
ports:
- "3306:3306"
phpmyadmin:
image: phpmyadmin/phpmyadmin
links:
- mysql-db
ports:
- "8081:80"
environment:
PMA_HOST: mysql-db
MYSQL_ROOT_PASSWORD: password
- Run the docker-compose command to rebuild your containers:
docker-compose up --build -d
- Open
http://localhost:8081/
to access phpMyAdmin:
- Use
root
as the user andpassword
as the password as set onMYSQL_ROOT_PASSWORD: password
and login to phpMyAdmin:
Conclusion
You have learned how to use Docker Compose and create an Apache httpd server to run PHP-FPM apps with MySQL.
I hope this guide was helpful!