This presentation was given at Oakjug.
Describes why Spring Boot is an excellent choice for building microservices.
Talks about the various ways that Docker can simplify development and deployment.
Discusses how docker-compose makes the life of a developer easier.
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Developing and deploying applications with Spring Boot and Docker (@oakjug)
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
6. @crichardson
Agenda
Introduction to Spring Boot
Why immutable infrastructure/containerization
Spring Boot and Docker
Using Docker Compose to deploy infrastructure
Using Docker Compose to launch your application
Docker-based deployment pipeline
9. @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
10. @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
12. @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
15. @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
Agenda
Introduction to Spring Boot
Why immutable infrastructure/containerization
Spring Boot and Docker
Using Docker Compose to deploy infrastructure
Using Docker Compose to launch your application
Docker-based deployment pipeline
17. @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
18. @crichardson
Package service as an RPM
Benefits:
Encapsulates language, framework, application server, ...
Handles dependencies
...
But
Conflicting dependency versions
Conflicting ports, ...
21. @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
...
22. @crichardson
Package a service as a
Docker image
Lightweight, OS-level virtualization mechanism
Runs on Linux
directly
via, e.g., Virtual Box
https://www.docker.com/
23. @crichardson
Docker images
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!
24. @crichardson
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
25. Boot2docker
Docker on the Mac (and
Windows)
Runs Docker in a small
VirtualBox VM
http://boot2docker.io/
Shares /User with VM
26. @crichardson
Agenda
Introduction to Spring Boot
Why immutable infrastructure/containerization
Spring Boot and Docker
Using Docker Compose to deploy infrastructure
Using Docker Compose to launch your application
Docker-based deployment pipeline
27. @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
29. @crichardson
FROM java:openjdk-8u45-jdk
MAINTAINER chris@chrisrichardson.net
EXPOSE 8080
CMD java -jar spring-boot-restful-service.jar
ADD build/spring-boot-restful-service.jar .
Dockerfile for packaging a
Spring Boot application
Base image
Copy JAR into image
Expose 8080
Bonus question: why is the ADD command last?
Startup command
30. @crichardson
Building the Spring Boot
application
copy jar to subdir so it can be
referenced by Dockerfile
Build image using ./Dockerfile
31. @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
32. @crichardson
Testing the REST API
$
curl
-‐v
-‐d
'{"emailAddress":
"foo@bar.com"}'
-‐H
"content-‐type:
application/json"
http://${DOCKER_HOST_IP}:8080/user
{"id":"5561f726e4b0b15173726b96","emailAddress":"foo@bar.com"}
33. @crichardson
Agenda
Introduction to Spring Boot
Why immutable infrastructure/containerization
Spring Boot and Docker
Using Docker Compose to deploy infrastructure
Using Docker Compose to launch your application
Docker-based deployment pipeline
34. @crichardson
Problem
Typical application needs a database
Many apps also need a message broker
Other projects need even more than that
Zookeeper, Kafka, DynamoDB
Making sure every developer installs the correctly version =
PITA
37. @crichardson
Using shell scripts
$
docker
run
-‐d
-‐p
5672:5672
-‐p
15672:15672
-‐-‐name
rabbitmq
dockerbile/
rabbitmq
$
docker
run
-‐d
-‐p
27017:27017
-‐-‐name
mongodb
dockerbile/mongodb
mongod
-‐-‐
smallbiles
Not bad but we can do better!
38. @crichardson
About Docker Compose
Tool for defining and running an application consisting of
multiple docker containers
Create a docker-compose.yml
Declarative system definition
Commands to start, stop, and remove containers
https://docs.docker.com/compose/
40. @crichardson
Using Docker Compose
$
docker-‐compose
up
-‐d
Recreating
docker_mongodb_1...
Recreating
docker_rabbitmq_1...
$
docker-‐compose
stop
Stopping
docker_rabbitmq_1...
Stopping
docker_mongodb_1...
$
docker-‐compose
rm
Going
to
remove
docker_rabbitmq_1,
docker_mongodb_1
Are
you
sure?
[yN]
y
Removing
docker_mongodb_1...
Removing
docker_rabbitmq_1...
41. @crichardson
Agenda
Introduction to Spring Boot
Why immutable infrastructure/containerization
Spring Boot and Docker
Using Docker Compose to deploy infrastructure
Using Docker Compose to launch your application
Docker-based deployment pipeline
48. @crichardson
Agenda
Introduction to Spring Boot
Why immutable infrastructure/containerization
Spring Boot and Docker
Using Docker Compose to deploy infrastructure
Using Docker Compose to launch your application
Docker-based deployment pipeline
51. @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
52. @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!
53. @crichardson
CI environment runs on
Docker
EC2 Instance
Jenkins
Container
Artifactory
container
EBS volume
/jenkins-
home
/gradle-home
/artifactory-
home
54. @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 ???
55. @crichardson
Summary
Spring Boot is a great way to build Spring-based
microservices
Docker is a great way to package microservices
Docker-compose is a super useful development tool