DEV Community


Discussion on: What tools do you use for CI/CD? Past experiences, recommendations?

jillesvangurp profile image
Jilles van Gurp

Docker is the tool of choice for us these days. We started dockerizing our apps a few years ago. But then we realized it provides a great solution for solving the mess of dependencies that used to be our jenkins CI server. We had a crap load of node.js, python and other crap in, typically, not quite up to date and flaky setups on our jenkins. All of that got dockerized. Including jenkins itself.

All our builds now consist of calling docker build on the relevant repo, publishing the resulting docker image with the right tags (branch) and name, and then deploying the resulting image to a staging/production (depending on the branch) using scripts that are part of another docker image that we docker build every time scripts get modified in our deployment repo. The only thing we have on our jenkins server (besides jenkins) is docker and a few generic scripts for triggering the above.

Several big advantages: 1) All our apps include Dockerfiles that document exactly what is needed to build and how to run them. Any configuration is injected via environment variables, as is the Docker way. Our CI builds are simple calls to docker build and essentially the same script for all our apps. This is way better than any README, which lets face it are always incomplete and out of date or having a lot of convoluted and undocumented stuff going on in CI builds. 2) Anyone in our team can run any of our apps straight from the docker repo as long as they have docker installed on their laptop. 3) We can spin up test environments with docker compose easily both for development and CI. 4) Docker's notion of layering containers is great when your build includes a "download the world" step because it can be cached. This makes repeat builds fast when they can be. Whether you are doing maven, npm, or bundler, that's a good thing and it gets rid of cruft accumulating on your build servers. 5) Docker imposes a clean separation between dev responsibility and ops responsibility. Devs provide working docker containers with all their dependencies included. Ops provide infrastructure that can run the images + nw infrastructure & config in the form of env variables to wire everything together.

All of our deploys (testing and production) are triggered by commits or pull requests). Our production deploy process is: approve the pull request from master to our production branch. ETA, about 10 minutes after doing that. Any master commits automatically roll out to our staging. We can spin up development branch specific environments easily as well and achieve the same automation (a dev branch without CI is the same as not doing CI; i.e. don't do that).