CONTROLLED DATA
Leidos Proprietary - US Citizens ONLY
The information contained herein is proprietary to Leidos, Inc. It may not be used, reproduced, disclosed, or exported without the written approval of Leidos.

Builds executed with Bamboo in the SDO environment must be configured to use a per build container (PBC). The PBC is actually a Docker image that is pulled from Artifactory and is executed within a Kubernetes pod. The PBC provides for build isolation and full control by a project, effectively decoupling the specific project build concerns from the SDO environment. These project-specific PBCs are themselves a product of a PBC build pipeline that is hosted by a Docker PBC Build Agent provided by SDO. Projects therefore will typically create a build plan in Bamboo to generate these PBC images. Once a project-specific PBC is created, it must go through a code review and Xray scan before it can be migrated to the SDO Docker repository where it can be used in subsequent project-specific build plans.

Step-by-step guide

Identify an agent with the correct capabilities required to execute your build. If one does not exist, you may need to generate a new build agent. An example build agent that includes a Java, Gradle and NodeJS is included here. Note also that all project-specific PBCs must inherit from sdo-docker-public.artifactory.sdo.leidos.com/bamboo-agent-base-6.6.3:<TAG>

Gradle and NodeJS Build Agent Example
FROM sdo-docker-public.artifactory.sdo.leidos.com/bamboo-agent-base-6.6.3:3.0.0

ARG GRADLE=gradle-5.5.1
ARG NODEJS=node-v12.14.0-linux-x64

ENV GRADLE_BIN=${GRADLE}-bin.zip
ENV GRADLE_HOME=/opt/gradle

ENV NODEJS_BIN=${NODEJS}.tar.xz
ENV NODEJS_HOME=/opt/node

# NPM requires NODE to be on path.
ENV PATH=$PATH:${NODEJS_HOME}/bin

USER root

# Update and install required packages
RUN apt-get -y update && \
	apt-get -y upgrade && \
	apt-get -y install \
		openjdk-11-jdk-headless \
		tar \
		xz-utils \
		zip \
		unzip \
		curl && \
	apt-get autoremove && \
	apt-get clean && \
	rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Resources
COPY ${GRADLE_BIN} ${NODEJS_BIN} ./

# Gradle
RUN unzip ./${GRADLE_BIN} -d /opt && \
	ln -s /opt/${GRADLE} ${GRADLE_HOME}  && \
	rm -f ./${GRADLE_BIN}

# NodeJS
RUN tar -xf ./${NODEJS_BIN} --directory /opt && \
	ln -s /opt/${NODEJS} ${NODEJS_HOME}  && \
	rm -f ${NODEJS_BIN}

# Permissions
RUN chown -R root:${BAMBOO_GROUP} /opt && \
	chmod -R 774 /opt

# Bamboo capabilities
RUN mkdir /buildeng-custom && \
	#JDK 8 (included in base image) capability
	echo '/buildeng/bamboo-update-capability "system.jdk.JDK 1.8" "/usr/lib/jvm/java-8-openjdk-amd64"' >> /buildeng-custom/setup.sh && \
	#JDK 11 capability
	echo '/buildeng/bamboo-update-capability "system.jdk.JDK 1.11" "/usr/lib/jvm/java-11-openjdk-amd64"' >> /buildeng-custom/setup.sh && \
	#Gradle
	echo "/buildeng/bamboo-update-capability \"system.builder.gradle.${GRADLE}\" \"${GRADLE_HOME}\"" >> /buildeng-custom/setup.sh && \
	#NodeJS
	echo "/buildeng/bamboo-update-capability \"system.builder.node.Node.js 12.14.0\" \"${NODEJS_HOME}/bin/node\"" >> /buildeng-custom/setup.sh && \
	#CL capabilities
	echo '/buildeng/bamboo-update-capability "system.builder.command.bash" "/bin/bash"' >> /buildeng-custom/setup.sh && \
	echo '/buildeng/bamboo-update-capability "system.builder.command.echo" "/bin/echo"' >> /buildeng-custom/setup.sh && \
	echo '/buildeng/bamboo-update-capability "system.builder.command.curl" "/usr/bin/curl"' >> /buildeng-custom/setup.sh

USER ${BAMBOO_USER}


Dockerfile Best-Practices

There are several best-practices that have emerged when building a docker build agent image from a Dockerfile for Bamboo.

  1. Inherit from sdo-docker-public.artifactory.sdo.leidos.com/bamboo-agent-base-6.6.3:<TAG>. This base image provides the minimum capabilities required to interface with Bamboo. It also includes Java 8 and Git. Moreover, it guarantees that all Debian package resolution is done securely through the internal Leidos Debian repositories.
  2. Do not run the container as root, use the ${BAMBOO_USER} instead. See example above.
  3. Do not use the ARG command to pass in credentials. Credentials passed in this way will show up in clear text when the Docker image history command is used.
  4. Limit the number of RUN, ADD and COPY commands. Each of these commands creates a new Docker layer and significantly increases the size of an image. There is typically a trade-off between the number of these commands, cohesion and readability. See example above for a reasonable balance of these factors.
  5. Use the 'headless' JDK versions whenever possible. This will also greatly reduce the size of images. PBC builds are non-interactive, therefore the interactive UI support afforded by 'full' JDKs is typically not needed. Note that this refers to interaction with the JDK itself and not the core JDK UI libraries. The 'headless' JDKs include AWT and Swing.
  6. Make sure to use versions of build tools that do not bundle documentation and code examples, such as gradle-x.y.z-all. Use gradle-x.y.x-bin instead. This will also significantly reduce the size of images.
  7. When building a PBC use the JFrog CLI to download build resources from Artifactory. Do not use 'curl' or 'wget'. The JFrog CLI is a capability of the Docker PBC Build Agent provided by SDO that will host a PBC build. See How to Use the Bamboo PBC Build Agent Template.
  8. The bamboo 'capability' system is required to map the capabilities in Bamboo to what is actually provided on the PBC agent. See https://confluence.atlassian.com/bamkb/list-of-default-keys-for-the-bamboo-capabilities-properties-file-946025256.html. It may take a number of iterations to work out any new capability strings. These new capabilities will require administration of Bamboo. Contact the SDO Service Desk for assistance in working through these issues.