This is a can I kicked down the road for a few weeks until I learned how to build and launch a Spring WAR application on a public-facing server. I never found a definitive guide for how to do this, so hopefully this post will help Spring Boot devs with a WAR file on their hands get the sucker out there to the world.
Here’s my NixMash Spring application at http://nixmashspring.daveburkevt.com. It’s being served up from my Linode Virtual Server running Ubuntu 14.04. It’s a Spring Boot WAR file launched with the process described here.
Here are the primary configuration issues I needed to deal with.
- There are several Java and WordPress sites running on my server, so the site has to play nice with others
- The site needs to run at the root, and I’m not going to configure multiple instances of Tomcat or anything just to accommodate this app at its own domain
- I’m using Apache for serving up HTTP at port 80 with mod_proxy to Tomcat port 8080 for Java apps. I’m not going to change anything with that configuration for this silly app
Adding the Site in Apache
We’re going to start with Apache2 and create a .conf file for the site like any other. But here’s the trick. In the past we would Proxy to http://localhost:8080/[appname], where “appname” is a symlink directory under the tomcat/webapps folder (or the Java WAR file.)
Since we’re going to serve our WAR at the root and bypass Tomcat altogether (more on that in a second), we proxy to http://localhost:8086.
<VirtualHost *:80> ServerAdmin webmaster@nixmashspring ServerName nixmashspring ServerAlias nixmashspring Alias /images/ /sites/nixmashspring/images/ Alias /css/ /sites/nixmashspring/css/ <Directory /sites/nixmashspring/ > Options Indexes Includes FollowSymlinks Multiviews AllowOverride All Order allow,deny Allow from all </Directory> ProxyPass /images ! ProxyPass /css ! ProxyPass / http://localhost:8086/ ProxyPassReverse / http://localhost:8086/ ... </VirtualHost>
We’ll enable the site and reload Apache2 as normal.
Sidebar: On Bypassing Tomcat
When I say “bypassing Tomcat”, what I’m saying is that we are not using the Tomcat instance that other Java sites on the server are using. With Spring Boot our Tomcat server is embedded in the WAR file. The Spring Boot Converting a Jar to a War doc has the details on that.
A bonus with using Embedded Tomcat is that my server is currently using Tomcat 8.0.8 and I’m quite happy with it, thank you. NixMash Spring, however, had problems with 8.0.8, so I’m using Tomcat 8.0.24 in the app. No need to upgrade Tomcat on the server!
Generating the Executable WAR in Gradle
Now back to IntelliJ (or Eclipse or whatever your persuasion.) We need to generate an executable WAR, which we’ll do with Gradle and the Spring-Boot Gradle plugin.
$ gradle bootRepackage
We’ve got our WAR file, now we simply get it to the server. Any location on the server is fine, which is pretty cool when you think about it. All we’re really interested in is port 8086. We can use the location we specified in the apache [site].conf file to serve up static content outside of the app, but we can launch the WAR from anywhere. We launch it with the following command on the server.
$ java -jar nixmash-spring.war
Okay, what just happened with that last command? We just launched our site using an embedded Tomcat server at http://localhost:8086. Our app’s Tomcat server is serving up web pages. Apache handles the HTTP request at port 80 with Proxy Mod doing the redirection to port 8086, which is what we configured our Spring Boot app for.
I SSH to my Ubuntu server in a terminal session and since I will want to exit the session and keep the WAR application running I launch it in the background with “&.” Real simple. Then I “exit” out of the SSH session and the WAR app keeps ticking.
That’s it, the definitive guide on launching a Spring Boot WAR with Embedded Tomcat and Apache on a public site. Check out the results at http://nixmashspring.daveburkevt.com if you don’t believe me.