Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

A Docker image

Docker packages an application together with its environment — the right Java version and system settings — into an image. You start a container from the image, and it runs the same on your laptop, on a server and in the cloud. Spring Boot offers two ways to get an image: write a short Dockerfile or let the Maven plugin build it. This lesson needs Docker installed.

A Dockerfile

Create a file in the project root, next to pom.xml:

# Dockerfile
FROM eclipse-temurin:25-jre
WORKDIR /app
COPY target/blog-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
LineMeaning
FROM eclipse-temurin:25-jreThe base — Linux with Java 25 (runtime only, no compiler)
WORKDIR /appThe working folder inside the image
COPY ...Puts the built JAR into the image
EXPOSE 8080A hint that the application listens on port 8080
ENTRYPOINTThe container's start command

Build the JAR first, then the image, and run a container:

./mvnw clean package
docker build -t blog .
docker run -p 8080:8080 blog

-t blog names the image, -p 8080:8080 links your computer's port to the container's port. The blog opens at http://localhost:8080, as before.

Without a Dockerfile

The Spring Boot plugin can build an image itself with Cloud Native Buildpacks:

./mvnw spring-boot:build-image
docker run -p 8080:8080 docker.io/library/blog:0.0.1-SNAPSHOT

The plugin picks Java from java.version in pom.xml and splits the JAR into layers: libraries apart from your code. Rebuilding after a code change is then faster.

Together with the database

On a server the application needs PostgreSQL. Both containers are handy to describe in one file:

# compose.yaml
services:
  db:
    image: postgres:18
    environment:
      POSTGRES_DB: blog
      POSTGRES_USER: blog
      POSTGRES_PASSWORD: changeme
  app:
    image: blog
    ports:
      - "8080:8080"
    environment:
      SPRING_PROFILES_ACTIVE: prod
      SPRING_DATASOURCE_URL: jdbc:postgresql://db:5432/blog
      SPRING_DATASOURCE_USERNAME: blog
      SPRING_DATASOURCE_PASSWORD: changeme
    depends_on:
      - db

docker compose up starts both containers. Settings are passed as environment variables — just as in the previous lesson. The real password is not written into the file: on a server it comes from secrets or from a .env file that stays out of Git.

Common mistake

Inside a container localhost is the container itself, not your computer and not the database container. With the address jdbc:postgresql://localhost:5432/blog the application does not start:

Connection to localhost:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.

In compose.yaml the database is reached by its service name — db, as in the example above.

Thanks for reading!

Donate to the site — we work hard for you.