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

Introduction

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 docker.com. 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.

 

Streaming containerized JAVA applications – Part 1

Introduction

I have the strange habit to try to keep my Macbook as “clean” as possible. That’s why I hate to install all sorts of applications I just want to test or applications that I only use once in a while. I know there are all sorts of methods to prevent cluttering of my harddisk but since I’m a bit of a Docker freak I wanted to find a container solution. In this post I will describe what I did.

In this post I assume you have docker installed on a MacOS device (Macbook, MacBook Pro, etc.) and you have installed XQuartz (xquartz.org). My first application is SQuirreL SQL, an open-source graphical Java application that will allow you to view the structure of a JDBC compliant databases, browse the data in tables, issue SQL commands etc..

The container

To build the image I have used the Ubuntu image as base image. Probably there are smaller base images which also work. The base image is update first and further enriched with a JAVA runtime environment, some tools to unzip the SQuirreL Sql application and the application itself. This results in the Dockerfile below.

As you can see I copy three drivers into the image:

  • the official MySQL JAVA driver (free download from mysql.com)
  • the Microsoft jdbc SQL driver (free download from microsoft.com)
  • the MariaDB driver (free download from mariadb.org)

You can add your own platform drivers to suit your needs.

To build the SQuirreL SQL image simply run the docker build command while you’re in the directory containing the Dockerfile:

$ docker build -t squirrel/custom:v1 .

You will see docker going to work to build the image: the base image is downloaded, updates are performed (and downloaded) and the applications are installed. After some time docker finishes and your image should be ready to test.

Executing the docker images  command should give you a list of images containing the newly build image.

REPOSITORY                TAG          IMAGE ID                CREATED              SIZE squirrel/custom           v1             70cdc9dea37a        1 minute ago        566MB

Running the application

To stream the display output of the running container to the X-system om my Macbook (over tcp/ip) I use the socat utility. Socat is a command line based utility that establishes two bidirectional byte streams and transfers data between them. Because the streams can be constructed from a large set of different types of data sinks and sources, and because lots of address options may be applied to the streams, socat can be used for many different purposes. You can install socat with brew: $ brew install socat . To be able to use brew you first need to install it. You also need some Xcode development tools which can be installed by  $ xcode-select --install . There goes my argument for a clean MacBook….

Nevertheless, to start the container with socat running you have create a small script:

This script first executes socat ensuring there is a byte stream established. Then the script executes docker run wit  an environment variable DISPLAY. In this example I’m also using the –rm option of docker run. This removes the container as soon as it has stopped. This has advantages (direct clean-up, always a new instance) and disadvantages (all your settings in the container will be lost after it stops).

Finally

The result is the SQuirreL SQL application running in a container while the user interface is displayed on your Mac in an X window. My second post about this topic will be showing other applications (tn5250, Scribus) which I have containerized.