When I was creating my first application in spray framework I used spray’s directive to serve static content:

As you can see the main actor combines routes from apiRoute (handles all rest requests) and staticRoute (handles static content that is located in src/main/resources/web). Static route returns index.html if no path is provided in the url and any other resource from web directory otherwise). That works pretty well but has three disadvantages:

  • If any file from web directory will change hitting F5 in the browser will return previous content until spray server is restarted. That is very annoying during developing app’s frontend when one wants to see changes immediately.
  • Restarting spray server takes time. Sure it’s relatively not that long (on my machine around 3-4 sec) but still too slow for convenient development process.
  • Returning file content to the user requires JVM involving. Whatever they told you it’s not the best way to do it. And it’s better to save CPU cycles for more important tasks.

I decided to use nginx for that task (it’s small and fast with low memory footprint http server). Here’s my configuration (it’s based on one of the gists but unfortunately I don’t remember the author):

To run nginx I created following script start_nginx.sh:

Notice the -p parameter. Without it nginx looks for provided configuration file (in my example called nginx.conf) in its default configuration directory. What’s interesting on Windows this parameter is not required. I was really surprised with this platform inconsistency.

To stop nginx you must run following command (nginx process it’s not “killable” (at least on windows)):

If everything is ok nginx will start listening on localhost:9000 and from now on it will be responsible for serving files from the web directory. I forgot to mention that I moved web folder outside resources folder to avoid including it in the final jar file.

Spray application is listening on localhost:8080 and all requests coming from localhost:9000/api/* are forwarded there. In my case I use ssl on port 9000 so I had to add following line:

This line transforms https prefix into http one. Of course you can use ssl on spray side as well but it’s unnecessary protection doubling.

And that’s all. Hope that will help someone 🙂