Latest blog

  • Dockerize Spring Boot App Example

    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

    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 Dockerfile

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

    Dockerize Spring Boot App Example – Image Created

    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:

    Dockerize Spring Boot App Example – Image Running

    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 Spring Boot App Example – Terminal

    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!

    Docker me…