Last Updated: April 2, 2021

Add Docker to Your Spring Boot Application

Docker enables you to deploy a server environment in containers. A container is a standardized unit of software that assembles code, runtime, dependencies, settings, and initialization in a single package that you can run reliably from one computing environment to another. Deploying your app as a Docker container is not hard, and can alleviate a lot of problems that you may encounter when moving your app around the multiple environments it has to go, like development machines, QA environment, staging, and production.

Docker host layer diagram

In this tutorial, you’ll see how to leverage Docker to deploy your Spring Boot application.

Prerequisites:

First, let’s build a sample Spring Boot app to use.

Create A Spring Boot App

You’ll use Spring Initializr to generate your Spring Boot project with the help of HTTPie, a simple command-line HTTP client.

You may use the Spring Initializr website directly if you don’t want to use the command line.

From the command line simply enter:

http https://start.spring.io/starter.zip bootVersion==2.4.4.RELEASE \
 dependencies==web,okta \
 groupId==com.okta.spring-docker.demo \
 packageName==com.okta.spring-docker.demo \
 --download

And then unzip the downloaded file.

unzip demo.zip -d spring-boot-docker
cd spring-boot-docker

You’ll next add a web controller by creating file src/main/java/com/okta/springdocker/demo/WebController.java:

package com.okta.springdocker.demo;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class WebController {

    @RequestMapping("/")
    public String home() {
        return "Welcome!";
    }
}

You also need to configure the security settings for this project. For the moment, you’ll want to allow all requests, so update your DemoApplication.java file to the following:

package com.okta.springdocker.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Configuration
    static class OktaOAuth2WebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.authorizeRequests().anyRequest().permitAll();
        }
    }
}

You may compile and run your app with:

./mvnw package
java -jar target/demo-0.0.1-SNAPSHOT.jar

Then if you hit http://localhost:8080 you should see a "Welcome!" message.

Run Your Spring Boot App as a Docker Container

To run your app as a Docker container, the very first step is to install Docker.

After installing, it’s time to build your container. For that, Docker uses a file that describes how to assemble the container, which is called a Dockerfile. The Dockerfile consists of step-by-step instructions to execute in a container.

Reach out to Dockerfile reference for an explanation of all commands you can use.

For your Spring Boot app, you’ll use a simple Dockerfile file:

FROM openjdk:11 (1)

COPY target/demo-0.0.1-SNAPSHOT.jar app.jar (2)

EXPOSE 8080  (3)

ENTRYPOINT ["java", "-jar", "/app.jar"] (4)
1 You’ll start your Dockerfile with a FROM declaration that defines a source container image to build upon. In this way you can leverage an existing container definition that contains JDK 11.
2 The second instruction is COPY. Here you are telling Docker to copy a local file into the container, in this case, your built application will be available in the container as /app.jar.
3 The EXPOSE part shows you that the app will listen on port 8080. Although it is not required to make the Docker container work properly, it acts as documentation for future readers.
4 The last command, ENTRYPOINT, tells Docker what it should execute when you run that container. As you are building a Spring Boot application, this is a simple java -jar of your app.
You can browse through a lot of community containers to use as a base at DockerHub.

Now you can build the container on your command line. Execute the following while replacing okta:spring_boot_docker with a tag of your liking, it will serve as a name to reference the container you are building:

docker build . -t okta:spring_boot_docker

If all went well, you may now run your Dockerized app (using the same tag as you used before):

docker run --publish=8080:8080 okta:spring_boot_docker

To stop the container, hit CTRL-C. Verify the container isn’t running, execute:

docker ps

This will list all the containers running on your machine. If your Spring Boot app is still running, you can terminate the container with (use the Container ID printed by docker ps):

docker kill <CONTAINER_ID>

As your JAR file is copied into the container when you build it, you will need to rebuild your container each time you want to use a newer version of the app. So the cycle would be:

  1. Change your code

  2. Build the app ./mvnw package

  3. Build the container docker build . -t okta:spring_boot_docker

  4. Run the container docker run --publish=8080:8080 okta:spring_boot_docker

  5. Stop the container

  6. Loop

Now you know the basics of using Docker containers to run your app! In the future, you can publish your built container into Docker registries (like DockerHub), so others can fetch the container and it’ll be ready to run.

Next, we will secure the app with Okta and understand how we can pass sensitive data to the container.

Secure Your Spring Boot and Docker App

Before you begin, you’ll need a free Okta developer account. Install the Okta CLI and run okta register to sign up for a new account. If you already have an account, run okta login. Then, run okta apps create. Select the default app name, or change it as you see fit. Choose Web and press Enter.

Select Okta Spring Boot Starter. Accept the default Redirect URI values provided for you. That is, a Login Redirect of http://localhost:8080/login/oauth2/code/okta and a Logout Redirect of http://localhost:8080.

What does the Okta CLI do?

The Okta CLI will create an OIDC Web App in your Okta Org. It will add the redirect URIs you specified and grant access to the Everyone group. You will see output like the following when it’s finished:

Okta application configuration has been written to:
  /path/to/app/src/main/resources/application.properties

Open src/main/resources/application.properties to see the issuer and credentials for your app.

okta.oauth2.issuer=https://dev-133337.okta.com/oauth2/default
okta.oauth2.client-id=0oab8eb55Kb9jdMIr5d6
okta.oauth2.client-secret=NEVER-SHOW-SECRETS

NOTE: You can also use the Okta Admin Console to create your app. See Create a Spring Boot App for more information.

Change the DemoApplication class, replacing .authorizeRequests().anyRequest().permitAll() with .authorizeRequests().anyRequest().authenticated(). This will tell Spring that all the endpoints of your app will require an authenticated user.

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests().anyRequest().authenticated();
}

Let’s give it a try!

First compile and build your container.

./mvnw package

Then build the container:

docker build . -t okta:spring_boot_docker

The Okta CLI added your Okta settings to src/main/resources/application.properties. However, you might want to check this file into source control. Therefore, it’s a good idea to remove the okta.oauth2.* properties from this file and use environment variables instead.

To pass Okta info to the container as environment variables, you can use the -e command line parameter. Like so:

docker run --publish=8080:8080 \
 -e OKTA_OAUTH2_ISSUER=<org_url>/oauth2/default \
 -e OKTA_OAUTH2_CLIENT_ID=<client_id> \
 -e OKTA_OAUTH2_CLIENT_SECRET=<client_secret> \
 okta:spring_boot_docker

Now if you hit http://localhost:8080 you will see a login form, and after providing your username and password you should be able to see the welcome page again. A dependency and a couple of properties are all it takes to secure your application with OIDC/OAuth 2.0!

Learn More About Spring, Docker, and Security!

In this tutorial, you learned how to build a Docker container for your Spring Boot app by writing the Dockerfile manually. There’s also a Maven plugin that can prepare the container for you. It’s called Jib and we cover it in more detail at Get Jibby With Java, Docker, and Spring Boot. Finally, Spring Boot 2.3 added built-in support for building Docker containers. Learn more in How to Docker with Spring Boot.

Other than that, we have more resources for you to continue learning about Java, Docker, Deployment, and OAuth 2.0:

The source code for this post is available on GitHub.

If you have any questions about this post, please add a comment below. For more awesome content, follow @oktadev on Twitter, like us on Facebook, or subscribe to our YouTube channel.

Changelog: