This presentation describes how to deploy a Spring Boot-based microservice using Docker.
See http://plainoldobjects.com/2014/11/16/deploying-spring-boot-based-microservices-with-docker/
Cybersecurity Challenges with Generative AI - for Good and Bad
Deploying Spring Boot applications with Docker (east bay cloud meetup dec 2014)
1. @crichardson
Deploying Spring Boot
applications with Docker
Chris Richardson
Author of POJOs in Action
Founder of the original CloudFoundry.com
@crichardson
chris@chrisrichardson.net
http://plainoldobjects.com
http://microservices.io
4. @crichardson
About Chris
Founder of a buzzword compliant (stealthy, social, mobile, big
data, machine learning, ...) startup
Consultant helping organizations improve how they architect
and deploy applications using cloud, micro services, polyglot
applications, NoSQL, ...
Creator of http://microservices.io
Organizer of @oakjug - http://bit.ly/ebjava
Co-organizer of http://meetup.com/oakland-scala
8. @crichardson
Building microservices with
Spring Boot
Makes it easy to create stand-alone, production ready
Spring applications
Automatically configures Spring using Convention over
Configuration
Externalizes configuration
Generates standalone executable JARs with embedded
web server
Provides a standard foundation for
all your microservices
9. @crichardson
Spring Boot simplifies configuration
Spring
Container
Application
components
Fully
configured
application
Configuration
Metadata
•Typesafe JavaConfig
•Annotations
•Legacy XML
Default
Configuration
Metadata
Spring
Boot
You write less
of this
Inferred from
CLASSPATH
11. @crichardson
About auto-configuration
Builds on Spring framework features
@EnableAutoConfiguration - triggers the inclusion of default
configuration
@Conditional - beans only active if condition is satisfied
Conditional on class defined on class path
e.g. Mongo Driver implies Mongo beans
Conditional on bean defined/undefined
e.g. define Mongo beans if you haven’t
14. @crichardson
Running the microservice
$ java -jar build/libs/spring-boot-restful-service.jar --server.port=8081
...
2014-12-03 16:32:04.671 INFO 93199 --- [ main]
n.c.m.r.main.UserRegistrationMain$ : Started UserRegistrationMain. in 5.707
seconds (JVM running for 6.553)
$ curl localhost:8081/health
{"status":"UP",
"mongo":{"status":"UP","version":"2.4.10"},
"rabbit":{"status":"UP", ...}
}
Built in health checks
Command line arg processing
16. @crichardson
Spring Boot simplifies
deployment
Spring Boot creates self-contained JAR file
No separate application server to install/configure
Externalize configuration = immutable application
Just need Java
But which version of Java? 7.x? 8.y?
And, what about the other applications?
Tomcat, Play, NodeJS, ...
Deploying a system is complex
17. @crichardson
Package service as an RPM
Benefits:
Encapsulates language, framework, application server, ...
Handles dependencies
...
But
Conflicting dependency versions
Conflicting ports, ...
20. @crichardson
Service-as-AMI is great BUT...
Building is so slow!
Booting is so slow!
AMIs aren’t portable - need to build for multiple platforms
Heavy-weight: Not practical to run multiple VMs on a
developer machine
...
21. @crichardson
Package a service as a
Docker image
Lightweight, OS-level virtualization mechanism
Runs on Linux (directly or via, e.g., Virtual Box)
Docker image:
Portable application packaging format
Self-contained, read-only file-system image of an operating system + application
Layered structure = sharing and caching very, very fast
5 seconds to package application!
Docker container:
Running Docker image
Group of sandboxed processes
Builds on control groups and namespaces
Contains entire OS but typically the only process is the application (JVM) fast startup
https://www.docker.com/
23. @crichardson
Packaging a Spring Boot
application as a Docker image
Install Java
Install application JAR file
Configure image to run Java on startup
Handle externalized configuration
25. @crichardson
Dockerfile for packaging a
Spring Boot application
Base
image
Copy JAR
into image
/data is base image’s CWD
Expose 8080
Bonus question: why is the ADD command last?
26. @crichardson
Building the Spring Boot
application copy jar to subdir so it can be
referenced by Dockerfile
Build image using ./Dockerfile
27. @crichardson
Running the Spring Boot
container
docker
run
-‐d
-‐p
8080:8080
-‐e
SPRING_DATA_MONGODB_URI=mongodb://192.168.59.103/userregistration
-‐e
SPRING_RABBITMQ_HOST=192.168.59.103
-‐-‐name
sb_rest_svc
sb_rest_svc
Map container port
to host port
Run as
daemon
Container
name
Image name
Specify environment
variables
31. @crichardson
Smoke testing docker images
Smoke test
Docker
daemon
Service
containerGET /health
POST /containers/create
creates
POST /containers/{id}/start
Docker daemon must listen on
TCP port
32. @crichardson
Publishing Docker images
docker tag service-${VERSION}:latest
${REGISTRY_HOST_AND_PORT}/service-${VERSION}
docker push ${REGISTRY_HOST_AND_PORT}/service-${VERSION}
docker/publish.sh
Pushing only takes 25
seconds!
33. @crichardson
CI environment runs on
Docker
EC2 Instance
Jenkins
Container
Artifactory
container
EBS volume
/jenkins-
home
/gradle-home
/artifactory-
home
34. @crichardson
Updating production
environment
Large EC2 instance running Docker
Deployment tool:
1. Compares running containers with what’s been built by Jenkins
2. Pulls latest images from Docker registry
3. Stops old versions
4. Launches new versions
One day: use Docker clustering solution and a service discovery mechanism,
Most likely, AWS container service
Mesos and Marathon + Zookeeper, Kubernetes or ???