How to Docker with Spring Boot

Those of you reading this have certainly heard of Docker. After years of hype, it has become the somewhat standard technology for everyday DevOps operations. It greatly helped to simplify deployments and testing by creating efficient, immutable images of the applications which are working in their own silo. More efficient placement of applications has made this technology central for cloud applications which is why it has gotten so much attention in recent years.

Docker has enabled a new, unified way of application deployment. The basic idea is simple: instead of preparing a target environment on each machine, bring it as a part of your application in the form of a container. This means no conflicting library versions or overlapping network ports. Built images are immutable - your application works the same way locally, on your teammate’s computer, or in the cloud. Also, it’s possible to run multiple instances of the container on the same machine, and that helps to increase the density of deployment, bringing down costs.

In this tutorial, you will build and run a simple web application into the Docker-compatible image using Cloud Native Buildpacks support, introduced in Spring Boot 2.3.0.


Table of Contents

Bootstrap a Secure Spring Boot Application

Start by creating a Spring Boot application using Spring Boot Initializr. This can be done via the web interface or using a handy curl command:

curl -d dependencies=web,okta \
   -d bootVersion=2.4.1 \
   -d groupId=com.okta \
   -d artifactId=demospringboot \
   -d type=gradle-project \
   -d language=kotlin \
   -d baseDir=springboot-docker-demo | tar -xzvf -

This command requests that Spring Boot Initializr generate an application that uses the Gradle build system and Kotlin programming language. It also configures dependencies on Spring Web and Okta. The created project is automatically unpacked to the springboot-docker-demo directory.

Update your main application class to allow unauthenticated access in WebSecurityConfigurerAdapter. While in there, add a controller that welcomes the user. It’s safe to put everything in a single file src/main/kotlin/com/okta/demospringboot/DemoApplication.kt:

package com.okta.demospringboot

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Configuration
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

class DemoApplication

