Skip to content

Database and PHP Website Dockerized

In this lecture we're doing what docker-compose is actually made for: orchestrate!

We are taking a Database and a simple PHP script and see how we can orchestrate these two services together.

View the Full Course Now

Build your environment with a simple php apache and database using docker-compose

Before we even start, there are a couple of things we haven't tried yet:

  1. Detach from the logs upon start
  2. Using multiple containers in one larger service

Let's start by using this docker-compose.yml file:

version: '3'

services:
  phpapp:
    build:
      context: ./
      dockerfile: Dockerfile
    image: phpapp:123
    ports:
      - "8080:80"
    volumes:
      - "./:/var/www/html"
    container_name: myphpapp-app

  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: my!!!root!!!pw
    container_name: myphpapp-db

It will create two services: * one called "phpapp" with a container called "myphpapp-app" and an image called "phpapp" with tag "123" and * another service called "db" from the official mysql:5.7 image. * This container restarts always, which means: it crashes? Then it restarts automatically! Until you stop it manually.

Upon start we set a password for the root user: "my!!!root!!!pw", just to demonstrate that special characters work just fine in yaml.

The container name is "myphpapp-db". Container names and image names are arbitrary chosen, there is no official pattern to follow.

The Dockerfile is this one:

FROM php:7.2-apache

RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli

And our index.php is this one.

<?php
header("content-type: text");
$host = "db"; //The hostname "db" from our docker-compose.yml file!!!
$username = "root"; //We use the root user
$pw = "my!!!root!!!pw"; //that's the password we set as environment variable

$conn = new mysqli($host,$username,$pw);

if ($conn->connect_errno > 0) {
    echo $db->connect_error;
} else {
    echo "DB Connection successful\n\n";
}

If you have never worked with php before, then this might look scary. But it essentially connects to the host "db". The host "db" is the service name, which we defined in the docker-compose.yml file.

Hostnames

In Docker the hostnames of other services are made available as their service name.

In this case the service "db" also gets the host "db" and we can simply connect to host "db" which resolves to the IP address of the service that runs the mysql container.

Let's run

docker-compose up -d
  • Creates the image "phpapp:123" if it isn't created yet
  • Starts the container myphpapp-app
  • Downloads the image "mysql" and starts it

Now go to http://localhost:8080 and see if you can see a "DB Connection successful".

Adding a Query

Let's add a query to select the existing databases in the MySQL server. Extend the index.php so that it looks like this:

<?php
header("content-type: text");
$host = "db"; //The hostname "db" from our docker-compose.yml file
$username = "root"; //We use the root user
$pw = "my!!!root!!!pw"; //that's the password we set as environment variable

$conn = new mysqli($host,$username,$pw);

if ($conn->connect_errno > 0) {
    echo $db->connect_error;
} else {
    echo "DB Connection successful\n\n";

    //we read out the content
    $result=mysqli_query($conn,"SHOW DATABASES;");
    while( $row = mysqli_fetch_row( $result ) ){
        echo $row[0]."\n";
    }
}

Reload the page at http://localhost:8080 and you hopefully should also see the "information_schema", "mysql" and "performance_schema" databases.

Getting the Logs

As we started docker-compose with the -d flag, it started in "detached" mode. That means, it starts the containers in the background and you don't see the logs.

You can get the logs in two ways:

docker logs myphpapp-app -f 
* This attaches to the stdout logs of the myphpapp-app container * Every time you reload the website you should see a new request

OR

docker-compose logs -f phpapp

which runs through the existing logs of the service phpapp and shows you all new ones as well.

Tail Logs

If you have a service that outputs a lot of logs and/or you have it running long time, just tail the logs:

docker-compose logs -f --tail=100

That shows you the last 100 lines of all services and live outputs new logs as they arrive

Ctrl-c to get out of the logs

docker-compose ps
  • Lists the Services running
docker-compose down
  • Shuts down the two services
  • And removes them