Public | Automated Build

Last pushed: a year ago
Short Description
CentOS 6.7 based Customizable Jenkins Container - Updated 12/27/2015
Full Description

CentOS 6.7 based Customizable Jenkins Container - 494 MB - Updated 12/27/2015

This container is built from centos:6.7

Description:

Jenkins is a web-based super extendable Continuous Integration framework.

Jenkins is the leading open source automation server. Built with Java, it provides hundreds of plugins to support building, testing, deploying and automation virtually any project

Official Jenkins Website:

This containers purpose is to get a customizable Jenkins instance up and running with a single docker run statement. The container is built with environment variables that allow the user to plug in custom values which will allow the container to configure itself on first run. This will give the user a fully customized experience just as if you set up Jenkins on your own from scratch.

THIS SERVER CREATES A NEW SSH KEY ON FIRST LAUNCH. IT IS ADVISABLE THAT THE GENERATED KEY CONTAINED IN /VAR/LIB/JENKINS/.SSH BE BACKED UP IF IT IS GOING TO BE DEPLOYED TO OTHER SERVERS. !!!:

On first boot (Jenkins Head/and Slave), a process checks to see if an SSH key for remote host connections exits in /var/lib/jenkins/.ssh. If a key already exists, then the server will use that key, if one does on does not exist it will generate a new key automatically. It will then copy that key and the public key cat'ed into the authorized_hosts to the /var/lib/jenkins_slave directory, which should be a shared volume that any slave nodes can attach to copy it to the jenkins user home directory. It is important that if a new key is created, that it is backed up, as it will be used for all jenkins servers.

 

Container Variables:

The container is built to allow several configurable variables to be passed in at run time. The values are as follows:

  • ROLE - Toggle that tells the container to be a jenkins head server or a jenkins slave. ROLE set to any other value, such as slave, will uninstall the jenkins executable upon execution.
  • SSH_PASS - Sets the jenkins user password so that you can ssh to the box via the jenkins user. Default = jenkins123
  • ENV - Variable to hold the environment, currently it serves no other purpose but is there in case its needed
  • TERMTAG - Environment variable to hold the highlighted bash shell tag. Currently set to the repo name, but can be change from within the container via TERMTAG="Whatever You Want"

 

ROLE VALUES:

  • Master - Run the Jenkins War File. This option creates a Jenkins Head server. This is the default setting.
  • Slave - This will uninstall Jenkins and turn the server into a bare bones jenkins slave, including the keys allowing the head server to connect to the slaves properly.

 

Running the Container as STANDALONE:

docker run -it \
--name jenkins-data \
-h jenkins-data \
-v /var/lib/jenkins \
-v /var/lib/jenkins_slave_key \
-e ROLE slave \
-e TERMTAG JENKINS-DATA
sciquest/jenkins

docker run -it \
--name jenkins \
-h jenkins \
restart: always \
--volumes-from jenkins-data \
-p 8080:8080 \
-e TERMTAG JENKINS \
sciquest/jenkins

This will assume the following

  • ROLE - Master
  • SSH_PASS - jenkins123
  • ENV - dev

Note: If you want to run jenkins slaves, then you will want to set up the slaves first, and the head server last so that you can provide linking if you so desire to ensure the head server can properly communicate with the slaves.

Note: This will set the /var/lib/jenkins directory on the jenkins-data volume to be the saved location where the jenkins head server will keep all of its configuration data. Jenkins is a database-less application, and its entire config is stored within this directory.

 

Running the Container with slaves:

Start a data only containers to hold jenkins ssh keys

docker run -it \
--name jenkins-keys \
-h jenkins-keys \
-v /var/lib/jenkins_slave_key \
-e ROLE slave \
-e TERMTAG "JKEY-DATA" \
sciquest/jenkins \
sleep 1

RUN a Second data only container to hold jenkins config data

docker run -it \
--name jenkins-data \
-h jenkins-data \
--volumes-from jenkins-keys \
-v /var/lib/jenkins \
-e ROLE slave \
-e TERMTAG JENKINS-DATA \
sciquest/jenkins \
sleep 1

Start up a Docker Slave

docker run -it -d \
--restart always \
--name docker-slave \
--volumes-from jenkins-keys \
-h docker-slave \
-e ROLE slave \
-e TERMTAG DOCKERSLAVE \
-v /var/run/docker.sock:/var/run/docker.sock \
sciquest/jenkins

Start up the Jenkins Head Server

docker run -it \
--restart always \
--name jenkins \
-h jenkins \
--volumes-from jenkins-keys \
--volumes-from jenkins-data \
-p 8080:8080 \
--link docker-slave:docker-slave \
-e TERMTAG JENKSINS \
sciquest/jenkins

Note: This process will start the first container being a data-only volume set in slave mode. Because iniitally no SSH keys exist in either /var/lib/jenkins/.ssh (jenkins user home) or the /var/lib/jenkins_slave_key directories, the server will create a new 2048 bit SSH key and save it to both the /var/lib/jenkins/.ssh direcory as well as the /var/lib/jenkins_slave_key directories. This operation is done at the first run of the contaienr, as to ensure that the key that is used in your Jenkins setup are unique to you, and not passed with the container to anyone pulling and running the public container. We launched this first container as a data volume flagging the /var/lib/jenkins_slave_key directory as a shared volume.

The second container that we launch will hold the config data for jenkins, and will also be a persistent volume container flagging /var/lib/jenkins as the data volume. It will kick off and check both the local /var/lib/jenkins/.ssh directory as well as the now mounted /var/lib/jenkins_slave_key directories for the id_rsa key. Because the first key container generated a key and stored it in /var/lib/jenkins_slave_key, the data container will see that a key exists in /var/lib/jenkins_slave_key and will copy that keyfile to /var/lib/jenkins/.ssh. It will also copy a config file that contains no host checking (no prompt connecting to new servers which will kill jenkins jobs), as well as an authorized_keys file which contains the public key for the generated private key. The purpose of this file is to ensure that slaves are automatically authorized so that we can install the slave war file on them, as well as running jenkins jobs on them. Jenkins has a database-less configuration, meaning that the entire configuration is stored in XML file format in the /var/lib/jenkins directory. It is VERY important that if anything else gets lost, that this directory is backed up and recoverable. It contains configuation, as well as all of your jenkins jobs.

Note: These containers are fired off with the command of sleep 1, as the containers do not need to be running for other containers mapped to its persistant volume to have access to the data in said volume.

This rest of this example will run a simple docker slave / master set up, the slave container simply runs a shell container, that is able to talk directly to the docker socket, so that docker commands can be issued against it. Note that on setup, its a shell container meaning that the slave needs to have it operative necessary bits installed. So in order for the docker-slave to be ready for docker tasks, docker will need to be installed first (This can be done after the environment is up and running). The slave however is linked to the key-data container, which will allow the container on run to check the /var/lib/jenkins_slave_key location on the key volume container for an existing key (which now should exist), and copy that key to the /var/lib/jenkins/.ssh/authorized_key file. This will allow the head server to communicate with the slave via SSH. The last container in the stack is the head server, again using volumes from both the jenkins key volume container, and the jenkins data volume container. This will allow the container to use the key generated and distributed by the key volume container, as well as having all of its data stored on the data volume container, allowing the ability for the entire jenkins head server to be removed at any time upgraded swapped. As long as the data volume data is in tact, the head server container is not important as it locally stores no data, but just runs the jenkins services. The container is also lined to the docker slave, and can be set to talk to the slave via the FQDN of docker-slave. (This will be needed in Manage Jenkins --> Nodes when setting up the slave node).

Note: Once all of the above has been performed, you will need to access jenkins via a web browser using port 8080, go to Manage Jenkins, then Manage Nodes. You will have to walk through the process to tell the Jenkins head server to use the slave as a slave. Assign the slave a tag, and then within the job, restrict the job to run on hosts with that tag.

 

Launching the Container via docker-compose as STANDALONE:

Copy the text below and paste it into a file named docker-compose.yml. Then you can navigate to the directory and if you have docker-compose installed, just issue the following command:
docker-compose up -d

data:
  image: sciquest/jenkins
  hostname: jenkins-data
  stdin_open: true
  tty: true
  volumes:
  - /var/lib/jenkins
  - /var/lib/jenkins_slave_key
  environment:
  - ROLE=slave
  - SSH_PASS=jenkinspassword
  command: sleep 1

web:
  image: sciquest/jenkins
  hostname: jenkins
  stdin_open: true
  tty: true
  restart: always
  ports:
  - "8080:8080"
  environment:
  - ROLE=master
  - SSH_PASS=jenkinspassword
  volumes_from:
  - data
  command: /bin/bash

Launching the Container via docker-compose with slaves:

Copy the text below and paste it into a file named docker-compose.yml. Then you can navigate to the directory and if you have docker-compose installed, just issue the following command:
docker-compose up -d

keydata:
  image: sciquest/jenkins
  hostname: jenkins-keys
  stdin_open: true
  tty: true
  volumes:
  - /mnt/docker/volumes/jenkins_key:/var/lib/jenkins_slave_key
  environment:
  - ROLE=slave
  - SSH_PASS=jenkinspassword
  - TERMTAG=KEYDATA
  command: /bin/bash  

data:
  image: sciquest/jenkins
  hostname: jenkins-data
  stdin_open: true
  tty: true
  volumes_from:
  - keydata
  volumes:
  - /mnt/docker/volumes/jenkins:/var/lib/jenkins
  environment:
  - ROLE=slave
  - SSH_PASS=jenkinspassword
  - TERMTAG=JENKINS-DATA
  command: /bin/bash

docker:
  image: sciquest/jenkins
  hostname: docker-slave
  stdin_open: true
  tty: true
  restart: always
  privileged: true
  environment:
  - ROLE=slave
  - SSH_PASS=jenkinspassword
  - TERMTAG=DOCKERSLAVE
  volumes_from:
  - keydata
  volumes:
  - /var/run/docker.sock:/var/run/docker.sock
  command: /bin/bash

maven:
  image: sciquest/jenkins
  hostname: maven-slave
  stdin_open: true
  tty: true
  restart: always
  volumes_from:
  - keydata
  environment:
  - ROLE=slave
  - SSH_PASS=jenkinspassword
  - TERTAG=MAVENSLAVE
  command: /bin/bash

rpmbuild:
  image: sciquest/jenkins
  hostname: rpm-slave
  stdin_open: true
  tty: true
  restart: always
  volumes_from:
  - keydata
  environment:
  - ROLE=slave
  - SSH_PASS=jenkinspassword
  - TERTAG=RPMSLAVE
  command: /bin/bash

head:
  image: sciquest/jenkins
  hostname: jenkins
  stdin_open: true
  tty: true
  restart: always
  ports:
  - "8080:8080"
  environment:
  - ROLE=master
  - SSH_PASS=jenkinspassword
  - TERMTAG=JENKINS
  volumes_from:
  - keydata
  - data
  links:
  - docker
  - maven
  - rpmbuild
  command: /bin/bash

Slave Setup Examples:

Setting up the Docker Slave:

docker attach docker_slave
yum install -y docker-io
gpasswd -a jenkins docker

# Add the following to /etc/sudoers:  
jenkins ALL=(ALL) NOPASSWD: ALL

Setting up the NodeJS Slave:

docker attach node_slave
yum install -y git npm ant ant-contrib ant-nodeps gettext rpm-build
npm install -g node node-devel
npm install -g bower
npm install jscpd -g
npm install jshint -g

Setting up the Maven Slave:

docker attach maven_slave
yum install -y ant ant-contrib ant-nodeps gettext rpm-build maven
cd /tmp
wget http://mirror.symnds.com/software/Apache/maven/maven-3/3.3.1/binaries/apache-maven-3.3.1-bin.tar.gz
tar -xzvf apache-maven-3.3.1-bin.tar.gz
mv apache-maven-3.3.1 /usr/local/
export PATH=$PATH:/usr/local/apache-maven-3.3.1/bin/
export MAVEN_OPTS="-Xms256m -Xmx512m"

Configure VMs/Bare Metal Servers to allow Jenkins to Deploy:

useradd jenkins; groupadd jenkins
usermod -u 499 jenkins
usermod -G jenkins jenkins
groupmod -g 499 jenkins
chown -R jenkins:jenkins /home/jenkins
su jenkins
cd /home/jenkins; mkdir .ssh; chmod 0700 .ssh; cd .ssh

# REPLACE THIS KEY WITH YOUR OWN KEY..

echo "ssh-rsa BBBB3NzaC1yc2EAAAADAQABA... REST OF KEY jenkins" >> /home/jenkins/.ssh/authorized_keys
chmod 0600 /home/jenkins/.ssh/authorized_keys

# Add the following to /etc/sudoers:
jenkins ALL=(ALL) NOPASSWD: ALL

Full container documentation can be found here

Docker Pull Command
Owner
sciquest
Source Repository