Docker deployment of spring boot application is a hot topic in the recent years, here are the detailed steps:Create a spring boot application: start with https://start.spring.io/, select Reactive web and Reactive Mongodb and provide group and artifact, generate project.
Import the generated project into STS (or eclipse)
Spring boot application
package com.leespace.bookstore; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration; import org.springframework.core.env.Environment; import org.springframework.data.mongodb.config.AbstractReactiveMongoConfiguration; import org.springframework.data.mongodb.repository.config.EnableReactiveMongoRepositories; import com.mongodb.ConnectionString; import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoClients; @SpringBootApplication(exclude = { MongoAutoConfiguration.class, MongoDataAutoConfiguration.class }) @EnableReactiveMongoRepositories @AutoConfigureAfter(EmbeddedMongoAutoConfiguration.class) public class BookstoreMongoSpringBootApplication extends AbstractReactiveMongoConfiguration { private final Environment environment; public BookstoreMongoSpringBootApplication(Environment environment) { this.environment = environment; } public static void main(String[] args) { SpringApplication.run(BookstoreMongoSpringBootApplication.class, args); } @Override public MongoClient reactiveMongoClient() { MongoClient mongoClient = MongoClients.create(new ConnectionString(environment.getProperty("spring.data.mongodb.uri"))); return mongoClient; } @Override protected String getDatabaseName() { return "leespacedb"; } }
Create Entity class
package com.leespace.bookstore.entity; import org.springframework.data.annotation.Id; import org.springframework.data.mongodb.core.mapping.Document; import lombok.Data; import lombok.RequiredArgsConstructor; @Data @Document @RequiredArgsConstructor public class Product { @Id private int id; private String name; private String description; private String author; private String category; private double price; private String imageUrl; public Product(int id, String name, String description, String author, String category, double price, String imageUrl) { super(); this.id = id; this.name = name; this.description = description; this.author = author; this.category = category; this.price = price; this.imageUrl = imageUrl; } }
Create ReactiveRepository
package com.leespace.bookstore.repository; import org.springframework.data.mongodb.repository.Query; import org.springframework.data.repository.reactive.ReactiveCrudRepository; import org.springframework.stereotype.Component; import com.leespace.bookstore.entity.Product; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Component public interface ReactiveProductRepository extends ReactiveCrudRepository<Product, String> { Flux<Product> findByName(String name); Flux<Product> findByName(Mono<String> name); Mono<Product> findByNameAndImageUrl(Mono<String> name, String imageUrl); @Query("{ 'name': ?0, 'imageUrl': ?1}") Mono<Product> findByNameAndImageUrl(String name, String imageUrl); }
Create RestController
package com.leespace.bookstore.rest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.leespace.bookstore.entity.Product; import com.leespace.bookstore.repository.ReactiveProductRepository; import reactor.core.publisher.Flux; @RestController public class ProductController { @Autowired private ReactiveProductRepository propductRepository; @GetMapping("/products") public Flux<Product> getAllProducts() { return propductRepository.findAll(); } }
Create Dockerfile
FROM frolvlad/alpine-oraclejdk8:slim EXPOSE 8080 RUN mkdir -p /app/ ADD target/bookstore-mongo-spring-boot-0.0.1-SNAPSHOT.jar /app/bookstore-mongo-spring-boot.jar ENTRYPOINT ["java", "-jar", "/app/bookstore-mongo-spring-boot.jar"]
Build docker image
docker build . -t bookstore-mongo-spring-boot
Run spring boot app in a docker container.
Firstly clean up stopped containers: docker rm $(docker ps -a -q) docker run --name="bookstore-mongo-spring-boot-A" --restart unless-stopped --publish 9001:8080 --detach bookstore-mongo-spring-boot docker run --name="bookstore-mongo-spring-boot-B" --restart unless-stopped --publish 9002:8080 --detach bookstore-mongo-spring-boot
You can insert some records in the product collection with the following:
db.product.insert({ “_id” : 1,”name”:”Java”, “description” : “Java introduction”, “author” : “Jack”, “category” : “Book”, “price” : 234, “imageUrl” : “javaUrl”, “_class” : “com.leespace.bookstore.entity.Product”} );
db.product.insert({ “_id” : 2, “name” : “Nodejs”, “description” : “Nodejs introduction”, “author” : “John”, “category” : “Book”, “price” : 134, “imageUrl” : “Nodejsurl” ,”_class” : “com.leespace.bookstore.entity.Product”})
You can check http://localhost:9001/products or http://localhost:9002/products
The expected rest response will be like :
{
"id": 1,
"name": "Java",
"description": "Java introduction",
"author": "Jack",
"category": "Book",
"price": 234,
"imageUrl": "javaUrl"
},
{
"id": 2,
"name": "Nodejs",
"description": "Nodejs introduction",
"author": "steve",
"category": "Book",
"price": 134,
"imageUrl": "Nodejsurl"
}