One of the benefits of a dockerize app (dockerize is synonymous with containerization, just like googling is to web searching) is the ease of deployment to different environments. Once you got that docker image built, you can stick it in any environment you like. Shall we dockerize your Spring Boot app? Here’s a quick example.
Tools
- Docker Desktop 4.55.0
- Windows 11 Home 10.0.26200
- IntelliJ IDEA 2023.3.4 (Community Edition)
- OpenJDK 17.0.10
- Crowsnest, example Spring Boot App
Those are the tools I used to build this example.
Dockerfile
Before we can run the docker file, let’s build the project first. Run, mvn clean install in IntelliJ or via command line. That should create a target directory. Now, let’s take a look at the Dockerfile found at the root directory.
FROM eclipse-temurin:17-jdk-alpine
RUN addgroup -S crowsnest && adduser -S crowsnest -G crowsnest
USER crowsnest:crowsnest
COPY docker-files/ app-files
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} crowsnest.jar
ENTRYPOINT ["java", "-jar", "crowsnest.jar", "--spring.config.location=/app-files/application.properties"]What does above file mean? What will it do? FROM means that this is the base image. Our crowsnest image will extend from this image. Docker Hub contains a lot of Docker images that are suitable as base images. In this case our base image is built by Eclipse Temurin loaded with OpenJDK 17.
The RUN command will execute the Alpine Linux shell commands addgroup and adduser. The end result is a user called crowsnest belonging to the crowsnest group. This user will run the Crowsnest Spring Boot app. We don’t want root running the app. The -S is a flag for system services or daemon group.
The USER command will set the user name and user group to crowsnest as the default user and group. This user is used for succeeding RUN, ENTRYPOINT, and CMD commands.
The COPY command, as it says, will copy the files in our local docker-files directory to the app-files directroy in the Alpine Linux image.
The ARG command defines the JAR_FILE variable that is passed at build time to the builder.
The next COPY command, copies all the jar files from the target directory into a single jar called crowsnest.jar.
Lastly ENTRYPOINT command configures the container to run as an executable. In this case, it will run java with the -jar and –spring.config.location parameters.
Right, let’s build the image using the docker build command. Like so:
C:\workspace\crowsnest>docker build -t crowsnest:v1.0.0 .
[+] Building 5.2s (8/8) FINISHED docker:desktop-linux
=> [internal] load build definition from DockerfileThe above command builds the crowsnest image with the image identifier (i.e tag) crowsnest:v1.0.0 on the current path. I sometimes add the option --no-cache to not use cache when building the image. After a successful build, you should have something like below. Old school way is docker images on the CLI (Command Line Interface).

Running the Docker Image
Righto, let’s see this image in action. Go to the command line and run docker run -p 8080:8080 crowsnest:v1.0.0. This command will create and run a new container from the image tagged crowsnest:v1.0.0 exposing port 8080 and routing incoming requests to Crowsnest running on port 8080. In the words, the first 8080 is the container port number. The second is your app’s port number. You should have something like below.
C:\workspace\crowsnest>docker run -p 8080:8080 crowsnest:v1.0.0
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.5.9)
2026-02-18T15:26:52.406Z INFO 1 --- [crowsnest] [ main] n.c.crowsnest.CrowsnestApplication : Starting CrowsnestApplication v0.0.1-SNAPSHOT using Java 17.0.17 with PID 1 (/crowsnest.jar started by crowsnest in /)
2026-02-18T15:26:52.409Z INFO 1 --- [crowsnest] [ main] n.c.crowsnest.CrowsnestApplication : No active profile set, falling back to 1 default profile: "default"
2026-02-18T15:26:53.293Z INFO 1 --- [crowsnest] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
2026-02-18T15:26:53.307Z INFO 1 --- [crowsnest] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2026-02-18T15:26:53.307Z INFO 1 --- [crowsnest] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.50]
2026-02-18T15:26:53.343Z INFO 1 --- [crowsnest] [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2026-02-18T15:26:53.344Z INFO 1 --- [crowsnest] [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 878 ms
2026-02-18T15:26:53.796Z INFO 1 --- [crowsnest] [ main] o.s.b.a.w.s.WelcomePageHandlerMapping : Adding welcome page: class path resource [static/index.html]
2026-02-18T15:26:53.974Z INFO 1 --- [crowsnest] [ main] o.s.m.s.b.SimpleBrokerMessageHandler : Starting...If you are not old school, the docker desktop UI will look like so:

You can start/stop the image from running via the Actions button. Chances are you might experience some connectivity problems. Can’t connect to an API or database. Click on the three dots then “Open in terminal”. This should give you a shell prompt like below. As you can see, we are running Alpine Linux. Remember FROM eclipse-temurin:17-jdk-alpine? On the root directory is app-files and crowsnest.jar. Built with the following commands COPY docker-files/ app-files and COPY ${JAR_FILE} crowsnest.jar. Here, you can try ping, curl, wget, telnet, etc. to check connectivity. Excellent!

Dockerize a Spring Boot App
Outstanding. We have built and ran a docker image. We can spin this image up in any environment we like. To recap, we build our image from a base image then add what we need like the necessary configuration files, the application itself, etc. Finally, we specify our app as the default executable. Happy dockerizing!