question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Create "layered" Docker build from thin launcher

See original GitHub issue

Being 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:open
  • Created 6 years ago
  • Reactions:4
  • Comments:5

github_iconTop GitHub Comments

1reaction
dsyercommented, Mar 4, 2021

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.

Maven is missing similar functionality

You could use Maven profiles to build apps (hence images) with different dependencies.

0reactions
plamentotevcommented, Mar 3, 2021

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:

  • Base layer that contains the common dependencies
  • Kafka layers containing the Kafka related dependencies build on top of the base layer and tagged as appVersion-kafka
  • RabbitMQ layers containing the RabbitMQ related dependencies build on top of the base layer and tagged as appVersion-rabbitmq

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).

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found