You don’t live in a vacuum. You change your environment and your environment changes you. Your application is the same way. Your application and your server environment) interact and are dependent on each other.
Ever wanted to see if the latest version update of your app server played nice with your application with an easy way to instantly fallback to your current configuration? Or have an issue on one development machine, that is not reproducible on another? How many times have you deployed apps that worked great in development environments, only to have them flop in production with configuration issues? Or want to test something on your entire server cluster without bringing the entire team’s progress to a halt? Traditionally, environment constraints have made these pain points for our teams.
Virtual Machines and the cloud have helped alleviate some of the pain, but they remain expensive both in terms of cost and performance resources. Additionally, they can be unwieldly and/or require very specialized knowledge.
Enter Docker. It runs at near native speeds (up to 1000x faster than VMs) yet still maintain strict process isolation and filesystem isolation. It’s also open source. FREE is a hard price point to compete with. Furthermore, Docker has a powerful api that should seem familiar to anyone who has ever used the commandline for Git or Linux.
However, the API is not what makes docker like Git. Git has been disruptively effective for developers because of it’s ability to cheaply and rapidly branch. This allows developers to freely try different ideas and approaches on different branches without having to worry about losing any progress. This means quicker iterations where the best solution rises to the top.
Docker is the same for Ops. It makes branch trivial, and gives Ops the ability to iterate quickly in a safe, sandboxed environment. In the rapidly evolving technology world, this agility is required to keep up. The stateless infrastructure model that has helped make the cloud so successful is now at the fingertips of Developers and Operations alike, a true DevOps nirvana.
Conceptually, Docker has two main objects for DevOps to interact with – Images and Containers. Instances of both are represented by hashes, similar to Git hashes. Images are essentially filesystems. Containers are the sandbox for your processes. Unlike VM’s, Docker only virtualizes the filesystem (the system’s hardware and OS are not virtualized). Then Docker makes use of Linux Containers (LXC) to isolate the already efficient Linux Processes.
Like Git, Docker uses repositories to house the images. Similar to GitHub for Git, Docker has the Docker Index. You can pull down Docker Images from the Docker instance and then follow the instructions on the repo’s readme to run the container. That means with a simple
docker pull myimage and
docker run myimage myapp you can have your entire environment configured and running at near native speeds.
You can then attach to this instance, make your enhancements, and save off your changes in a new commit hash. So, just like Git you have a full history at any commit snapshot for both images and containers. You can also diff the two hashes to see changes in the image. This is what enables the incredible iteration speeds for Ops teams.
However, unlike Git, you cannot merge filesystems or containers together. In my experience, this is not an issue since you can adopt a layering workflow. I believe this layering workflow will become the new default, similar to the Nvie Branching Model for Git. To see an example, checkout my BLC-Demo image here on the Docker Index. Follow the instructions on the readme and then run a
docker history jhamit/blc-demo to see a history of all the layered images I combined to create this environment. As an extra bonus, after pulling down my image, you will have the BLC Demo Site up and running with a simple the provided
docker run command.
Have questions? Want a workshop for your local usergroup or team? Tweet me @josh_hamit or post a comment below.