Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Containerizing Apache, MySQL and PHP With Docker

I've been searching the web and reading manuals and I just can't seem to get my head around what is wrong with my Docker setup.

The Goal

To container-ize Apache, PHP and MySQL allowing them to be customized on a per-project basis. The only dependency to deploy the stack should be docker. All other dependencies / actions should be able to be able to be built / run via Dockerfile.

The Proof of Concept

From my Apache + MySQL + PHP stack via docker-compose.yml file - I'd like to target an index.php page to successfully render Hello Docker! along with a list of all available databases.

The Problem

When I visit docker.dev/index.php in my browser, rather than the PHP code running, I can only view the PHP source code. This is what I see:

<?php

/**
 * This file:
 *     Has not been tested
 *     Does not use prepared statements
 *     Is for Proof of Concept only!
 */

$host = '127.0.0.1';
$user = 'root';
$pass = 'docker';

$conn = new mysqli($host, $user, $pass);

$sql = 'show databases';
$results = $conn->query($sql);

?>

<h1>Hello Docker!</h1>

<ul>
    <?php while ($row = $results->fetch_assoc()) : ?>
        <li><?= $row['Database'] ?></li>
    <?php endwhile ?>
</ul>

My understanding (which may be mistaken) is that Apache is correctly handling the virtual host, but doesn't know to load the PHP file through an Apache PHP Module.

I have setup Apache to depends_on PHP and I have linked them through a network (along with MySQL) but obviously I'm missing something or else everything would be working just as I want it to).

I have created an repo on github that should allow you to test my setup with a few simple commands:

git clone https://github.com/dambrogia/docker-testing.git
cd docker-testing
docker-compose up -d

You will also have to edit add docker.dev to 127.0.0.1 in your hosts file on your host machine!

How can I render the PHP rather than read the source of it when I visit docker.dev/index.php?

I do not want to use a PHP and Apache combined image if at all possible. I would like to have three separate containers - PHP, Apache, MySQL.

like image 697
domdambrogia Avatar asked Oct 25 '25 09:10

domdambrogia


1 Answers

If you're working with PHP, and you wish to have a single process per container, then I do recommend using Nginx and using PHP-FPM, as it's significantly easier to configure than Apache for this type of setup (at least that's what I've found).

You need to ensure you have a common shared volume to both the Nginx and PHP containers. In that volume you would have your index.php. Here is a crude example docker-compose.yml:

services:
  php7:
    image: "php:7.1.10-fpm"
    container_name: "prefix-php"
    volumes:
      - "./your/local/dir:/var/www/html"
  nginx:
    image: "nginx:1.13.6"
    container_name: "prefix-nginx"
    ports:
      - "80:80"
      - "443:443"
    links:
      - "php7"
    volumes:
      - "./your/local/dir:/var/www/html"

You would then run this following command in the directory where the docker-compose.yml file is:

$ docker-compose -p prefix

The reason for "prefix" is that you create a project grouping for your containers so as not to clash with other container names.

Naturally you then need an nginx site configuration that points to /var/www/html. You will have little to no configuration requirements for the php-fpm container.

A side note regarding the nginx configuration. The above docker-compose.yml is incomplete without the referencing of the php container within the nginx configuration. This would look like so (roughly speaking):

server {
    listen 80 default_server;

    # ...more config, like root, index, server_name, etc

    location ~* \.php$ {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass prefix-php:9000; # Note the container name here.
        fastcgi_index index.php;
        fastcgi_hide_header X-Powered-By;
        fastcgi_read_timeout 300s;

        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    # ...more rules
}

You'll notice I named the container "php7", you could actually add another "php5" container to this docker-compose.yml and then that allows you to define nginx sites that use different versions of PHP all running on the same docker-compose setup.

I appreciate that this doesn't directly answer your question as it doesn't solve it using apache, but it's an alternative to consider.

Hopefully this at least gives you ideas to help solve your setup.

like image 195
Dave Goodchild Avatar answered Oct 27 '25 00:10

Dave Goodchild



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!