Serving static content with Dropwizard
Dropwizard, in its own words is a "Java framework for developing ops-friendly, high-performance, RESTful web services".
It is extremely lightweight, stable and mature, with most of the boilerplate code for configuration, application metrics, logging, alerting already built in.
In User Insights, Dropwizard powers our REST API. The same code base also hosts an internal console powered by BackboneJS which consumes these API's for visualizing the results. Now, here is where the challenge comes in. By default, static files are part of the JAR that runs your application server. Any changes to the console (quite frequent) requires the JAR to be rebuilt and deployed on the server. I wanted to separate the static files required by the console so that the UI developer could deploy the console package as per his whims without having any dependency on the API JAR. At the same time I did not want to deploy another web server on the box just for these files.
One of the issues that most people face while serving static content with Dropwizard is how to serve these static files from outside the JAR. If you are one of those people, here is a post that you might find useful.
You can serve static content for your Dropwizard application efficiently in two ways:
1) Using nginx
2) Using a custom Asset Bundler
1) Using nginx:
You can configure nginx so that it serves all the static content, while unrecognized requests can be forwarded to your application server.
Here is a sample config:
</code> For the above config, nginx is serving files with the any of the following extensions: *.jpg, *.jpeg, *.gif, *.css, *.png, *.js, *.ico, *.html. 2) Using custom Asset Bundler: Hope you find this useful. If you have any suggestions/alternatives regarding this, then do let me know!
# Site (port 80 -> 8080)
server {
listen 80; # Listen on port 80 for IPv4 requests
server_name localhost;
access_log /var/log/nginx/site_access.log;
error_log /var/log/nginx/site_error.log;
# Set the root of the static content
root /usr/share/nginx/html;
# Redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
# Filter static content types and serve from the root
location ~\*\.(jpg|jpeg|gif|css|png|js|ico|html)$ {
access_log off;
expires max;
}
# Serve the dynamic content (Site)
location / { # The application provides its own detailed logs
access_log off;
# Hand over to the application
proxy_pass http://localhost:8080/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
The location of these files should be: /usr/share/nginx/html
Any other content is forwarded to your application server serving on port 8080 (default Dropwizard port).
Any 50x error generated by your application server will cause a redirect to the /50x.html static file located at /usr/share/nginx/html
This github repo hosts a drop in replacement for Dropwizard's AssetsBundle class which allows Assets (files) to be served from outside the jar.
Many people find it difficult to use this plugin because of lack of proper documentation/examples.
Here is a link to a sample project I created which shows the proper use of this plugin.