Create "layered" Docker build from thin launcher
See original GitHub issueBeing inspired from the discussion in spring-projects/spring-boot#1813 I would like to see the following based on thin launcher: Create a Docker build with the following properties
- Add all dependencies as Docker layers (by separate Docker
ADD
commands) - Add the application jar as the latest Docker layer
As long as only the application changes this should result in
- a very fast Docker build since all other layers would be already cached
- an improved shipment of the Docker image (ship dependency layers once, then only ship final application layer on changes)
The idea was also discussed here: https://github.com/JCrete/jcrete2017/tree/master/Day3/Session2/Java-Docker-Alignment and a PR is prepared and on it’s way.
Issue Analytics
- State:
- Created 6 years ago
- Reactions:4
- Comments:5
Top Results From Across the Web
Spring Boot Thin Launcher and Docker - DEV Community
I wanted to create a docker layer for the libraries. So I downloaded the wrapper.jar and put it in the repository. It has...
Read more >Reusing Docker Layers with Spring Boot - Baeldung
In this tutorial, we'll see how to exploit the new capabilities of Spring Boot to reuse Docker layers.
Read more >Multi-stage builds - Docker Documentation
Each RUN , COPY , and ADD instruction in the Dockerfile adds a layer to the image, and you need to remember to...
Read more >Creating Optimized Docker Images for a Spring Boot Application
It is very easy to create Docker images of Spring Boot ... Only the thin layer of application is pulled during application updates...
Read more >Spring Boot Layered Images - YouTube
In this final video of the Building Spring Boot Images module, users learn how to configure a Docker file for a Spring Boot...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I think you might have a point. There’s nothing stopping you from creating multiple images with different labels (via the thin launcher or other build time tools). But it’s not that easy to set up and we could make it more of a feature. The Spring Boot team have expressed some interest in extending the layering options and making them more aware of the dependency graph. I think that would also be a good place to add value here. Cc @wilkinsona and @philwebb.
You could use Maven profiles to build apps (hence images) with different dependencies.
I think the profile feature (changing the runtime dependencies) plays nice with Docker tags. Consider an application that may work with either Kafka or RabbitMQ. Then for each version of the application we can have two tags - one for Kafka and one for RabbitMQ. This would help keep the Docker images minimal - the one for Kafka would not include the RabbitMQ dependencies and vice versa. Here is an example of Docker layers:
I’m not sure if currently there is an easy way to achieve this. You basically need to separate the dependencies into different groups. One for the common dependencies and one for each profile. Spring Boot now provides layering feature to help with building optimized Docker images, but don’t think it understands the thin launcher profiles. Still, it looks like the way to go forward. Or not?
I don’t know how much demand is there for this feature, but I can give a real world example with Spring Cloud Contract Stub Runner Docker image. Spring Cloud Contract Stub Runner Boot application uses thin launcher and has three profiles - default (base) one and two additional profiles if you want to use messaging stubs - one for Kafka and one for RabbitMQ. Currently there is a single Docker image contains all dependencies no matter if you need the messaging stubs or if you are going to use Kafka or RabbitMQ. A better approach would be to have three images instead of one - 3.0.1, 3.0.1-kafka, 3.0.1-rabbitmq, each containing only the dependencies for the respective profile. This is considered a good practice from both performance (smaller image to download) and security point of view.
I would imagine there are other projects like Spring Cloud Contract that publish single image with all dependencies just because there is no easy way to separate them into profiles and layers. Many of them probably even still don’t use the thin launcher and its profiles (I myself learned about the thin launcher from the Spring Cloud Contract sources) which is a shame.
As a side note Gradle dependencies configurations are probably an easy way to group dependencies into profiles, but Maven is missing similar functionality (unless I’m missing something).