Inspecting Docker Images

About

When building Spring Boot applications for containerized deployment, it's common to package them as Docker images. But the way these images are built and what they contain can greatly impact performance, security, and maintainability.

Inspecting Docker images involves analyzing the image’s internal structure: its layers, file system, configuration metadata, embedded application artifacts (like JARs), and runtime setup. Tools like dive, docker history, and docker inspect allow developers to gain visibility into how Spring Boot applications are built and shipped in container form.

Why It Matters ?

  • Understand What Goes Inside: A Spring Boot image often includes our application JAR, dependencies, configs, and even a base OS. Inspection helps verify what’s actually packaged.

  • Optimize Image Layers: Avoid unnecessary bloat caused by repetitive or misplaced build steps (e.g., COPY commands, Maven caches).

  • Troubleshooting & Debugging: Pinpoint missing files, misconfigured entrypoints, or wrong permissions inside the image.

  • Security Auditing: Check for unexpected tools, leftover secrets, or outdated libraries.

  • CI/CD Confidence: Verifies whether final production images match expectations set in Dockerfiles or Jib builds.

What to Look For During Inspection of a Spring Boot Docker Image ?

Aspect

What to Look For

Why It Matters / Use Case

Application JAR

Is the JAR file (e.g., hello-springboot.jar) present in the expected path like /app or /target?

Validates that the build and copy steps succeeded. Missing JAR means the app won’t run at all.

Configuration Files

Are application.properties or application.yml files included? Are they in the right directory?

If these files are missing, environment-specific configs (DB URL, ports, etc.) won't be picked up.

Liquibase / Flyway Migrations

Check if migration scripts (e.g., db/changelog.xml) are copied into the image.

Without these, Liquibase or Flyway will fail silently or at runtime due to missing migration files.

Secrets or Credentials

Are there any .env, .pem, or credentials accidentally copied?

Avoid leaking secrets into images. They should be injected via environment variables at runtime instead.

Layer Size

Which layer adds the most size? Are there any large, unnecessary files?

Identifies optimization opportunities. For example, Maven cache might get added if .dockerignore is misconfigured.

Base Image

What is the base image used (e.g., openjdk, eclipse-temurin, distroless)?

Affects image size, startup time, and security posture. Distroless or slim images are better for production.

Permissions

Are file permissions and ownership correct (e.g., non-root user)?

Running apps as root is a security risk. Inspect /home/nonroot or UID/GID mappings.

Entrypoint / CMD

Is ENTRYPOINT ["java", "-jar", "app.jar"] correctly defined?

Ensures that the app starts automatically when the container is run.

Unwanted Files

Are .git, test/, target/, .idea, or node_modules present in final image?

These should be excluded using .dockerignore. Including them increases size and leaks internal structure.

Healthcheck or Labels

Are labels like maintainer, version, or healthcheck metadata added?

Helps in managing images during deployment and monitoring.

Build Artifacts

Is Maven or Gradle cache included?

May unnecessarily inflate image size; should be kept in builder stage only.

Using Dive to Explore Spring Boot Docker Images

To deeply inspect the internals of our Spring Boot Docker image such as layer-by-layer file changes, image composition, and efficiency the tool Dive is highly recommended.

Dive provides a terminal-based interface to:

  • View each image layer and what it adds or removes

  • Analyze the image’s file system at any layer

  • Identify redundant or bloated layers (e.g., Maven caches, test files)

  • Detect config file locations, application JAR placement, and more

  • Measure image efficiency, especially in multi-stage builds

This is especially useful when we want to:

  • Ensure our application.properties, Liquibase scripts, and compiled JAR are properly placed

  • Confirm that unwanted artifacts (e.g., .git, .class files, temp logs) are excluded

  • Debug runtime issues caused by misconfigured or missing files

Refer to the Page for more details - Use Case

After inspecting the image, proper classpath updates can be done to locate the appropriate configuration files

['-cp','/app/WEB-INF/classes:/app/WEB-INF/lib/:/app/classes:/app/libs/:/app/resources/','-Dlogging.level.liquibase=DEBUG']

Last updated