But how do you do this in a development environment? Generally, a developer will use the grails run-app command. This invokes a built-in instance of Jetty, which makes your Grails application available at the URL http://localhost:8080/yourApp/. It's easy enough to serve static files from below the yourApp directory. Simply drop them in the web-app folder in your Grails project, but there isn't any way to serve static files from above this.
The problem is that Grails is not designed to work this way. Many of the solutions I found online try to work against Grails' design, such as hacking at the internals directly, or forcing the configuration to serve everything from the root context. These have potential problems when it comes to things like upgrading Grails, or deploying to production.
Instead, I opted to find an external mechanism to serve these static files. This way the Grails application can remain untethered from the rest of its environment. It doesn't need to be aware of what's going on outside its context, its realm of control. This can be accomplished with Apache and mod_proxy. We can use Apache to serve documents from the root, then we can use mod_proxy to delegate any requests from a subdirectory to the Jetty instance used by Grails.
1. Install Apache httpd 2.2
The specifics of installing httpd are beyond the scope of this blog post. If your operating system has a packaging system (apt-get, yum, etc.), use that. If not, refer to the available Apache documentation.
For the rest of this tutorial, I will be assuming use of a Linux system.
Start httpd.
sudo /sbin/service httpd startTest that it is installed correctly using a web browser.
2. Create a root directory
Pick a location on your disk where you will keep your static files. This will be the document root for httpd. I will be using /var/grails_root.
mkdir /var/grails_root3. Create a VirtualHost in httpd.conf
touch /var/grails_root/crossdomain.xml
Open httpd.conf in your favorite text editor.
vim /etc/httpd/conf/httpd.confPick your favorite port, and create a virtual host on that port. I will be using 9090, but any port will do.
Add these lines to httpd.conf
Listen 9090Restart httpd
<VirtualHost *:9090>
DocumentRoot "/var/grails_root"
<Directory "/var/grails_root">
Allow from all
</Directory>
</VirtualHost>
sudo /sbin/service httpd restartTest that you are now able to access the static files in your document root directory. If not, you will need to fix this before moving on to the next step.
4. Enable mod_proxy and mod_proxy_http
You need to load both of these modules. mod_proxy has the base functionality for proxying, and the mod_proxy_xxx modules have information specific to a protocol. They ship standard with httpd 2.2, so you shouldn't need to install anything extra.
Add these lines to httpd.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
Now modify the virtual host you set up in the previous step. (You can omit the comments)
<VirtualHost *:9090>
DocumentRoot "/var/grails_root"
<Directory "/var/grails_root">
Allow from all
</Directory>
# New lines start here
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /grailsApp http://your.grails.server:8080/grailsApp
# New lines end here
</VirtualHost>
Restart httpd
sudo /sbin/service httpd restart
Now, you should be able to access both your static files and your Grails app via port 9090.
More information on this can be found here.
Excellent, thanks. Found this really helpful after half a day trying to convince Grails to display some static html content.
ReplyDelete