Easy Apache PHP Guide with Docker Compose, MySQL and PhpMyAdmin

Posted November 20, 2023
Easy Docker Apache PHP Setup with Docker Compose, MySQL and PhpMyAdmin

Have you thought of running PHP on Docker? This guide teaches everything you need from start to finish and gets PHP up and running within Docker using Docker Compose, Apache, and MySQL.

PHP requires you to have an Apache server to run its code. You will need a MySQL database installed on your computer. With a Docker container, you can use Docker Compose and spin up the Apache server and MySQL database to run your PHP apps.

You will learn how to set up a PHP Docker development environment based on the following:

  • Spin up a PHP Apache server Docker Compose container that will run any PHP version of your choice, i.e. (PHP 5.3, 5.4, 5.6, 7.0, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2) just to name a few.
  • You will create a PHP Dockerfile example to define all the PHP configurations you might need and bundle them in a single Docker image.
  • Create MySQL Docker Compose container that will communicate with the PHP Apache server
  • Create a simple PHP app that communicates with the Dockerfile Apache and MySQL to run SQL queries using PHP scripts.
  • While on the same, you will see how to use the docker php ext install mysql command to install the MySQL extension for PHP within Docker. This way, you’ll have your PHP MySQL database connection within Docker.
  • Use Docker Compose to create a PhpMyAdmin container and access your PHP-related MySQL database

Let’s Dive into this comprehensive guide and learn the easy Docker Apache PHP setup with Docker Compose and MySQL.

For related setups, check the following:

Prerequisites

Setting up a Docker Compose Apache PHP MySQL container 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.

Before diving in, the following will be your application structure:

php-docker/
│ ├── Dockerfile
│ └── docker-compose.yml
└── www/
    └── index.php

Let’s break it down:

This structure will contain all the Docker Apache PHP and MySQL settings you need as follows:

  • Dockerfile contains all the instructions to package a PHP image.
  • docker-compose.yml defines your Docker Compose services for your app. These services will be phpMyAdmin, MySQL, PHP, and Apache.
  • www/index.php hosts your PHP app source code.

Spinng Up PHP Apache Server using PHP Dockerfile Example

Dockerfile defines all the configurations you need to package your application together. This involves the command you need in your application and the version of PHP Apache you want to run:

In your working directory, create a Dockerfile and define the Docker image for your PHP and Apache environment as follows:

  • Add the base image of the PHP version you want to use. This is key to ensuring you have consistency in the PHP version. Here, I used php:8.2 as follows:
# Use an official PHP runtime
FROM php:8.2-apache

At the same time, note that you are using a php:8.2-apache image. This will package PHP and Apache Server together, so you don’t need to create Apache configurations separately. You can choose any version that works for you (PHP 5.3, 5.4, 5.6, 7.0, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2), etc.

  • Proceed and enable PHP Apache modules using RUN. At the same time, install any extensions you need, including docker-php-ext-install mysqli, for MySQL connections as follows:
# Enable Apache modules
RUN a2enmod rewrite
# Install any extensions you need
RUN docker-php-ext-install mysqli pdo pdo_mysql
  • Within Docker, you need a PHP working directory. Because you are using Apache, make sure you set the working directory to the default Apache server path as follows:
# Set the working directory to /var/www/html
WORKDIR /var/www/html

Docker will need to execute your PHP code. I can’t do that out of the box. Use Docker COPY command and copy your source files so Docker can be able to use them:

# Copy the source code in /www into the container at /var/www/html
COPY ../www .

Your Dockerfile should be ready and complete as follows:

# Use an official PHP runtime
FROM php:8.2-apache
# Enable Apache modules
RUN a2enmod rewrite
# Install any extensions you need
RUN docker-php-ext-install mysqli pdo pdo_mysql
# Set the working directory to /var/www/html
WORKDIR /var/www/html
# Copy the source code in /www into the container at /var/www/html
COPY ../www .

Creating PHP Apache Container with Docker Compose and Serve PHP App

You have all you need to create to package your PHP app. Now, you need to use the docker-compose.yml file and create a PHP Apache Docker Compose service for your app. This way, Docker will:

  • Builds the PHP and Apache image using the Dockerfile.
  • Expose your PHP app. For example, use maps port 8080 on the host to port 80 on the container and expose your app

First, head over to your www/index.php and create a PHP test script as follows:

<?php
echo "Testing a PHP Apache Docker Container";
?>

In your docker-compose.yml, create your PHP Apache service as follows:

version: '3.9'
services:
  webserver:
    container_name: PHP-webServer
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./www:/var/www/html
    ports:
      - 8000:80

In this case:

  • Docker will create a new container named PHP-webServer.
  • Docker Compose will create your container based on Dockerfile.
  • Your PHP app will be exposed on port 8000.

Now run the following command to test if your PHP app is working as expected:

docker-compose up -d

Easy Docker Apache PHP Setup with Docker Compose, MySQL and PhpMyAdmin

These changes should be reflected in Docker Demon as such. You should have a PHP image ready and a container running as follows:

Easy Docker Apache PHP Setup with Docker Compose, MySQL and PhpMyAdmin

To verify if the PHP Apache container is running, head over to http://localhost:8000/. You should be served with your simple PHP app based on the index.php file as follows:

Easy Docker Apache PHP Setup with Docker Compose, MySQL and PhpMyAdmin

How to Add MySQL Docker Container to PHP Apache using Docker Compose