fun main(args: Array<String>) {

class OktaOAuth2WebSecurityConfigurerAdapter: WebSecurityConfigurerAdapter() {
    override fun configure(http: HttpSecurity) {

class WebController {
    fun home(user: Principal?) = "Welcome, ${user?.name ?: "guest"}!"

Run Your Spring Boot Application

Start your application in the project folder via the command line:

./gradlew bootRun

Then, open a browser at http://localhost:8080. Your web application greets the guest user:

Webpage displaying welcome guest

Build a Spring Boot Docker Image

Since version 2.3.0, Spring Boot has supported Cloud Native Buildpacks. It has become straightforward to deploy a web service to the popular clouds using Buildpacks due to the mass adoption of this technology.

Build your application and send the image to the local Docker daemon:

./gradlew bootBuildImage --imageName=springbootdemo

Next, start your containerized web application with Docker:

docker run -it -p8080:8080 springbootdemo

As expected, your web application will be available on http://localhost:8080.

Secure Your Spring Boot Application in Docker

User management is never an easy task and, most certainly, is not the main objective of your application. Okta is an identity provider that helps you to take care of routine work such as implementing OAuth 2.0, social login, and SSO (Single Sign-On). It’s very developer-friendly, and it has excellent integration with different frameworks, including Spring Boot.

Start with installing the Okta CLI tool - it’s a real time saver for developers.

  1. Create your free developer account with Okta, no credit card required:

     okta register
     ...(provide registration details)...
     To set your password open this link:

    Don’t forget to set your password using the link above!

  2. Create an Okta application. In your project directory, execute:

    okta apps create --redirect-uri http://localhost:8080/login/oauth2/code/okta

    The Okta CLI will prompt you for an application name—choosing the default is OK. Next, select 1 (Web), then 1 (Okta Spring Boot Starter). Accept defaults, the Okta CLI will configure the default login redirect URI (http://localhost:8080/login/oauth2/code/okta) and logout redirect URI (http://localhost:8080). Don’t worry, you can change these values later if something needs to be adjusted.

  3. When an application successfully created, its configuration is saved in the current folder, in a .okta.env file.

    cat .okta.env
    export OKTA_OAUTH2_ISSUER=""
    export OKTA_OAUTH2_CLIENT_SECRET="yyy"
    export OKTA_OAUTH2_CLIENT_ID="zzz"

    You’ll need to run source .okta.env to set these values as environment variables. If you’re on Windows, rename the file to .okta.bat and change export to set. These parameters need to be injected into the application to enable OAuth flows for authentication and authorization.

    ⚠️ NOTE: make sure you never check in credentials to your source control system.

Configure Spring Security to Lock Down Access

Previously, your webpage was accessible for everyone. To allow access for authorized users only, update the Spring Security configuration in src/main/kotlin/com/okta/demospringboot/DemoApplication.kt:

class OktaOAuth2WebSecurityConfigurerAdapter: WebSecurityConfigurerAdapter() {
    override fun configure(http: HttpSecurity) {

That’s it. The Okta Spring Boot Starter takes care of the rest!

Rebuild the application again:

./gradlew bootBuildImage --imageName=springbootdemo

The --imageName parameter allows specifying an image name. Without it, the name would be something like appName:0.0.1-SNAPSHOT.

Start Spring Boot Application in Docker

When your application starts, the Okta module reads environment variables to configure security in your application. Start your application with your values set:

docker run -it -p8080:8080 \
    -e OKTA_OAUTH2_ISSUER="" \
    -e OKTA_OAUTH2_CLIENT_SECRET="yyyyyyyyyyyyyyyyyyy" \
    -e OKTA_OAUTH2_CLIENT_ID="zzzzzzzzzzzzzzzz" \

The argument -e allows to set an environment variable for the application running inside your container and -p maps container’s point to the localhost.

Now, head over to http://localhost:8080, and you’ll be asked to log in using Okta’s standard form. Enter your login credentials and, upon successful sign-in, your web browser will be redirected to the main page, displaying a welcoming message.

Webpage displaying 'welcome username'

Congratulations, you have created a simple Spring Boot application contextualized with Docker and secured with Spring Security + Okta.

Bonus - Use a dotenv File

While providing a few environment variables in the command-line might be acceptable, it’s not very convenient and can leave unwanted traces of the secrets in your terminal history. Docker supports dotenv file format, which makes it easier to set multiple environment parameters.

  1. Create a .env file in the root of the project and set desirable environment variables:
  2. Always be extra careful with credentials - avoid leaking them to the version control system even for the pet project. Add .env to .gitignore.
    echo ".env" >> .gitignore
  3. Run Docker providing your .env file via --env-file argument
    docker run -it -p8080:8080 --env-file .env springbootdemo

    Looks much cleaner, doesn’t it?

Deploy Spring Boot + Docker to Heroku

If you’d like to deploy your dockerized Spring Boot app to Heroku, you’ll need to use Heroku Buildpacks. This is because the Paketo buildpacks refuse to allocate heap on containers smaller than 1GB of RAM. A free Heroku dyno has 512MB.

First, you’ll need to add the following to src/main/resources/ so Spring Boot uses Heroku’s PORT environment variable.


Then, build your image with --builder heroku/spring-boot-buildpacks:

./gradlew bootBuildImage --imageName=springbootdemo --builder heroku/spring-boot-buildpacks

Create an app on Heroku:

heroku create

Log in to Heroku’s container registry and push your app:

heroku container:login
docker tag springbootdemo<your-app-name>/web
docker push<your-app-name>/web

Set your Okta app settings as environment variables:

heroku config:set \
  OKTA_OAUTH2_ISSUER="https://{yourOktaDomain}/oauth2/default" \
  OKTA_OAUTH2_CLIENT_ID="{clientId}" \

Next, release your container and tail the logs.

heroku container:release web
heroku logs --tail

You’ll need to update your Okta OIDC app to have your Heroku app’s redirect URIs as well.

  • Login redirect URI: https://<your-app-name>
  • Logout redirect URI: https://<your-app-name>

Run heroku open to open your app and sign in.

Learn More About Docker, Spring Boot, and Buildpacks

In this brief tutorial, you created a secure Spring Boot application and packaged it with Docker. You configured Okta as an OAuth 2.0 provider, built an image into your local Docker daemon, and learned how to run your app in Docker. This bootstrap project is a great starting point for your next cloud-native project.

You can find the source code for this example on GitHub.

See other relevant tutorials:

Follow us for more great content and updates from our team! You can find us on Twitter, Facebook, subscribe to our YouTube Channel or start the conversation below!


  • Dec 31, 2020: Updated post to add Heroku instructions, since it requires another buildpack. Thanks for the idea, Maurizio! See the code changes in the example on GitHub. Changes to this post can be viewed in oktadeveloper/okta-blog#514.