Instiki via Apache Reverse Proxy

Instiki is a cool instant-setup wiki written in Ruby. It runs on top of WEBrick, which doesn't allow for instant integration with Apache.

I wanted to run a published version of my Instiki without having to set up vhosting, just as a subdir on my website. I used Apache's proxy module to set up a reverse proxy to the published Instiki then used mod_proxy_html to rewrite the URLs in the pages to match the subdir where Instiki is hosted.

Apache Setup

I use Apache 2 on FreeBSD, so the first think I needed to do was rebulid Apache enabling the proxy and proxy_http modules. To do this add WITH_CUSTOM_PROXY="proxy proxy_http" when building the port. (If you are using portupgrade, you want to add this to your pkgtools.conf.) Note that even though the Makefile says a ',' between the module names is ok, it isn't.

Next build the mod_proxy_html module. This rewrites the HTML pages so that the links match up. If you want to publish the whole wiki, you can ignore this step.

Apache Configuration

Next you need to load the proxy modules. The following lines in httpd.conf will do that:

# Proxy support
LoadModule proxy_module libexec/apache2/mod_proxy.so
# HTTP Proxy
LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so
# for proxy_html_module
LoadFile /usr/local/lib/libxml2.so
# rewrites HTML URLs for proxied pages
LoadModule proxy_html_module libexec/apache2/mod_proxy_html.so

Next we set up the proxy. The idea is to map /wiki on Apache onto /wiki/published on Instiki. Stylesheets are stored in a separate directory, so those need to be proxied separately to avoid path collisions:

# Turn off forward proxying
ProxyRequests Off

<Proxy *>
  Order deny,allow
  Allow from all
</Proxy>

# Forward /wiki and /wiki_css to Instiki
ProxyPass /wiki http://localhost:2500/wiki/published
ProxyPass /wiki_css http://localhost:2500/static_style_sheet

Finally, we need to make sure everything gets rewritten properly so all the links resolve to the correct places. Currently, Instiki links to other pages with a URL of ../published/WikiWord, and published is not a very sensible name for the wiki. mod_proxy_html takes care of this:

# Rewrite links
ProxyHTMLURLMap ../published /wiki
ProxyHTMLURLMap ../static_style_sheet /wiki_css

<Location /wiki>
  # Rewrite response headers
  ProxyPassReverse / 
  # Enable link rewriting
  SetOutputFilter proxy-html
  # Apparently compression causes problems in mod_proxy_html
  RequestHeader unset Accept-Encoding
</Location>

Here's the complete configuration:

# Proxy support
LoadModule proxy_module libexec/apache2/mod_proxy.so
# HTTP Proxy
LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so
# for proxy_html_module
LoadFile /usr/local/lib/libxml2.so
# rewrites HTML URLs for proxied pages
LoadModule proxy_html_module libexec/apache2/mod_proxy_html.so

# Turn off forward proxying
ProxyRequests Off

<Proxy *>
  Order deny,allow
  Allow from all
</Proxy>

# Forward /wiki and /wiki_css to Instiki
ProxyPass /wiki http://localhost:2500/wiki/published
ProxyPass /wiki_css http://localhost:2500/static_style_sheet

# Rewrite links
ProxyHTMLURLMap ../published /wiki
ProxyHTMLURLMap ../static_style_sheet /wiki_css

<Location /wiki>
  # Rewrite response headers
  ProxyPassReverse / 
  # Enable link rewriting
  SetOutputFilter proxy-html
  # Apparently compression causes problems in mod_proxy_html
  RequestHeader unset Accept-Encoding
</Location>

Debugging

If you aren't getting things right, you can enable debugging on mod_proxy_html with the following two lines:

ProxyHTMLLogVerbose On
LogLevel Debug

This will place info about what rewrites mod_proxy_html is performing in Apache's error log.