Over a million developers have joined DZone.

But It Worked on My Machine

DZone's Guide to

But It Worked on My Machine

There are many reasons code could pass on one machine but fail elsewhere. See how using a personal CI server with Docker can help solve this problem.

· DevOps Zone ·
Free Resource

Is the concept of adopting a continuous everything model a daunting task for your fast moving business? Read this whitepaper to break down and understand one of the key pillars of this model in Continuous Governance: The Guardrails for Continuous Everything.

Anyone familiar with software development can attest to hearing "But it worked on my machine," or a variation of it. There could be a multitude of reasons for code to pass on a developer's machine but fail everywhere else. Some of the common reasons for a particular changeset or commit to fail on the development team's official continuous integration system are: 

  • Differences in system environments.

  •  The commands used to run and test the build ("-Dmaven.test.skip=true" anyone?).

  • Files and/or dependencies that only exist on the developer's machine.

  • Bugs in the code.

One of the primary objectives of a CI system is to catch build issues as soon as the code is checked into the version control system. While compile issues are identified almost instantaneously, it takes a bit longer for a CI system to catch regressions or new bugs. But then again, code bugs seldom happen - we software engineers never make coding errors, do we?

The amount of time it takes for a CI system to report the outcome of a run––often called the feedback time––depends on the size of the codebase and the number of automated smoke and integration tests. Additionally, if a failed run is an aggregation of changesets from multiple developers, identifying the root cause takes even longer. Such delays in the feedback time are clearly a source of frustration for all stakeholders involved.  For what it's worth, modern CI systems do their best to identify offending changelists, albeit prone to false positives and other errors. 

To address this issue and cut the feedback time, developers should be encouraged to setup and use a personal CI server before posting code reviews or checking in code. The advent of Docker makes such a setup a breeze. Here's a sample development flow:

  • Based on requirements, a developer makes changes to the codebase on his or her local machine.

  • After a satisfactory outcome, the developer creates a changelist and kicks off a build on their personal CI system.

  • While the entire suite of automation tests run on the personal CI server––ideally in a Docker container––the developer can attend to other tasks.

  • After a successful test run, the developer can post a code review and check-in the changes.

Running the changelist on a personal CI server beforehand gives the developer and the reviewers greater confidence in the changes. Ideally, it would also mean that there won't be any issues after the code is checked-in. Which means green builds, a stable codebase, and a happy team.    

Now let's switch gears to setup and run one. While there are a number of open source automation servers––like Jenkins and others––to choose from, I will use buildpal. 

Buildpal is a Docker native continuous integration server that promotes the "pipeline as code" philosophy. Pipelines are defined using JavaScript; they can be stored and versioned in a source code repository. Pipelines that are stored in source repositories can be automatically scanned by buildpal. One or more phases constitute a pipeline; phases can be run in parallel or in sequence. Each phase can define its own environment variables, docker image, and commands to run.

Install buildpal

First, make sure you have Docker up and running on your local machine. Now open up a terminal and run the following command:

docker volume create buildpal-data && \
docker run -d --name buildpal -v /var/run/docker.sock:/var/run/docker.sock \
  -v buildpal-data:/buildpal/data -p 8080:8080 buildpal/buildpal

That's it. You should have buildpal up and running. Go to http://localhost:8080. Log in using the default credentials admin/admin123.

Create a Pipeline

Let's use buildpal's code repository to define a pipeline. The first step is to create a repository in buildpal.

Create a repository

The next step is to create a new pipeline. Since buildpal is based on Java and uses gradle, modify the sample JavaScript code as shown below. 

Create a pipeline

All we have to do at this point is to run the pipeline and monitor the build.


Developers working on codebases of any size will greatly benefit by running a local CI server. Code changes can be checked-in with greater confidence. It leads to a higher number of green builds on a team's official CI/CD system, which means a stable codebase and a happy team. 

Are you looking for greater insight into your software development value stream? Check out this whitepaper: DevOps Performance: The Importance of Measuring Throughput and Stability to see how CloudBees DevOptics can give you the visibility to improve your continuous delivery process.

continuous integration ,docker ,build automation ,software development ,devops

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}