}}

Customizing your Docker container

Stable Updated: January 17, 2017

About customizing your Docker container

By default, Mesosphere DC/OS runs everything inside Docker containers to minimize dependencies on the underlying host operating system and to offer resilience in the event of a machine failure. When using Jenkins for DC/OS, the underlying Mesos scheduler in DC/OS creates new Jenkins agents that run as Mesos tasks within a Docker container. User-configured builds are then run inside the same container.

Because builds typically have steps that invoke the Docker utility, such as docker build or docker push, we provide the mesosphere/jenkins-dind Docker image and configure Jenkins for DC/OS to use this by default. The mesosphere/jenkins-dind image also includes several other well-known tools. For a complete list, see the Dockerfile.

If you have dependencies to specify for your applications and environment, you can create custom Docker images for your Jenkins build agents with your environment-specific packages and configurations. Below, you’ll find several common scenarios and a recipe for each. After your new Docker image is built, you can then push it to Docker Hub or your own private Docker registry. This registry must be accessible by each of the DC/OS agents.

At a minimum, a custom agent requires the following packages:

  • OpenJDK 8: Required by Jenkins to launch the agent and register with the master.
  • CA certificates: Required to verify SSL/TLS certificates.

Additionally, you might also want these commonly-used packages:

  • Bash: Required by many Jenkins build scripts.
  • Git: Popular version control system.
  • OpenSSH client: Required to clone Git repositories via SSH.

Creating a new image based on mesosphere/jenkins-dind

To provide your own dependencies, we recommend extending the provided jenkins-dind image and install your required packages.

This example shows how to create an image which includes sbt, a Scala build tool (this code snippet is based on docker-sbt):

FROM mesosphere/jenkins-dind:0.2.2

ENV SBT_VERSION 0.13.8
ENV SBT_HOME /usr/local/sbt
ENV PATH ${PATH}:${SBT_HOME}/bin

RUN curl -sL "http://dl.bintray.com/sbt/native-packages/sbt/$SBT_VERSION/sbt-$SBT_VERSION.tgz" 
    | gunzip | tar -x -C /usr/local && echo -ne "- with sbt $SBT_VERSIONn" >> /root/.built

Modifying the SSH host keys

By default, Velocity includes the SSH public keys used by GitHub. If you aren’t using GitHub to host your Git repositories and you want to use SSH when cloning your Git repositories, you must add your Git server’s SSH public keys to /etc/ssh/ssh_known_hosts. You can do this by appending these lines to your Dockerfile:

    ENV SSH_KNOWN_HOSTS github.com my.git.server
    RUN ssh-keyscan $SSH_KNOWN_HOSTS | tee /etc/ssh/ssh_known_hosts

Configuring Jenkins

After the image is created and available on Docker Hub or your private Docker registry, you must configure Jenkins to make this image available in your job configurations.

  1. From the Jenkins web interface, navigate to the Manage Jenkins page, and then to the Configure Jenkins page.

  2. Scroll to the Cloud section at the bottom and click Advanced. You should see a grey button to Add Slave Info.

  3. On the Add Slave Info page, set values based on the needs of your particular job or application. Some options include:

    • Label string. Specify a label for the Jenkins agent. This will be referenced in any jobs that make use of this image.
    • Usage. Leave this as the default, “Utilize this node as much as possible.”
    • Jenkins slave CPUs. The CPU shares consumed by a single agent.
    • Jenkins slave memory in MB. The memory consumed by a single agent.
    • Maximum number of executors per slave. Number of Jenkins executors that will exist within a single container.
    • Jenkins executor CPUs. The CPU shares given to each executor within the container (estimated).
    • Jenkins executor memory. The memory given to each Jenkins executor within the container (estimated).

    Note: The actual resources available to the Jenkins agent are calculated using the following formulas. Use these to create your estimates when you configure the agent’s CPUs and memory.

    actualCpus = slaveCpus + maxExecutors * executorCpus
    actualMem = slaveMem + maxExecutors * executorMem
    

  4. To configure this Jenkins agent with a custom Docker image, click Advanced again and select the Use Docker Containerizer checkbox. Here you can specify the Docker Image name.

    Note: If you’re creating a new Docker-in-Docker image, be sure to select Docker Privileged Mode and specify a custom Docker command shell.

  5. Click Save.

Configuring your Jenkins job to use the new agent

  1. To configure a build to use the newly specified image, click on Configure for the build, select Restrict where this project can be run, and specify the same Label String.

  2. Click Save.