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.
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.jarin the root of the image
- Line 3 says to execute
java -jar app.jarwhen 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.
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:
Now, if we want to build the image when we update source, we'll have to make a few changes to the
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/appcreates 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
cdto navigate within the
- We also copy all the source we need to build the application
./gradlew bootJarbuilds 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:
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.
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.
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!