Build development environment with Docker

Building reliable and comfortable development environment is not an easy task. Running multiple versions of the same software might be a hard process. This post illustrates how to build an awesome development environment with Docker.

Docker is an open-source platform that automates development of applications inside software containers.

What advantages might bring using the external tool to manage software on development machine?

  • running multiple versions — usually only a single version (very often it’s not the latest version) of application can be found in package manager (example: there’s no Oracle MySQL package in ArchLinux packages repository)
  • saving time spent on compiling an application from sources — managing multiple versions of the same software would be time consuming
  • avoiding dependency hell — few versions of the application can be used without introducing any dependency compatibility issue
  • 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. Details about the official Docker images for MySQL can be found at Docker Hub page.

The following dependencies will be required to achieve the 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 ). As can be see, two MySQL versions will be used for the sake of 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. Dockerfiles can be opened using any text editor: emacs, vim, gedit and so on.


FROM mysql:5.6ENV MYSQL_ALLOW_EMPTY_PASSWORD trueVOLUME /var/lib/mysql/5.6EXPOSE 3306CMD ["mysqld"]


FROM mysql:5.7ENV MYSQL_ALLOW_EMPTY_PASSWORD trueVOLUME /var/lib/mysql/5.7EXPOSE 3307CMD ["mysqld"]

Some explaination 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 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 number of exposed port that will be available from the container host
  • CMD sets the default entry point up

As multiple versions of MySQL are used, the volume path and exposed port number both need to be customized. This statement does not apply when using single instance.

After Dockerfiles are ready an automation technique will be required to build & run the containers. This example uses simple shell scripts, but any build tool can be used: touch ~/.docker/mysql/{5.6,5.7}/


#!/bin/bashdocker stop mysql-5.6
docker rm mysql-5.6
docker build -t mysql-5.6 .docker run -d \
-p 3306:3306 \
-v /srv/mysql:/var/lib/mysql \
--name mysql-5.6 \
docker start mysql-5.6


#!/bin/bashdocker stop mysql-5.7
docker rm mysql-5.7
docker build -t mysql-5.7 .docker run -d \
-p 3306:3306 \
-v /srv/mysql:/var/lib/mysql \
--name mysql-5.7 \
docker start mysql-5.7

Some details about the build scripts:

  • docker stop command stops any running container named mysql-5.6 or mysql-5.7
  • docker rm removes any existing container with the specified name
  • docker build builds a new image with the specified tag - in this example mysql-5.6 or mysql-5.7
  • docker run runs a container using previously created image
  • docker start starts a newly created container

At this stage MySQL Docker containers are fully functional, accessible from the host machine and storing 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 ths post a systemd will be used.


Description=MySQL 5.6 Docker container
ExecStart=/usr/bin/docker start -a mysql-5.6
ExecStop=/usr/bin/docker stop -t 2 mysql-5.6


Description=MySQL 5.7 Docker container
ExecStart=/usr/bin/docker start -a mysql-5.7
ExecStop=/usr/bin/docker stop -t 2 mysql-5.7

The newly created service units depends on Docker service, so the services will be started always after the docker service has been started. To start on system boot services need to be enabled:

sudo systemctl enable mysql-5.6.service
sudo systemctl enable mysql-5.7.service

After the services are enabled both MySQL containers should be started after system boot.

This method can be used as a replacement for the default system packages. Personally, I use it on all my development machines to install software that is not available in the system package repositories as well as to run multiple versions of the same server (PostgreSQL, MySQL, MongoDB, etc) for all non-dockerized applications I work on.

Andrzej Ośmiałowski

Written by

Senior Software Engineer at

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade