Orchestrating	Continuous	Delivery
D O C K E R 
 A N D 
 J E N K I N S .
 A L E X S O T O B 	 - 	 L O R D O F T H E J A R S . C O M
	alexsotob		lordofthejars
S O F T W A R E 
 I S 
 E A T I N G
T H E 
 W O R L D
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars

	alexsotob		lordofthejars

Faster
	alexsotob		lordofthejars

Faster
Sooner
	alexsotob		lordofthejars

Faster
Sooner
Better
	alexsotob		lordofthejars
K E Y 
 I S 
 A U T O M A T I O N
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
S P E E D 
 + 
 F R I C T I O N 
 = 
H E A T
	alexsotob		lordofthejars
G O 
 - 
 G O 
 - 
 G O
	alexsotob		lordofthejars
C O N T A I N E R S 
 C O D I F Y
O S 
 C O N F I G
	alexsotob		lordofthejars
	alexsotob		lordofthejars
$	docker	run	$	docker	run	--ti	ubuntuti	ubuntu::12.1012.10	bash	bash
[[a2ba2b]]	apt	apt--getget	update	update
[[a2ba2b]]	apt	apt--getget	install	curl	install	curl
[[a2ba2b]]	exit	exit
$	docker	commit	$	docker	commit	--m	m	"curl	installed""curl	installed"	a2b	username	a2b	username//imageimage
$	docker	build	$	docker	build	..
H O W 
 I 
 B U I L D 
 A 
 D O C K E R 
 I M A G E ?
	alexsotob		lordofthejars
J E N K I N S : 
 D O C K E R 
 A N D 
 C D
Docker
Hub
Notification:
triggers
downstream
jobs
when
a
tagged
container
is
pushed
to
Docker
Hub
	alexsotob		lordofthejars
J E N K I N S : 
 D O C K E R 
 A N D 
 C D
Docker
Hub
Notification:
triggers
downstream
jobs
when
a
tagged
container
is
pushed
to
Docker
Hub
Docker
Traceability:
identifies
which
build
pushed
a
particular
container,
displays
on
Jenkins
builds
page
	alexsotob		lordofthejars
J E N K I N S : 
 D O C K E R 
 A N D 
 C D
Docker
Hub
Notification:
triggers
downstream
jobs
when
a
tagged
container
is
pushed
to
Docker
Hub
Docker
Traceability:
identifies
which
build
pushed
a
particular
container,
displays
on
Jenkins
builds
page
Docker
Custom
Build
Environment:
specifies
customized
build
environments
as
Docker
containers
	alexsotob		lordofthejars
J E N K I N S : 
 D O C K E R 
 A N D 
 C D
Docker
Hub
Notification:
triggers
downstream
jobs
when
a
tagged
container
is
pushed
to
Docker
Hub
Docker
Traceability:
identifies
which
build
pushed
a
particular
container,
displays
on
Jenkins
builds
page
Docker
Custom
Build
Environment:
specifies
customized
build
environments
as
Docker
containers
Docker:
use
a
docker
host
to
dynamically
provision
a
slave,
run
a
single
build,
then
tear-down
	alexsotob		lordofthejars
J E N K I N S : 
 D O C K E R 
 A N D 
 C D
Docker
Hub
Notification:
triggers
downstream
jobs
when
a
tagged
container
is
pushed
to
Docker
Hub
Docker
Traceability:
identifies
which
build
pushed
a
particular
container,
displays
on
Jenkins
builds
page
Docker
Custom
Build
Environment:
specifies
customized
build
environments
as
Docker
containers
Docker:
use
a
docker
host
to
dynamically
provision
a
slave,
run
a
single
build,
then
tear-down
Build
and
Publish
:
builds
projects
that
have
a
Dockerfile
and
pushes
the
resultant
tagged
image
to
Docker
Hub
	alexsotob		lordofthejars
B U I L D , 
 T E S T , 
 & 
 D E P L O Y 
 D O C K E R 
 I M A G E
F R O M 
 J E N K I N S
	alexsotob		lordofthejars
D O C K E R 
 H U B 
 N O T I F I C A T I O N 
 P L U G I N
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
D O C K E R 
 T R A C E A B I L I T Y 
 P L U G I N
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
D O C K E R 
 P L U G I N
	alexsotob		lordofthejars
	alexsotob		lordofthejars
D O C K E R 
 C U S T O M 
 B U I L D 
 E N V I R O N M E N T
P L U G I N
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
B U I L D 
 A N D 
 P U B L I S H 
 P L U G I N
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
	alexsotob		lordofthejars
N O 
 M O R E 
B U I L D
J O B S / U P / D O W N S T R E A M S 
P L E A S E ! ! ! !
	alexsotob		lordofthejars
Continuous	Delivery	as	Code
P I P E L I N E 
 P L U G I N
	alexsotob		lordofthejars
F E A T U R E S 
 O F 
 P I P E L I N E 
 P L U G I N
Configuration
in
Source
Repositories
F E A T U R E S 
 O F 
 P I P E L I N E 
 P L U G I N
Configuration
in
Source
Repositories
Less
click-and-type,
more
code
F E A T U R E S 
 O F 
 P I P E L I N E 
 P L U G I N
Configuration
in
Source
Repositories
Less
click-and-type,
more
code
From
simple
to
complex
F E A T U R E S 
 O F 
 P I P E L I N E 
 P L U G I N
Configuration
in
Source
Repositories
Less
click-and-type,
more
code
From
simple
to
complex
Survives
Jenkins
restarts
&
connection
losses
($)
F E A T U R E S 
 O F 
 P I P E L I N E 
 P L U G I N
Configuration
in
Source
Repositories
Less
click-and-type,
more
code
From
simple
to
complex
Survives
Jenkins
restarts
&
connection
losses
($)
Reusable
Definitions
F E A T U R E S 
 O F 
 P I P E L I N E 
 P L U G I N
Configuration
in
Source
Repositories
Less
click-and-type,
more
code
From
simple
to
complex
Survives
Jenkins
restarts
&
connection
losses
($)
Reusable
Definitions
Build
history/trend
segregated
per
branches
F E A T U R E S 
 O F 
 P I P E L I N E 
 P L U G I N
Configuration
in
Source
Repositories
Less
click-and-type,
more
code
From
simple
to
complex
Survives
Jenkins
restarts
&
connection
losses
($)
Reusable
Definitions
Build
history/trend
segregated
per
branches
UI
($
->
OSS)
stage	stage	'compileAndUnit''compileAndUnit'
node	node	{{
								git	branch								git	branch::		'master''master',,	url	url::		'https://github.com/lordofthejars/starwars.git''https://github.com/lordofthejars/starwars.git'
								gradle									gradle	'clean	test''clean	test'
								stash	excludes								stash	excludes::		'build/''build/',,	includes	includes::		'**''**',,	name	name::		'source''source'
								stash	includes								stash	includes::	'build	'build//jacocojacoco/*.exec',	name:	'unitCodeCoverage'/*.exec',	name:	'unitCodeCoverage'
								step([$class:	'JUnitResultArchiver',	testResults:	'**/								step([$class:	'JUnitResultArchiver',	testResults:	'**/buildbuild//testtest--resultsresults//**..xml'xml']]))
}}
stage	stage	'codeQuality''codeQuality'
parallel	parallel	'pmd''pmd'		::		{{
				node					node	{{
								unstash									unstash	'source''source'
								gradle									gradle	'pmdMain''pmdMain'
																stepstep(([[$$classclass::		'PmdPublisher''PmdPublisher',,	pattern	pattern::		'build/reports/pmd/*.xml''build/reports/pmd/*.xml']]))
								}}
}},,		'jacoco''jacoco'::		{{
				node					node	{{
								unstash									unstash	'source''source'
								unstash									unstash	'unitCodeCoverage''unitCodeCoverage'
								gradle									gradle	'jacocoTestReport''jacocoTestReport'
								}}
}}
J E N K I N S F I L E 
 ( 1 / 3 )
	alexsotob		lordofthejars
stage	stage	'assemble-binaries''assemble-binaries'
nodenode(('linux''linux'))		{{
				unstash					unstash	'source''source'
								withEnvwithEnv(([["SOURCE_BUILD_NUMBER=${env.BUILD_NUMBER}""SOURCE_BUILD_NUMBER=${env.BUILD_NUMBER}"]]))		{{
								gradle									gradle	'assemble''assemble'
								}}
}}
input	messageinput	message::		"Deploy	Application	to	QA	?""Deploy	Application	to	QA	?"
stage	namestage	name::		'Deploy	to	QA''Deploy	to	QA',,	concurrency	concurrency::		11
node	node	{{
				echo					echo	"Application	Deployed	to	QA.""Application	Deployed	to	QA."
}}
J E N K I N S F I L E 
 ( 2 / 3 )
	alexsotob		lordofthejars
gradle	gradle	==	load		load	'jenkins/gradle.groovy''jenkins/gradle.groovy'
withCredentialswithCredentials(([[[[$$classclass::		'UsernamePasswordMultiBinding''UsernamePasswordMultiBinding',,		
																		credentialsId																		credentialsId::		'MyID''MyID',,	usernameVariable	usernameVariable::		'GIT_USERNAME''GIT_USERNAME',,		
																		passwordVariable																		passwordVariable::		'GIT_PASSWORD''GIT_PASSWORD']]]]))		{{
sh	sh	"git	tag	-a	some_tag	-m	'Jenkins'""git	tag	-a	some_tag	-m	'Jenkins'"
		sh			sh	"git	push	https://${env.GIT_USERNAME}:${env.GIT_PASSWORD}@	--tags""git	push	https://${env.GIT_USERNAME}:${env.GIT_PASSWORD}@	--tags"
}}
def	mvnHome	tool	def	mvnHome	tool	'Maven	3.3.3''Maven	3.3.3'
sh	sh	"${mvnHome}/bin/mvn	-B	verify""${mvnHome}/bin/mvn	-B	verify"
J E N K I N S F I L E 
 ( 3 / 3 )
	alexsotob		lordofthejars
D O C K E R 
 P I P E L I N E 
 I N T E G R A T I O N
dockerdocker..withRegistrywithRegistry(('https://lordofthejars-docker-continuous_delivery.bintray.io''https://lordofthejars-docker-continuous_delivery.bintray.io',,		'd4fc3fa9-39f7-47ea-a57c-795642f90989''d4fc3fa9-39f7-47ea-a57c-795642f90989'))		{{
				git					git	'git@github.com:lordofthejars/busybox.git''git@github.com:lordofthejars/busybox.git'		
				def	newApp					def	newApp	==	docker	docker..build	build	"lordofthejars-docker-continuous_delivery.bintray.io/lordofthejars/javatest:${env.BUILD_TAG}""lordofthejars-docker-continuous_delivery.bintray.io/lordofthejars/javatest:${env.BUILD_TAG}"
				newApp				newApp..pushpush(())
}}
dockerdocker..imageimage(('lordofthejars/javatest''lordofthejars/javatest'))..withRun	withRun	{{c	c	-->>
		sh			sh	'./executeTests.sh''./executeTests.sh'
}}
J E N K I N S F I L E 
 ( 1 / 2 )
	alexsotob		lordofthejars
dockerdocker..imageimage(('maven:3.3.3-jdk-8''maven:3.3.3-jdk-8'))..insideinside(('-v	~/.m2/repository:/m2repo	-u	1000:50''-v	~/.m2/repository:/m2repo	-u	1000:50'))		{{
		git			git	'…your-sources…''…your-sources…'
		sh			sh	'mvn	-Dmaven.repo.local=/m2repo	clean	install''mvn	-Dmaven.repo.local=/m2repo	clean	install'
}}
dockerdocker..withServerwithServer(('tcp://swarm.mycorp.com:2376''tcp://swarm.mycorp.com:2376',,		'swarm-certs''swarm-certs'))		{{
		docker		docker..imageimage(('httpd''httpd'))..withRunwithRun(('-p	8080:80''-p	8080:80'))		{{c	c	-->>
				sh					sh	"curl	-i	http://${hostIp(c)}:8080/""curl	-i	http://${hostIp(c)}:8080/"
				}}
}}
def	def	hostIphostIp((containercontainer))		{{
		sh			sh	"docker	inspect	-f	{{.Node.Ip}}	${container.id}	>	hostIp""docker	inspect	-f	{{.Node.Ip}}	${container.id}	>	hostIp"
				readFilereadFile(('hostIp''hostIp'))..trimtrim(())
}}
J E N K I N S F I L E 
 ( 2 / 2 )
	alexsotob		lordofthejars
	alexsotob		lordofthejars
D I F F E R E N T 
 W A Y S 
 O F 
 D O I N G 
 S A M E
T H I N G S 
 W I T H 
D S L
	alexsotob		lordofthejars
S I M P L E 
 B U I L D 
 F O R 
 P I P E L I N E 
 P L U G I N
	alexsotob		lordofthejars
simpleBuild	simpleBuild	{{
		machine			machine	==		"hi-speed""hi-speed"
		docker			docker	==		"java:1.9""java:1.9"
				
		env			env	==		[[
				FOO					FOO	::		4242,,
				BAR					BAR	::		"YASS""YASS"
				]]
				
		git_repo			git_repo	==		"https://github.com/cloudbeers/PR-demo""https://github.com/cloudbeers/PR-demo"
				
		before_script			before_script	==		"echo	before""echo	before"
		script			script	==		'echo	after	$FOO''echo	after	$FOO'
		after_script			after_script	==		'echo	done	now''echo	done	now'
				
		notifications			notifications	==		[[
				email					email	::		"foo@bar.com""foo@bar.com"
				]]
}}
J E N K I N S F I L E
	alexsotob		lordofthejars
L E T ' S 
 W I N D 

D O W N
	alexsotob		lordofthejars
C O N C L U S I O N S
Automation
is
the
Key
	alexsotob		lordofthejars
C O N C L U S I O N S
Automation
is
the
Key
Docker
Simplifies
Environment
Problems
	alexsotob		lordofthejars
C O N C L U S I O N S
Automation
is
the
Key
Docker
Simplifies
Environment
Problems
Jenkins
is
Ready
For
Docker
and
CD
	alexsotob		lordofthejars
C O N C L U S I O N S
Automation
is
the
Key
Docker
Simplifies
Environment
Problems
Jenkins
is
Ready
For
Docker
and
CD
Pipleline
as
Code
gives
you
Freedom
	alexsotob		lordofthejars
O N L Y 
 O N E 
 P I E C E 
 O F 
 T H E 
 J I G S A W
	alexsotob		lordofthejars
F O L L O W 
 T H E 
 R U L E S , 
 A D A P T 
 T O 
 Y O U R
N E E D S
	alexsotob		lordofthejars

C L O U D B E E S
J E N K I N S
It	is	not	necessary	to	change.	
Survival	is	not	mandatory.
W . 
 E D W A R D S 
 D E M I N G
	alexsotob		lordofthejars
Q U E S T I O N S
	alexsotob		lordofthejars

http://www.slideshare.net/asotobu/jenkins-docker

asotobu@gmail.com
	alexsotob		lordofthejars
https://github.com/lordofthejars/starwars
https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Plugin
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Pipeline+Plugin
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Traceability
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Build+and+Publish+plugin
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Hub+Notification
https://wiki.jenkins-ci.org/display/JENKINS/Docker+Plugin
https://github.com/jenkinsci/simple-build-for-pipeline-plugin

Jenkins Docker