Overview

Docker is a modern technology that allows you to create templates for virtual machines to be created, started and shared between different host systems or without other people. Starting a template actually implies creating a virtual machine of it first and it is not uncommon, to discard of that vm immediately after it is shut down.

In this example I use docker to try and debug the plugin PHP code that I created for my CaldavCalendarBlocktypePlugin (see link section). Docker in this case helps me to encapsulate the database, php and webserver instances so I don't have to install that on my local machine. Also the disposable nature of the VMs helps me to always start from scratch when I want to reinstall the plugin after a modification and it saves disk space because the database is removed with the VM. 

Another technology I used to improve my plugin development experience is Phing which helps me to persist the docker-commands and make them available as a menu-option in my netbeans suite.

Docker - setup

Like already set in the overview, docker is a technology based on blueprints (called images) of virtual machines that can be used to create actual virtual machines (called containers) and that can be started up, shut down and quite often are disposed of after. For a productive system, the data to be persisted is usually collected on volumes, that can actually be simple folders mounted from the host-system into the container or docker-specialized volumes that are designed to be hooked into containers. Docker also has an additive mechanic for inheriting between containers. This works as follows: You start with an initial image (docker itself provides some basic and minimalistic ones but you can build one from scratch as well) and then you make modifications on it and then you create your own image - but what is actually stored for your image is only the reference to the initial image and the delta, that is, the parts where you added, removed or overwrote stuff. I link to think of this like a set of paper, transparent overhead projector slides and tippex. The paper contains the original version. When you want to change something, you put a transparent overhead projector slide on top and either add your stuff on top of blank background or use tippex and write on that, where you want to change stuff that is already there. No consider, that a computer does not need the actual slides, it just remembers the positions where stuff was added or removed. This saves a lot of space, when your image only needs minimalistic changes.

Docker also suggests to use one container for a single process/task, which goes with the minimalistic base images. You can of course descide for yourself, how far you drive this. In my example, I split up the installation into two containers: a db container with mysql and an apache-container with php installed (You will see php and apache split up occasionally, but I didn't see the point here as I don't plan to hook up other web servers, like nginx). The apache.container also gets the mahara-program and some scripts copied to it so it can automatically install mahara on startup.
I looked around at the various mahara-images on docker-hub, none of them offically from the mahara-team, as it seamed or if so, not up to date and finally decided on one that offered a lot of parameters: cms0/mahara. I had to fiddle around a bit to make it work, but in a rather short time I got my own version: tobiaszeuch/mahara. Starting the containers locally, I was able to pair this with a plain mysql-instance and install mahara.

Next step was to automate the configuraion of the docker-containers build from the images. I did this using docker-compose, which is sufficiently powerful for a local machine, though not as complicated as e.g. Kubernetes, wnich is intended rather for bigger environments. In the compose-file, I am able to specify variables that are handed into the containers to configure them, like the admin-name and password for the mahara-instance, the database-server and some more things. I also specified a folder to be hooked into the container and mounted to where the mahara-installation would live. This will later help me to apply changes in the plugin-code directly into the running container. Now I am able to start two doker-containers, one with the database and one with the apache-server running the actual mahara - all with a single command from the shell.

Buttenize the workflows with Phing

I have a family with small kids, so I won't be able to continuously work on plugin, so if I come back in a year with some time to look into my plugin, it would be nice to have the command at heand. But much more important: I would like to apply any modification of my plugin code into the running container with a single click from within Netbeans (my Code editor and development environment). 

I found my solution with Phing, a PHP project build tool. Netbeans comes with direct Phing-integration in that it lists phing-targets as entries in the context-menu of a project. Phing-targets are declared in a build.xml file. You can see my example here. I initially created three targets: one to create and start my containers, one to stop them and one that copies the plugin-content into the corresponding path into the folder that is mounted into the apache-container. 

Conclusion and next steps

The primary focus of setting up the container was to learn about docker and the plugin-development was merely a substancial example, but in the end I tested and used the setup in extending the plugin with an autodiscovery functionality for caldav servers. And although php by nature is not talkative about programming errors until you fire up the program and run into them, the docker-setup and the phing-integration prooved to be relaly helpful.

Another helpful task of course would be to implement php-unit-tests, that by the way could also be integrated into phing tasks. 

You might also wonder about the caldav-server: For the moment I worked with my private owncloud installation, although I also worked on a setup with a dockerized caldav server. Biggest drawback on the moment is that I haven't looked into how to automatically populate the calendar when the container starts, but there has to be a way for sure. 

Also I have another docker-project on my desk for integration-testing the plugin with future mahara-releases and with as much automation as possible. 

In the link-list you should be able to find references to the various technology, my plugin, and also the docker-files hosted on github. Feel free to comment or contact me or just use the linked resources for your own project.