Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Developing and deploying applications with Spring Boot and Docker (@oakjug)

19,081 views

Published on

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.

Published in: Software
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

Developing and deploying applications with Spring Boot and Docker (@oakjug)

  1. 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
  2. 2. @crichardson Presentation goal Deploying Spring-based microservices using Docker
  3. 3. @crichardson About Chris
  4. 4. @crichardson About Chris Founder of a startup that’s creating a platform for developing event-driven microservices (http://bit.ly/trialeventuate)
  5. 5. @crichardson For more information https://github.com/cer/event-sourcing-examples https://github.com/cer/microservices-examples http://microservices.io http://plainoldobjects.com/ https://twitter.com/crichardson
  6. 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
  7. 7. @crichardson User registration microservices User Registration Service RabbitMQ MongoDB POST /user { emailAddress: "foo@bar.com", password: "xyz" } NewUserNotification User Management Service Email Service Exchange Queue Queue User Registration Web App Registration Form Confirmation page http://plainoldobjects.com/category/spring-boot/
  8. 8. @crichardson Spring-based components
  9. 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. 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
  11. 11. @crichardson Tiny Spring configuration Scan for controllers Customize JSON serialization
  12. 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
  13. 13. @crichardson The Main program
  14. 14. @crichardson Building with Gradle buildscript { repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.1.8.RELEASE") } } apply plugin: 'scala' apply plugin: 'spring-boot' dependencies { compile "org.springframework.boot:spring-boot-starter-web" compile "org.springframework.boot:spring-boot-starter-data-mongodb" compile "org.springframework.boot:spring-boot-starter-amqp" compile "org.springframework.boot:spring-boot-starter-actuator" testCompile "org.springframework.boot:spring-boot-starter-test" } ... Ensures correct dependencies
  15. 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. 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. 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. 18. @crichardson Package service as an RPM Benefits: Encapsulates language, framework, application server, ... Handles dependencies ... But Conflicting dependency versions Conflicting ports, ...
  19. 19. @crichardson Let’s have immutable infrastructure
  20. 20. @crichardson Package as AMI http://boxfuse.com/learn/why.html packer.io, github.com/Netflix/aminator cloudnative.io
  21. 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. 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. 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. 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. 25. Boot2docker Docker on the Mac (and Windows) Runs Docker in a small VirtualBox VM http://boot2docker.io/ Shares /User with VM
  26. 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. 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
  28. 28. @crichardson Docker and Java https://registry.hub.docker.com/_/java/
  29. 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. 30. @crichardson Building the Spring Boot application copy jar to subdir so it can be referenced by Dockerfile Build image using ./Dockerfile
  31. 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. 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. 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. 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
  35. 35. @crichardson A couple of years ago Vagrant was the cool way to do this VM s are so yesterday!
  36. 36. @crichardson Using Docker is easier and much more efficient
  37. 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. 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/
  39. 39. @crichardson Docker-compose.yml rabbitmq:      image:  dockerbile/rabbitmq      ports:          -­‐  "5672:5672"          -­‐  "15672:15672"   mongodb:      image:  dockerbile/mongodb      ports:          -­‐  "27017:27017"      command:  mongod  -­‐-­‐smallbiles
  40. 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. 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
  42. 42. @crichardson Let’s imagine that you want to run your distributed app (e.g. end-to-end testing)
  43. 43. @crichardson java -jar app1.jar java -jar app2.jar Lots of scripting :-(
  44. 44. @crichardson docker run -d … app1 docker run -d … app2 Lots of scripting :-(
  45. 45. @crichardson Docker-compose.yml - part 1 restfulservice:      image:  java:openjdk-­‐8u45-­‐jdk      working_dir:  /app      volumes:          -­‐  spring-­‐boot-­‐restful-­‐service/build/libs:/app      command:  java  -­‐jar  /app/spring-­‐boot-­‐restful-­‐service.jar      ports:          -­‐  "8081:8080"      links:          -­‐  rabbitmq          -­‐  mongodb      environment:          SPRING_DATA_MONGODB_URI:  mongodb://mongodb/userregistration          SPRING_RABBITMQ_HOST:  rabbitmq Link to other containers Make the jar file available inside container
  46. 46. @crichardson Docker-compose.yml - part 2 web:      image:  java:openjdk-­‐8u45-­‐jdk      working_dir:  /app      volumes:          -­‐  spring-­‐boot-­‐webapp/target:/app      command:  java  -­‐jar  /app/spring-­‐boot-­‐user-­‐registration-­‐webapp-­‐1.0-­‐SNAPSHOT.jar      ports:          -­‐  "8080:8080"      links:          -­‐  restfulservice      environment:          USER_REGISTRATION_URL:  http://restfulservice:8080/user   Link to the other container hostname of other container
  47. 47. @crichardson
  48. 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
  49. 49. @crichardson My application architecture API gateway Event Store Service 1 Service 2 Service ... Event Archiver Indexer AWS Cloud S3 NodeJS Scala/Spring Boot
  50. 50. @crichardson Jenkins-based deployment pipeline Build & Test microservice Build & Test Docker image Deploy Docker image to registry One pipeline per microservice
  51. 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. 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. 53. @crichardson CI environment runs on Docker EC2 Instance Jenkins Container Artifactory container EBS volume /jenkins- home /gradle-home /artifactory- home
  54. 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. 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
  56. 56. @crichardson @crichardson chris@chrisrichardson.net http://plainoldobjects.com http://microservices.io

×