Use your preferred Git workflow to achieve fast and error free environment promotion with Docker TL;DR Deploy Docker FastPath in your build system. One of the most useful piece of information that I learned from the classic by Humble and Farley (got get your copy now!) is to . Continuous Delivery Only Build Your Binaries Once Many build systems use the source code held in the version control system as the canonical source for many steps. The code will be compiled repeatedly in different contexts […]. Every time you compile the code, you run the risk of introducing some difference[J. Humble, D. Farley, Continuous Delivery, p. 133] You can notice that the book has been written in 2011 by the use of the word “compiled”. Fast forward in 2017, and Javascript-based technologies reach a staggering 85% preference in the last and dynamic languages are dominating . Unsurprisingly that advice is still valuable today: you just need to change “compile” with your preferred build method ( , , , etc.). StackOverlow Developer Survey web development npm install bundle install webpack In a researchers found out that: study […] typical circumstances under which a build breaks are missing referenced files, mistakenly checking in work-in-progress, and transitive dependencies. Also, building again and again the same codebase is time expensive and it makes harder for developers to get timely feedback. So, nowadays it’s even more necessary to “Only Build Your Binaries Once”. In a development pipeline this translates into: Docker Only Build Your Images Once Your typical Git + Docker Continuous Integration pipeline The typical continuous integration process using Docker is: A code push to the git repository triggers the build process(Jenkins, TravisCI, GitLab, etc.) A Docker image is built, (tagged) and pushed to a Docker Registry The image is automatically tested The image is deployed on your favourite Docker orchestrator (Kubernetes, ECS, Swarm, etc.) in a testing environment The process is repeated for the following environments in the pipeline (staging, production, etc.) Usually, you have more than one server environment. Environment labelling varies a lot; popular choices being , , . When the goals for a given environment are fulfilled, there’s the need to promote the change to a higher environment. development qa staging The goal here is to push our artifact (the Docker image) from one environment to he next one. One possibility is to decouple this process from the code repository: the image promotion happens on an external system. This approach is not easy to integrate with common git workflows (G , , , ), where the control stays in the hand of the developers. But, as Humble and Farley taught us, promoting at the code level is (and I agree). itflow GitHub Pull Requests GitLab Merge Requests something else bad Introducing Docker FastPath I advocate here to keep control in the hand of developers by letting them use their preferred Git workflow and enjoy the power of . The method is independent of the particular Git workflow in use and it is based on two simple rules: only building their images once Tag the image with the Git commit ID from which the image has been built. Do not rebuild on code push if the codebase is identical to an existing image: deploy that image instead. To apply rule number 2 it is necessary to examine the Git history and cross check the result with the Docker registry tag list for the image. Note that in most cases you can have two identical codebases with different Git commit IDs: so comparing Git IDs is not enough, you need to diff the two codebases. does that. Docker FastPath Let’s see some examples. Example #1: Merging a feature-branch This is the default behaviour for GitHub Pull Requests. All commits from the feature branch are added to the base branch using a merge commit (using the option). In this case, commit is identical to commit and it does not need to be rebuilt. Image tagged can be deployed directly. master --no-ff 1044aee e51acc3 1044aee Example #2: Squash and merge This is the behaviour for GitHub Pull Request when you select “Squash and merge”. All feature branch commits are squashed into a single commit and added to the base branch using Git fast forward. In this case, commit is identical to commit and it does not need to be rebuilt. Image tagged can be deployed directly. af49f3d e51acc3 e51acc3 Example #3: Rebase and merge This is the behaviour for GitHub Pull Request when you select “Rebase and merge”: all commits from the feature branch are added to the base branch, without a merge commit. In this case, commit is identical to commit and it does not need to be rebuilt. Image tagged can be deployed directly. 1eb55b3 e51acc3 e51acc3 Try it code is available on GitHub as a command line tool. You can download an executable for MacOS or Linux which can be easily deployed on most build systems, but you can build it from source code if you wish. Docker FastPath Two deployment examples are provided: one using , and another one using . It should be easy to use those examples to adapt FastPath to your existing software project based on Docker. Jenkins Travis CI If you enjoyed this piece click the “♥︎” button below. For more pieces on DevOps and Docker, join my . mailing list