Deploying in the Cloud: Spring-Boot MVC Application with Docker
5 min read

Deploying in the Cloud: Spring-Boot MVC Application with Docker

Deploying in the Cloud: Spring-Boot MVC Application with Docker

Introduction

I was working on a programming kata after seeing this question posted on Quora. I'll talk about the question, solution and more in another post. For today, I wanted to share some of the things I've learned deploying the application to the cloud.

Application Stack

The app is a very simple spring-boot based project. It's essentially spring mvc with an embedded server. The frontend uses a very simple AngularJS structure.


Steps

The steps below detail the main steps on how to deploy the app in docker.

1. Create the App

Obviously, you have to create an application first. Check out the spring-initializer to quickly get started. Once done, make sure it runs locally. You can test it by going to the folder where the jar file will be located and typing the command below.

java -jar appname.jar

Note: Spring Boot project is a project wherein there is an embedded server. Basically, you don't need to find a server and deploy a WAR file. You run the file via the command line and that's it. Magic

If you can access your app through your browser, you are good to go. Get the jar file and put it in a working directory somewhere in your computer.

2. Create a Docker File

We want to build a docker image that will run our app. We could just create a new one, use bash and do a copy of our jar, run it from command line blah blah blah. That's not cool. We're all about making our life easier. Docker has something called a dockerfile which is a text file that contains a bunch of commands we normally pass to the command line one by one.

Create a new file called dockerfile in your working directory with the contents below.

FROM java:8
MAINTAINER {YOURNAME}
EXPOSE 8080
ADD {APPNAME}.jar /data/{APPNAME}.jar
CMD java -jar /data/{APPNAME}.jar
  • FROM - the container name
  • MAINTAINER - your name goes here
  • EXPOSE - the port that the container will expose to docker
  • Important note: This port will only be inside the docker container. It's not being exposed to the outside world yet. We'll have a fix later
  • ADD - This copies your file from src to dest
  • CMD - The command to run. In this case, simply the one we use on our local

What we are doing is creating a new container based on the java docker image (which itself is built from a dockerfile. We use that because as you might assume, it already has java installed. We pass a parameter so that it pulls Java 8 for us automagically. If you wanted to, you can replace this with another image.

After providing your name, what's next is the expose. Again, we just show the port we want to access. This is the same port we access the app in our localhost (http://localhost:PORT). If you use the basic mvc app, it's port 8080. Now the ADD allows us to copy the file and put it into another folder. This destination is where we will store the app and run it. The last line should be familiar to you and easily understandable.

To understand more, check out the documentation here

3. Copy the files (FTP)

Now that we have both the app's jar and the dockerfile, we just need to copy the file to our server. Use whatever app or method you want to do this. Copy the files into any folder really.

4. Docker Build

We are ready to build our very own docker image! How exciting. CD into the directory where you copied your jar and dockerfile. If you check the contents of the folder with ls you should see the 2 files.

Build the file by running the command below.
sudo docker build -t {image-name} .

As explained in this lovely guide

This script builds the image using the docker build command. The –t argument specifies the name give to the new image. The “.” argument tells Docker to build the image using the current working directory as what is called the context of the build.

It should all run smoothly (I hope) and you should now have a new image.

5. Create New Instance

Since you created your new image, we can now create a new instance based on it. You can run the command below to generate a new instance.

sudo docker run -d -p {PORT YOU WANT TO ACCESS FORM YOUR DOMAIN}:{PORT YOU EXPOSED = 8080} --name {INSTANCE NAME} {IMAGE NAME}
As you can see, we have a few things to fill up. Specify a port number for the first part. This will be how you access it from your domain. If you specified 9999, you'll be able to view your app via http://YourIPAddress:9999. You get the idea. The next port is the one you specified in the dockerfile. If you copy pasted the code, it's 8080. The value after --name is the instance name. You'll use this to start/stop the app. Name it something unique like my-awesome-app-production. The last variable is the image name we specified in when building. We're telling docker to build a new instance based on this config.

6. Enjoy

It should all magically work. If you run into errors, reach out to me or better yet http://stackoverflow.com is your bestfriend.


Things to Improve

##Access your app via a subdomain. Instead of an IP-address, you should allow users to access your awesome app via a subdomain (or domain). This is not covered in the app but it's easy enough to do and search. You can read a bit on that in the Nginx section from my previous article [here.](http://krisviceral.com/setup-a-ghost-blog-with-docker-and-nginx/)

Deployment Pipeline

After you do this procedure once or twice, it doesn't seem too bad. If you have to do this 300 times then we obviously have a problem. We can automate that. You can think about using Dokku (Docker version of Heroku), creating a Jenkins server or something similar.


Conclusion

I learned quite a bit while making and deploying this app. I've learned a bit more on docker, nginx and the web in general. This should be a good skeleton guide for deploying other small apps in the future.

References

I couldn't have written this post without the great articles below.

Contact

Hit me up on krisviceral at gmail.com if you have questions. I'll have a comment section one of these days.