I'm trying out a new way of deploying my Spring Boot apps into the "cloud". This time it's AWS "Elastic Beanstalk". EBS offers platforms such as Ruby, Python, Node.js, PHP, .NET, and yes, Java. However, none of the Amazon-provided platform images were quite what I was looking for: a place to just run an app in a .jar.
That's because the EBS Java offering comes pre-loaded with Tomcat and expects you to supply a .war, but these days I build my Java web apps using Spring Boot, so I've already got an embedded servlet container and my build products are runnable .jars. Yes, I know, I could convert my Spring Boot project to build a .war file, but what I'm really interested in is being able to deploy my apps *anywhere* that there's a Java runtime. I want to be able to deploy the same .jar onto the private PaaS (a customized Cloud Foundry) at the office, or onto Heroku, or onto AppFog, or onto some random bare metal I happen to have lying around the house, so long as it has a Java runtime and a gateway to the Internet.
Enter Docker. I've formed a tentative conclusion that Docker is to EBS what custom "buildpacks" are to Heroku and Cloud Foundry. Docker allows me to define my own platform image and combine that with my runnable jars, so that the platform is as lean as I want it to be (no "extra" external servlet container bloating the image). What's more, using Docker gives me full control of the Java runtime version - right down to the bug-fix update of my choice.
As I write this, I am uploading my first-cut at a "java8" image to Docker. Assuming that completes successfully, it will be publicly available here: https://registry.hub.docker.com/u/w7tek/java8/. This image I've created starts with another Docker image, vettl/amazon-linux:2014.03, and from there uses rpm to install the JDK RPM of my choice from Oracle, then sets the stage for folks to reuse my image by using it in their own Dockerfile. Of course, when I say "folks", I mean "probably nobody but just me" but even if that's the case, I've got a personalized, reusable image that I can reuse with any Java/Spring Boot/Maven projects.
Well, it looks like my 1.07GB upload - painfully slow as it was over CenturyLink DSL in Herriman, UT - has completed. Happily, when I made "one more tweak" to the Docker image, it only took a few seconds to upload the new changes. Now, to see if theory matches practice: I'm going to use that image as the basis for the image I want to deploy onto EBS, and the next step is figuring out how to supply the database connection credentials to my app from the process environment… wish me luck!
OK, so the first glitch is that the ONBUILD commands in the Dockerfile for my java8 image don't seem to work on EBS; I tried creating a hello-aws using FROM w7tek/java8:0.2 and it fails to deploy because (claims EBS) there is no "EXPOSE" statement in the hello-aws Dockerfile. Grumble. So although Docker seems to support the boilerplate-factoring, EBS isn't quite 100% Docker.
ReplyDelete…and voila! http://w7tek-myapp-1.elasticbeanstalk.com is now serving from my Docker image. That seems to confirm my guess: ONBUILD directives in Dockerfile are not honored by the Docker version Amazon is using. So, there's a certain amount of boilerplate in the w7tek/hello-aws Dockerfile, that must appear in other images' Dockerfiles, but I now have a reusable pattern for stamping Spring Boot apps onto Amazon EC2. Good-night!
ReplyDelete