Transparantly make multiple web applications available at a single address

Solution 1:

What you're looking for is called "reverse proxy". There are many web servers that have this capability, including Apache httpd, lighttpd, and nginx, as well as more stripped-down web servers designed solely for reverse proxying.

Since Apache is the most likely to be available to you and/or easiest to deploy, this snippet of code to be included in the relevant section of your Apache config files should give you the minimal configuration for what you need, assuming you have mod_proxy_http installed and enabled:

# ... [snip] ...
<VirtualHost *:80>
# ... [snip] ...

# This line prevents mod_proxy from acting as a forward proxy
# Yes it looks silly, but it's correct for reverse proxy configurations
ProxyRequests Off

# Rails app on port 8080
ProxyPass /app1 http://localhost:8080
ProxyPassReverse /app1 http://localhost:8080

# CherryPy app on port 8081
ProxyPass /app2 http://localhost:8081
ProxyPassReverse /app2 http://localhost:8081

# ... [snip] ...
</VirtualHost>

Update: here are some links to (sometimes dense) documentation for various servers:

  • Apache mod_proxy
  • Nginx HttpProxyModule
  • Lighttpd mod_proxy_core

Word to the Wise

Also consider that with reverse-proxy the back-end applications will no longer be receiving requests from the IP of the client initiating the request. Instead, all requests will appear to come from localhost (127.0.0.1). So any client IP-related logic will stop functioning. If your application needs this request metadata, you will need to follow a procedure dependent on your reverse proxy HTTP server.

In Apache, mod_proxy automatically adds an X-Forwarded-For header to the request whose value is the IP address of the request that came into Apache (or a list of IPs that have forwarded the request, if you have a chain of several reverse proxies). For Nginx, I believe you may have to instruct the server to send such a header (details are in the link above).

If your back-end application cares about the Host: header from the original client request, you'll need to modify that code to look for (in Apache) the X-Forwarded-Host header as well.

Solution 2:

It's called a Reverse Proxy. You can do it with Apache as well as other web servers. There are also dedicated proxy servers that you could use as well.