Some shared libraries may be used by only one application, so the 130 MB might increase.
To maximize compression, manage third-party dependencies with a centralized SBOM (Software Bill of Materials) to unify versions and prevent conflicts (e.g., Guava 33.1 vs. 33.2 across applications).
The frontend
Frontend static files are served using Caddy or Nginx. Extract assets from your frontend Docker image:
Networking and routing
We use Traefik for networking, relying on its auth middleware for header-based authentication. While chosen for our cloud Kubernetes solution, Nginx is a valid alternative if preferred.
Include these components:
Process management
Standard Spring Boot images have a single entrypoint to start the JAR. For multiple processes, use Supervisor for process management (provisioning, restarting, shutdown):
Supervisor manages all processes at startup:
The final build
After completing all steps, we achieve this layout:
The final Dockerfile pseudocode:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
# 130 MB FROM jre:17 # 70 MB RUN apt-get install supervisor ... # 60 MB after UPX compression COPY <binaries: caddy/traefik> # ~150 MB COPY <JAR dependencies (symbolic links created during build)> COPY <etc configuration> # ~20 MB COPY <business classes> # ~20 MB COPY <frontend assets> # Rootless operation RUN <useradd> EXPOSE80808443 ENTRYPOINT <launch supervisor>
This produces a Docker image of approximately 500 MB.