You just created the most basic PHP Apache Docker container. Let’s now dive deeper and add MySQL to our app.

To do so, you need to spin up a MySQL docker container using Docker Compose. Navigate to your docker-compose.yml and make the following changes:

version: "3.9"
services:
  webserver:
    container_name: PHP-webserver
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./www:/var/www/html
    ports:
      - 8000:80
    depends_on:
      - 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"

You will note that:

  • depends_on was added to your previous PHP-webserver container. This way, PHP Apache will know to depend on MySQL database (mysql-db) service to create your connections.
  • MySQL environment defines your typical database password, users, and databases. In this example, you can update them according to your liking.
  • Once the Docker Container fires up a MySQL container, a test_database database will be created.

Now, you will use these database environment variables like on a local computer. But because we are on Docker, now you will update the www/index.php file and include MySQL as follows:

<?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();
?>

Here:

  • 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 check your containers:

docker-compose up -d

Easy Docker Apache PHP Setup with Docker Compose, MySQL and PhpMyAdmin

Open http://localhost:8000/. If you set up everything correctly, PHP Apache should be able to establish a connection to MySQL database as follows:

Easy Docker Apache PHP Setup with Docker Compose, MySQL and PhpMyAdmin

Adding phpMyAdmin to MySQL PHP Apache Server

Your database is running. However, up to now, you don’t a GUI access and check what’s happening with your database. In that regard, you will use phpMyAdmin to log in to MySQL and visually access your database. Go ahead and update your docker-compose.yml file as follows:

version: "3.9"
services:
  webserver:
    container_name: PHP-webserver
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./www:/var/www/html
    ports:
      - 8000:80
    depends_on:
      - 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

Rerun Docker Compose to add phpMyAdmin service:

docker-compose up -d

You have three services running:

Easy Docker Apache PHP Setup with Docker Compose, MySQL and PhpMyAdmin

phpMyAdmin will be served on port 8081. Open http://localhost:8081/ on your browser:

Easy Docker Apache PHP Setup with Docker Compose, MySQL and PhpMyAdmin

To access MySQL, use root as username and the value of MYSQL_ROOT_PASSWORD as password. In this example, it is password:

Easy Docker Apache PHP Setup with Docker Compose, MySQL and PhpMyAdmin

This Is how your MySQL database looks like. You can confirm by making sure it was test_database.

Creating a PHP CRUD API and Running it with MySQL and PHP Apache Docker Container

What if you now want to create a CRUD API using PHP and run it within Docker alongside PHP, Apache, and MySQL? That’s very possible. Your PHP Docker environment is working, and you can run any PHP code and still use your MySQL database.

Assume you want to run the following POST and GET requests with PHP in your index.php file:

<?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";

// Handle POST request
if ($_SERVER["REQUEST_METHOD"] == "POST") {
    if (isset($_POST['submit'])) {
        $name = $_POST['name'];
        $email = $_POST['email'];

        // Insert data into the database
        $sql = "INSERT INTO users (name, email) VALUES ('$name', '$email')";
        if ($conn->query($sql) === TRUE) {
            echo "<br>Data inserted successfully";
        } else {
            echo "<br>Error inserting data: " . $conn->error;
        }
    }
}

// Handle GET request
if ($_SERVER["REQUEST_METHOD"] == "GET") {
    if (isset($_GET['action']) && $_GET['action'] == 'fetch') {
        // Retrieve data from the database
        $result = $conn->query("SELECT * FROM users");
        if ($result->num_rows > 0) {
            echo "<br><br>Users:<br>";
            while ($row = $result->fetch_assoc()) {
                echo "Name: " . $row["name"] . " - Email: " . $row["email"] . "<br>";
            }
        } else {
            echo "<br>No users in the database";
        }
    }
}

$conn->close();
?>

<!DOCTYPE html>
<html>
<head>
    <title>PHP Form</title>
</head>
<body>
    <h2>Submit Form</h2>
    <form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
        Name: <input type="text" name="name"><br>
        Email: <input type="text" name="email"><br>
        <input type="submit" name="submit" value="Submit">
    </form>

    <h2>Retrieve Data</h2>
    <a href="?action=fetch">Fetch Data</a>
</body>
</html>

What you need to do is create your database table on phpMyAdmin using the following script:

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    email VARCHAR(255) NOT NULL
);

The run Docker Compose to restart your containers:

docker-compose up -d

Open your server http://localhost:8000/, and it should be ready:

Easy Docker Apache PHP Setup with Docker Compose, MySQL and PhpMyAdmin

Try adding new data and fetch them as such:

Easy Docker Apache PHP Setup with Docker Compose, MySQL and PhpMyAdmin

At the same time, the data you add should be added to MySQL, and you can verify that on phpMyAdmin:

Easy Docker Apache PHP Setup with Docker Compose, MySQL and PhpMyAdmin

Conclusion

You now have Pro Docker Apache PHP Setup with Docker Compose and MySQL. You can now spin up a PHP Apache server Docker Compose container to run any PHP version you choose, i.e. (PHP 5.3, 5.4, 5.6, 7.0, 7.2, 7.3, 7.4, 8.0, 8.1, 8.2). You now have a working CRUD API on docker while using MySQL to run SQL queries using PHP scripts with docker php ext install MySQL command to create the connections.

Easy Apache PHP Guide with Docker Compose, MySQL and PhpMyAdmin

Written By:

Joseph Chege