I already have apache 2.4.19 installed on my Ubuntu 16.04 working with Tomcat. I'm trying to add a node app and redirect all requests for /node to http://localhost:3000 with ProxyPass. My node app is listening to port 3000 of course.

It works very well to redirect my requests like https://myapi.com/node/foo

However I have issues with the documentation generated with apidoc which I serve statically in my node app with app.use(express.static('doc'));. When I go to https://myapi.com/node, it seems that all the urls like /vendor/xxx, /locales/xxx didn't get /node prefixed. I thought ProxyHTMLURLMap would take care of that but I must be using it wrong.

Here is my /etc/apache2/sites-enabled/000-default.conf (I've stripped out some comments to make it shorter)

<VirtualHost *:443>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    # Tomcat
    JkMount /* worker1

    # SSL Config
    SSLEngine on
    SSLCertificateFile /path/to/certificate
    SSLCertificateKeyFile /path/to/private.key
    SSLCACertificateFile /path/to/intermediate-cert

    # Headers
    Header always set Access-Control-Allow-Origin "*"
    Header always set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding"
    Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PULL"
    # Return 200 for all OPTIONS requests
    RewriteEngine On
    RewriteRule ^(.*)$ $1 [R=200,L]

    # Reverse Proxy to Node
    # The part below was supposed to change the relative url to /node/xxx but it does not seem to work
    ProxyHTMLURLMap http://localhost:3000 /node
    <Location /node>
           ProxyPass http://localhost:3000
           ProxyPassReverse http://localhost:3000
           ProxyHTMLEnable On
           SetOutputFilter proxy-html
           ProxyHTMLURLMap http://localhost:3000
<VirtualHost *:80>
    ServerName myapi.com
    Redirect / https://myapi.com/

I can't use ProxyHTMLExtended On as suggested by Andrew Schulman because it will mess up the output of apidoc.js
The index.html generated with apidoc.js has this statement at the very end:
<script data-main="main.js" src="vendor/require.min.js"></script>
Then the main.js does a bunch of require
I tried replacing the main.js with node/main.js in the script statement but then the requires are failing...
I've also noticed that if I query https://myapi/node/index.html directly, all the files seem to load fine. Maybe I'll just configure Apache to redirect /node to /node/index.html


By default mod_proxy_html doesn't rewrite links in inline CSS and Javascript. To enable that you have to set ProxyHTMLExtended On. See the docs.

That may fix your problem, but it doesn't touch CSS and Javascript that's sourced from other files, instead of included inline. If you want to try to fix those up too, you'll need to use another module such as mod_sed or mod_line_edit. That also may work for you, but it can also be impossible to get completely right, since in code (i.e. Javascript) URLs can be calculated in arbitrary ways that a regex parser can't find.

| improve this answer | |
  • I had tried to use ProxyHTMLExtended On but the problem is that the index.html generated with apidoc.js contains some code like {{#if title}} some html {{/if}}. With this option turned on, the /if gets replaced with /node/if and breaks everything. I'll update my question with more details – Gpack Mar 1 '18 at 3:14
  • So you may need to adjust your code or your matching rules, or use mod_line_edit or mod_sed to compensate. Not pretty but it may work. – Andrew Schulman Mar 1 '18 at 12:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.