Deploying a Spring Boot Kofu API

Last time we built (mostly borrowed) a simple API built with Spring Fu (more specifically, Kofu) with help from Spring Boot and Kotlin.

Now that we have something that works, lets get it out on the public web.

Docker

We'll need to start with a Docker image - something to hand to AWS Fargate to run.

Back in IntelliJ, create a new file Dockerfile in the root of the project and add these 3 lines:


FROM openjdk:8-jdk-alpine

COPY build/libs/valer-api.jar app.jar

ENTRYPOINT ["java","-jar","app.jar"]
 
  • Line 1 pulls in the JDK 8 Alpine image as a starting point
  • Line 2 copies the jar we generated in the last post to app.jar in the root of the image
  • Line 3 says to execute java -jar app.jar when the image runs, after all the previous steps

Now let's build the docker image using docker build -t valer/api . to tag it as valer/api and build using the Dockerfile in the root.

Execute docker run -p 8080:8080 valer/api to run the container, exposing port 8080 outside the container also to port 8080.

Let's test it again using Insomnia:

Great!

Now, if we want to build the image when we update source, we'll have to make a few changes to the Dockerfile.


FROM openjdk:8-jdk-alpine

WORKDIR /workspace/app

COPY gradle gradle
COPY src src
COPY build.gradle.kts .
COPY gradlew .

RUN ./gradlew bootJar

COPY build/libs/valer-api.jar app.jar

ENTRYPOINT ["java","-jar","app.jar"]
 
  • WORKDIR /workspace/app creates a working directory - the name is arbitrary (I just copied this one from another example). From here, all commands will be run in that directory. It is better than using cd to navigate within the Dockerfile.
  • We also copy all the source we need to build the application
  • ./gradlew bootJar builds our Jar
  • Finally, we copy the built jar out of the build directory using COPY build/libs/valer-api.jar app.jar

Let's build this sucka to make sure we did it right:

Fargate

I'm cutting out the indecision and research and going straight for AWS Fargate. The service does the management for us, we just have to point it to what we want running and give it a few small decisions about what our app needs.

BUT FIRST, we need a place to host our Docker image on the internet. Since we know we're using AWS, let's use their container registry: ECR. Head over to the AWS console and find ECR:

Hit that orange Get Started button to create a repository.

Give it a good name and hit Create Repository.

That was easy.

Click into the repository - no images there, yet.

Click that View push commands button in the upper right.

AWS gives the commands you need to login to ECR, build, tag, and push the image using the Docker CLI. Follow those exactly.

You'll need the AWS CLI as well and if you have issues with the login command, try upgrading your AWS CLI.

That last push command will take some time unless you have some kick-ass upload bandwidth.

Back in the AWS console, find Elastic Container Service or ECS. Click Get Started.

We want custom, so hit that Configure button.

Give your container a name and paste in the ECR image URL and tag. Make sure you map port 8080 because that's what our API runs on.

Continue on. We don't want a load balancer for this basic example, it will just cost us money. Next.

Give your cluster a name. Next.

Create.

Once the launch is complete, navigate over to your service and wait for the task to transition to RUNNING.

Find CloudWatch in AWS console, then navigate on the left to Log groups. Find the one that matches your task (/ecs/first-run-task-definition probably) and then Search log group button.

Notice mine has some error logs - I initially missed the step to copy the built jar to the workspace. Otherwise, yours should look similar.

Back in the ECS console, find the running task and copy the public IP address from the details. Plug that into Insomnia to see it in action.

Once you don't need it anymore, be sure and shut it down. In the service, change the number of tasks from 1 to 0.

Stop the task.

All done!

The initial setup phase is done, but now what if we want to make code changes and deploy them quickly and easily?

Come back for some CI/CD goodness.

Thanks for reading!

Comments powered by Talkyard.