I'm currently looking to setup a more sophisticated continuous integration (CI) pipeline for my private software projects, doing so I recently used Travis CI.

Travis is very good and intuitive, the setup to test complex database applications is also very nice, however there is no open source/self hosted version of it.

About a year ago I already tried Jenkins which is kind of the industry standard for CI and also CI+Deployment, but the step learning curve and the high chance of permanent mental issues from its UI are a big drawback.

Recently I attended to a very good talk explaining the basic usage of Jenkins new pipeline feature, which was introduced only recently.

Here is a basic schema of a CI/CD pipeline:
Jenkins Pipeline

After the talk I decided to give it another try, here is the basic docker+jenkins setup I came up with.

Installation

  1. Create a Dockerfile

    FROM jenkins:latest
    
    
    USER root
    RUN apt-get update
    RUN apt-get install -yy \
         apt-transport-https \
         ca-certificates \
         curl \
         gnupg2 \
         software-properties-common
    
    
    RUN curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -
    
    
    RUN add-apt-repository \
       "deb [arch=amd64] https://download.docker.com/linux/debian \
       $(lsb_release -cs) \
       stable"
    
    
    RUN apt-get update
    
    
    RUN apt-get install -yy docker-ce
    
    
    RUN rm -rf /var/lib/apt/lists/*
    RUN echo "jenkins ALL=NOPASSWD: ALL" >> /etc/sudoers
    
    
    USER jenkins
    
  2. Build the Dockerfile using docker build -t jenkins-docker .

    This Dockerfile extends the official Jenkins image, by installing docker-ce, which provides the necessary tools for Jenkins to access the hosts docker socket that will be mounted into the Jenkins container.

  3. Run Jenkins

    This command utilizes my nginx+letsencrypt setup to expose Jenkins publicly, if you prefer another setup just strip the -e arguments.

docker run -d -u root \  
  --expose 8080 \
  --name jenkins \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /database/jenkins:/var/jenkins_home \
  -e VIRTUAL_HOST=jenkins.foo.bar \
  -e VIRTUAL_PORT=8080 \
  -e LETSENCRYPT_HOST=jenkins.foo.bar \
  -e LETSENCRYPT_EMAIL=foo@bar.com \
  jenkins-docker
  1. Get the initial password for Jenkins
    docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword
  2. Open https://jenkins.foo.bar in your browser

    Create your admin user using the initial password.

Create a pipeline

  1. Add a Jenkinsfile to your project
node {  
  stage("Prepare environment") {
    checkout scm
    docker.image('node:6').inside {
      stage("Install Dependencies") {
          sh "npm install"
        }
      stage("Test and validate") {
          sh "npm test"
      }
    }
  }
}
  1. Add your project repository to Jenkins