Building a reliable and comfortable development environment is not an easy task. Running multiple versions of the same software might be a bit tricky. This post shows how to build an awesome development environment with Docker.
Docker is an open-source platform that automates the development of applications inside software containers.
What are the advantages of using an external tool to manage software on a development machine?
- running multiple versions. Usually only a single version of the application can be found in package manager. Very often, it’s not the latest version. Example: there’s no Oracle MySQL package in the ArchLinux packages repository.
- saving time spent on compiling an application from sources. Managing multiple versions of the same software is time-consuming.
- avoiding dependency hell. You can use a few versions of the application without introducing any dependency compatibility issues.
- reliability. Official Docker images are more reliable than third party repositories.
Using Docker to install multiple versions of MySQL
MySQL has been used as an example in this post, but the process is almost the same for any kind of software. You can find the details about the official MySQL Docker images at the Docker Hub page.
You’ll need the following dependencies to achieve our goal:
- Docker
- systemd or equivalent
- (optional) a build tool (GNU Make would match the requirements perfectly) – this
example uses simple shell scripts.
The first step is to create a directory where the configuration files will be stored. A home directory will be a good choice:mkdir -p ~/.docker/mysql/{5.6,5.7}
(the location of the ). Two MySQL versions will be used as an example: 5.6
& 5.7
.
Every container requires a Dockerfile, so creating those is the second step: touch ~/.docker/mysql/{5.6,5.7}/Dockerfile
.
You can open Dockerfiles using any text editor: emacs, vim, gedit and so on.
~/.docker/mysql/5.6/Dockerfile
~/.docker/mysql/5.7/Dockerfile
Some explanation of the Dockerfiles content:
FROM
specifies the image name & image tag used in the following format:name:tag
ENV
sets a environment variable. In this example, an empty root user password is allowed.VOLUME
sets the location of mounted volume as database files should be stored on the host machine.EXPOSE
determines the port number that will be available from the container host.CMD
sets up the default entry point.
As we’re using multiple versions of MySQL, the volume path and exposed port number both need to be customized. This isn’t necessary if you’re using single instance.
After the Dockerfiles are ready, an automation tool will be required to build and run the containers. This example uses simple shell scripts, but any build tool can be used: touch ~/.docker/mysql/{5.6,5.7}/build.sh
.
~/.docker/mysql/5.6/build.sh
~/.docker/mysql/5.7/build.sh
Some details about the build scripts:
docker stop
command stops any running the container namedmysql-5.6
ormysql-5.7
docker rm
removes any existing container with the specified namedocker build
builds a new image with the specified tag – in this examplemysql-5.6
ormysql-5.7
docker run
runs a container using a previously created imagedocker start
starts the newly created container
MySQL Docker – Almost there…
At this stage, MySQL Docker containers are fully functional and accessible from the host machine. They store MySQL user home directory on the host. There’s one issue with the containers – they do not start on the system boot. To start them, an init system or a cron job might be used. In this post, I’ll use systemd.
/etc/systemd/system/mysql-5.6.service
/etc/systemd/system/mysql-5.7.service
These newly created service units depend on Docker service. The services will always start after the docker
service has been started. To start on system boot, you should enable the following services:
Now both MySQL containers should be started after system boot.
You can use this method as a replacement for the default system packages. Personally, I use it on all my development machines to install software that isn’t available in the system package repositories. I also use it to run multiple versions of the same server (PostgreSQL, MySQL, MongoDB, etc) for all non-dockerized applications I work on.
Why don’t you also check out our Introduction to Docker presentation?