I’ve recently been exposed to Docker and am becoming captivated by the opportunities it presents. On previous teams, we were responsible for building and maintaining the Virtual Machines (VMs) used for development, staging, and production. It goes without saying that the core parts of each environment must be exactly the same. Nothing ruins a deployment like the realization that code working flawlessly in testing doesn’t pass in production.
When first building these VMs, it was easy to construct three identical environments. As time passed and the code grew, libraries needed to be added while others needed to be updated. If we failed to perform these actions exactly the same in each environment, discrepancies between the code behavior on each VM would result. This was a huge hassle and led to many problems. Docker circumvents this problem by presenting a way to ensure the code will run identically whether it’s on development, staging, or production.
Consequently, what is Docker and how do I use it? Docker is a tool used to build environments and run applications. The two main objects when using Docker are an image and a container. The image is an executable, describing how a container should be built, while the container is where the application will run. Before an image can be run to create a container, a Dockerfile must be written. The Dockerfile is like a blueprint that provides instructions on exactly how the image will be built. The Dockerfile specifies the environment and the initial executions — the operating system, the libraries needed, where to store the code for the application, and what commands to execute when starting the container.
Once everything is laid out in the Dockerfile, this file is used to build a Docker image. The Docker image is kind of like a VM snapshot. The Docker image can be pushed to Docker Hub, https://hub.docker.com. Docker Hub is just like GitHub, and lets developers share Docker images. Running the Docker image will create a container where the application will run. This container is like an instance of the image. Every time the Docker image is run, a new container is created; each of these containers is an exact copy of each other.
How can Docker be used to ensure development, staging, and production are identical? First, regarding the development, staging, and production VMs, Docker must be installed. But after that, no independent actions need to take place on the separate VMs. (Unless the containers need different environmental variables, but that is beyond the discussion of this blog post.)
Building the Docker image will take place on a personal machine. Here, the Dockerfile (blueprint for the Docker image) is constructed, and the code for the application can be modified. When the code is ready, run the docker build command on the Docker file to produce the Docker image. Then, run the docker push command on the Docker image, so it goes up to Docker Hub.
Once on Docker Hub, each VM can run the docker pull command to obtain the Docker image. On the development VM, pull the Docker image and run the image using the docker run command to produce a container with the application. While performing testing on the application, if any errors are found, return to the personal machine and edit as necessary. Then, on the personal machine, build a new image and push it up to Docker Hub. Back on the development VM, pull the new image, run a container, and continue testing. Perform this process until the application is ready for staging.
Next, on the staging VM pull the same Docker image that passed testing on the development VM, and run a container. Remember, this container on the staging VM will be a replica of the container tested on development because the two containers were built using the same Docker image. If problems are found on staging, make modifications on the personal machine, build a new image there, and push the new image to Docker hub. Then perform testing again as described above, starting on the development VM and moving to the staging VM, always using the same Docker image in each environment.
Once testing is complete, switch to the production VM, pull the Docker image that passed testing on the staging VM, and run a container. Using Docker in this way ensures the application will behave exactly the same on production as intended and tested throughout staging and development.
This was a quick overview of one simple way to use Docker. The full use and description of Docker is far more expansive. If you would like to do some research on your own, please see the docs at https://docs.docker.com.;
Check back with us next month for Docker Part 2, outlining the build process and mounting volumes.