One of the most popular questions we get from customers is how Codefresh compares to Jenkins. People are also curious about seeing the classic comparison matrix between the two solutions as part of their evaluation.
It is important to understand that Codefresh and Jenkins are not truly comparable as they are not serving the same function. Codefresh has a bigger scope than Jenkins.
In fact, one of the most crucial points of the comparison is that Jenkins is only a Continuous Integration (CI) solution, while Codefresh covers both Continuous Integration and Continuous Delivery. Therefore by design, Codefresh offers many more features as it focuses on the full CI/CD lifecycle. In the next sections, we will explain how Codefresh offers a superset of what is possible with Jenkins.
Also notice that for the purposes of this article, “Jenkins” refers to the open source Jenkins 1.x and 2.x versions (and their enterprise siblings from Cloudbees). We will explore Jenkins X in a separate article and see how it compares to Codefresh on its own.
Point 1 – Jenkins is CI only, Codefresh covers both CI and deployments (CD)
At its core, Jenkins is a simple task runner. It can run builds that cover all the basic Continuous Integration tasks such as:
- Code compilation
- Artifact packaging
- Pull request handling
Codefresh, on the other hand, supports all these tasks as well as the actual deployment. Here is how both tools compare in the classic pipeline that first deploys to staging and then to production environments:
It should be clear from the picture above the Jenkins offers zero facilities for actual deployment. When people say that they “deploy with Jenkins” they mean that they execute a completely custom in-house deployment script which actually takes care of deployment.
Jenkins does not do deployments on its own. It needs to be coupled with a CD solution and traditionally companies have used configuration management solutions for this purpose.
The lack of Jenkins deployment capabilities is well known and several companies have tried to put glue code in their Jenkins pipelines in the form of bash/Chef/puppet/Ansible scripts. This approach quickly results in a spaghetti of procedural custom code that is hard to maintain and upgrade. Maintenance of Jenkins nodes can quickly become one of the most boring tasks in a development team.
Codefresh, on the other hand, was designed with the full software cycle in mind from the beginning. Here is a screenshot of Codefresh deploying to Kubernetes via the GUI (one of the many ways to deploy with Codefresh). This functionality is built into Codefresh by default (no plugin is needed for this capability).
For programmatic deployments, Codefresh offers a declarative yaml syntax (discussed later in this post) which is far superior to procedural in-house deployment scripts.
What is more important is the fact that Codefresh standardizes deployment with its built-in deployment capabilities instead of using custom in-house scripts.
Point 2 – Codefresh is a batteries included DevOps solution
We have seen in the previous section that Codefresh covers both CI and CD while Jenkins is only a CI server. In the case of Kubernetes/Helm deployments, Codefresh takes it one step further by providing everything you need in a single platform:
- A CI solution for packaging of artifacts
- A CD solution for deploying artifacts
- An integrated Docker registry to store artifacts
- An integrated Helm repository to store Helm charts (i.e. Kubernetes packages)
This makes Codefresh a one-stop-shop for Kubernetes deployments as it contains the whole platform in a single cohesive package:
With Jenkins, you only get the CI part and nothing else. It is your responsibility to cover not only CD but also the Docker and Helm management of your pipelines.
This means that any solution based on Jenkins requires extra effort on your part to find the missing components for the full pipeline. With Codefresh you can start deploying right away without any extra requirement.
Point 3 – Codefresh has built-in Docker/Kubernetes/Helm management dashboards
We have seen in the previous section that Codefresh also comes with an integrated registry and integrated Helm repository. Apart from the storage itself, Codefresh has a set of graphical dashboards that allow you to manage your artifacts and releases.
The Docker registry has its own dashboard that includes search filters:
The Kubernetes dashboard shows the running status of your cluster along with what is deployed:
Finally, the Helm dashboard shows what Helm packages are installed in your Kubernetes cluster:
A unique feature offered by Codefresh is the ability to rollback Helm releases to a previous version right from the User interface.
Jenkins offers none of these dashboards because it only handles CI and knows nothing about environments or deployments. This is a crucial point as we will see in the next section.
Point 4 – Codefresh offers full traceability from commit to deployment
We now reach perhaps the most important point in this comparison. We have seen already that Codefresh is a full DevOps platform that includes all phases of the CI/CD lifecycle including artifact storage and cluster management.
This gives Codefresh the full view of a deployment from start (commit) to finish (release). It is very easy from the Codefresh dashboards to track what is released where:
The question of what is released on which environment is one of the most common questions among a development team. In Codefresh, any stakeholder can easily answer this question just by looking at the integrated dashboards.
Jenkins, on the other hand, knows only about jobs and builds. It is your responsibility to find a way to correlate what is deployed from where.
Point 5 – Codefresh pipelines use Docker-based steps by design
Traditionally Jenkins 1.x builds are based on VMs which have pre-installed all possible build tools needed by all projects inside a company. Builds are then executed in a scripted manner where all needed build dependencies are prepared in advance.
Unfortunately, this practice is the same one that results in huge unmaintainable jobs that were hard to version and reason as Jenkins 1.x was configured via GUI elements instead of programmatic pipelines.
Using multiple versions of the same build tool in the same pipeline is a nightmare in Jenkins 1.x. Upgrading the tool to a new version is also very hard as it might break any of the builds that use it.
Jenkins 2.x added the concept of pipelines that can execute commands inside Docker images. This is an extra ability that is changing the way builds are happening compared to Jenkins 1.x and is indeed a welcome change. Tool upgrades are now easier (i.e. only the respective Docker image must be changed) and using multiple versions of the same tool is now possible.
This capability of Jenkins 2.x is however purely optional. A team that is using Jenkins is still able to create pipelines using the old way of installing all build tools on the Jenkins host and running them in a single VM, still stumbling in all the issues and problems of the traditional method.
Codefresh, on the other hand, enforces Docker-based builds (where all build tools are Dockerized) in a strict manner by offering this as the sole way of creating pipelines. In Codefresh, all build steps are running in the context of a Docker container. This makes Codefresh pipelines resilient to tool upgrades and future proof in the sense that any tool that comes in a Docker image can be used in a Codefresh pipeline.
What is more, Codefresh offers some additional capabilities:
- A common Docker volume is attached automatically between all build steps, so there is no need for the concept of “artifacts” or “cached folders” in order to share information between steps.
- Aggressive caching of this volume as the well of the intermediate Docker images allow for fast builds regardless of the actual build tool used.
- All successful builds automatically push their result in the Integrated Docker registry, making future builds much faster if the artifacts do not change.
The killer feature of Codefresh, however, is the capability to create dynamic Docker images from the same pipeline that will use them:
In Codefresh it is possible to:
- Create a Docker image on a build step with custom tools (e.g. add a test framework on an application image).
- Run a command in the next step using a context the Docker image created in the previous.
To sum up, Codefresh has fully embraced Docker-based builds instead of offering it as an optional extra feature as Jenkins 2.x does.
Point 6 – Codefresh pipelines are declarative yml instead of Groovy scripts
We have already mentioned the problems of maintenance when it comes to Jenkins 1.x. Jenkins 2.x comes with programmatic pipelines that are implemented in the Groovy language.
Even though Groovy is a great programming language for DSLs and can result in very concise code, it can also be used to create unreadable procedural scripts.
Jenkins 2.x allows for both “declarative” and “scripted” modes for Groovy scripts. The “scripted” mode is very close to real Groovy code making it very easy for developers to abuse the syntax offered.
Codefresh offers only one mode for pipelines: declarative yaml. There is no scripted mode, so creating pipelines always happens in a standardized manner. This is very important for companies that are moving from monoliths to microservices, as the large number of pipelines from different teams makes standardization a compulsory requirement.
Codefresh also comes with very sensible defaults (convention-via-configuration). The most minimal pipeline in Codefresh is just 5 lines:
version: '1.0' steps: MyAppDockerImage: type: build image_name: my-own-app
This pipeline will:
- Automatically checkout the code from the GIT repository connected to it.
- Create a Docker image named “my-own-app” from the root level Dockerfile and tag it with the branch name of the git repository.
- Upload the resulting docker image in the integrated Codefresh registry (happens automatically for all successful pipeline builds).
The comparable Jenkins 2.x pipeline would be more than 15 lines of Groovy script.
As another example, Monorepo support (where multiple projects are in the same git repo) can be enabled in Codefresh with a single line:
This instructs the Codefresh pipeline to run only if the files under my-awesome-app folder are changed. The same thing in Jenkins requires custom scripting and knowledge of the internal Jenkins API.
Point 7 – Codefresh extensions are Docker images instead of custom Groovy libraries
We have talked in the previous section about Groovy pipelines in Jenkins 2.x and how they can easily be abused for unmaintainable scripts. Another important point is the concept of pipeline extensions.
In Jenkins 2.x it is perfectly fine to use the “declarative” mode of Groovy in simple pipelines. In complex pipelines, however, you will need to extend the basic syntax and add your own capabilities.
The suggested way to extend Jenkins is via shared libraries. The official Jenkins documentation page alone is 11 pages and assumes that:
- you know Groovy,
- you know the shared library Jenkins API,
- you have admin access on the Jenkins instance in order to install the library.
This makes the creation of a Jenkins library a full-scale project as you need to follow a predefined project file structure, learn the API and also know how to test and install it.
The fact that only people with admin access can install shared libraries goes against the whole spirit of DevOps, as it instantly creates a barrier between those that want to upgrade the libraries used and those that can actually do it.
The Groovy choice is also a big problem for companies that have no in-house expertise in Java/Groovy. Even if there is expertise in Java/Groovy, the Jenkins API is hard to mock and test.
Codefresh takes a very simple approach. A Codefresh plugin is just another Docker image. That’s it! There is no other requirement. You can use any programming language to create a Codefresh plugin. You can also use any pre-existing Docker images for a Codefresh plugin.
Communication with Codefresh pipelines happens only via environment variables and files which are known by all developers. This means that you can write Codefresh plugins in Scala, Rust, Go, Erlang, Haskell and anything else that can write files and understand environment variables.
Finally, using a custom Docker image in a Codefresh pipeline requires no special privileges. Creating and testing a custom Docker image in Codefresh is actually a very common pattern.
In summary, creating a plugin for Codefresh is a painless operation without requiring a specific programming language, API knowledge, or admin access.
By this point, it should be clear that Jenkins offers only a very small subset of Codefresh features. It should also be clear that this is because the scope of Jenkins is very narrow. Jenkins started as a simple job/task runner and was never designed as a full CI/CD solution.
There is a very large number of Jenkins plugins out there (of various quality levels) but none of them can change the basic abstractions offered by Jenkins, which have nothing to do with deployment and monitoring of a modern cloud application.
The abstractions in Jenkins are only two
In Codefresh the following are top-level constructs:
- Git repositories
- Docker images
- Docker registries
- Kubernetes clusters
- Kubernetes services
- Kubernetes namespaces
- Kubernetes deployments
- Helm repositories
- Helm charts
- Helm releases
As companies are moving into microservices, where the deployment of an application is something that happens very often (instead of having full blown “release” periods), having a true CI/CD platform will become an essential requirement. Despite all the plugins, Jenkins is still a plain build server.
Update: A comparison is also available for Codefresh versus Jenkins X.
New to Codefresh? Create Your Free Account Today!