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.
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:
- Detach from the logs upon start
- 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
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