Using Docker: how to start with MySQL and a simpel website


I’m writing this post for my son who is a first year University IT student. In his lectures he often uses MySQL databases in combination with simple (PHP) websites. He likes to use Docker but doesn’t know where to start. So, here we go…

To start using Docker you have to install it on your pc/Mac (obviously). I want go into detail about the installation procedure. Just follow the documentation on After the installation is finished you are ready to start using containers.

Database container

The first command to execute is $ docker images . This command will show you your pulled (downloaded) images. Docker is based on images and containers.  Containers are instances of images, so with one image (eg. MariaDB) it is possible to create multiple containers running MariaDB. Each container is an independent instance of the MariaDB image running it’s own databases etc. After you installed docker you can download (pull) your first image:

$ docker pull hello-world

Executing $ docker images  now will show your pulled image. To create a container (so do something with the image) you need to execute the $ docker run  command:

$ docker run hello-world

When everything runs smooth, the container will give you a result and stop running.

One of the important things to remember is that a docker container stops running when there is no active process. Executing $ docker ps  will result in an empty list: the container has disappeared. Although not running, it still is on your system. Running $ docker ps -a  will show you all the containers on your system, including the stopped containers.

To keep the container running you need to give it something to do. This can be a running application like a webserver or a shell process by which you can access the container. You can try this by running the following command:

$ docker run -it ubuntu bash

This will pull the ubuntu image from the docker hub, run it in interactive mode and allocate a pseudo-TTY (-it option) and run the bash command for you to create a shell. One important remark: to transfer an image to your docker installation you can use the docker pull  command but docker run  will do the same if the image is not present. If you look around in the bash-shell you will see that you are in an ubuntu linux operating system. The docker run  command has a lot of options. To show all the options just type –help after the docker command you need to know more of.

Now, let’s move into the direction of some real applications. We want to create a website with a database server. To make this work we will create two containers: a webserver container and a database container. We will start with the database container and connect the webserver container to this newly created database later.

For the database we use MariaDB, the community-developed fork of MySQL.

$ docker run --name mymariadb -e MYSQL_ROOT_PASSWORD=mypass -d mariadb

This will do the following:

  • the MariaDB image is pulled from docker hub (the first time you run this only)
  • The –name option sets the name of the container
  • The -e option sets an environment variable, in this case the root password op the MySQL database.
  • the -d option runs the container in daemon mode (so not interactive)

The result is a running container with a MySQL database. To investigate the container it is possible to open a shell by running the docker exec  command:

$ docker exec -it mymariadb bash

Check the database instance by running mysql client and query for the installed databases. You output will be simular to the output below.

So, this way we have created an instance (container) of the MariaDB image. If you need another MariaDB database server you just repeat the docker run  command with another name and you have second server running.

Webserver container

Now, let’s create the webserver. There are many different webserver images available for docker. For this example I will use the standard php with apache image. Running a standard webserver with this image is easy:

$ docker run --name my-apache-php-server php:7.2-apache

Directly after running this command you will notice two “problems”:

  • how can we reach the container with a browser?
  • how to deal with web content? Where do we place this?

Of course, docker has thought about this. The connectivity of a container is dependent on the (virtual) network it is running in and the ports that have been shared by creation. In this beginner tutorial I will not discuss the network possibilities. As long as both containers have been create without network options they will be running in a default network and this will be sufficient now.

To reach the web content with a browser we need port 80 and/or 443 (ssl) to be available. This is possible by adding the -p option to the docker run command. For this example follow these steps:

  • Stop the running container with:

$ docker stop  my-apache-php-server

  • Remove the container with:

$ docker rm my-apache-php-server

Create the new container with the command:

$ docker run -name my-apache-php-server -p 80:80 php:7.2-apache

The syntax of the -p option is: -p <hostport>:<containerport>. In the docker run command above port 80 of the host (your pc/Mac) is connected with the virtual docker port 80 of your newly created container. The result is that you can now reach the container with a browser on http://localhost. It’s also possible to use another port on your host. In that case you can use eg. 8080 by changing the option to -p 8080:80. Port 8080 of the host is connected to port 80 of the container.

After connecting the ports this will still be a webserver without content. To copy content to the running container there are multiple options:

  • you can copy content by using the scp (winscp) command from the host
  • it is possible to enter the container by running docker exec …. and use tooling to copy content from the host to the container
  • we can share a volume with the container

The most convenient way is to share a volume. First you have to create a folder on your host with will be the mount point of the volume. Let’s assume you create this folder and name it “html“.  To mount this volume in the docker container you use an option of the docker run command.

So, again stop your running my-apache-php-server container and remove it. Create the new container by executing the command:

$ docker run -d --name my-apache-php-server --link mymariadb -p 80:80 -v "$PWD"/html:/var/www/html php:7.2-apache

Now the container has been created with an open port (80, http), linked to the mysql container and with a shared volume. So everything you copy, move or create in the html folder you have created before will be available in the container in the folder /var/www/html. Create a simple php file in the html folder and save it as index.php:

Now, when you direct your browser to the http://localhost you will see the output of your website.

Ok, so far everything works. Let’s try to test the connection to the database  server now. To connect to a mysql database from the php/apache container we have to install an extra php extension in the container. To accomplish this first connect to the container with a shell:

$ docker exec -it my-apache-php-server bash

In the docker php image documentation the “docker-php-ext-install” command is mentioned to install extra php extensions. In this case we want to install the mysqli extension. Run the following command in the container:

# docker-php-ext-install mysqli

The script will install the extension. After the script finished you can exit the container (by typing exit). To enable the extension you have to restart the container:

$ docker restart my-apache-php-server

Final result

Use the script below to test the connection to the database. Copy it into a new file in your html folder named mysqlinfo.php and direct your browser to it (http://localhost/mysqlinfo.php):

The final result is a successful connection.