Reverse proxy for Node.js Iconify API

Node.js version of Iconify API does not handle HTTPS requests, does not have security features such as rate limiting.

But do not worry, it is not meant to handle it. That is what web servers are for.

You can hide Node.js application behind reverse proxy. What reverse proxy does it handles HTTP and HTTPS requests, forwards them to Node.js application and returns response to customer. It is useful if you want to:

  • Run API on different port, so you can host multiple websites on same server instead of only hosting API.
  • Handle HTTPS requests. All SSL stuff will be handled by web server.
  • Dealing with bad customers. You can use web server rules to block misbehaving customers and bots.
  • Using API on sub-directory rather than custom sub-domain.

Before configuring reverse proxy, you need to run Iconify API on some port hidden from outside world. Default port is 3000. You can change that port in config.json or by setting "PORT" environment variable.

Reverse proxy: Apache 2.4

This section explains how to setup reverse proxy in Apache 2.4

In httpd.conf you need to uncomment these 2 lines to enable mod_proxy:

LoadModule proxy_module libexec/apache2/mod_proxy.so
LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so

Then you can add mod_proxy to virtual host like this:

<VirtualHost *>
    ServerName api.yourdomain.com
    ProxyPass "/" "http://localhost:3000/"
    ProxyPassReverse "/" "http://localhost:3000/"
</VirtualHost>

This configuration will allow you to access API at http://api.yourdomain.com/

Here is alternative solution that you can add to your existing VirtualHost directive that allows you to run API on sub-directory:

<VirtualHost *>
    ServerName yourdomain.com
    ServerAdmin noreply@sourceforge.net
    DocumentRoot "/home/iconify/htdocs"
    ProxyPass "/api/" "http://localhost:3000/"
    ProxyPassReverse "/api/" "http://localhost:3000/"
</VirtualHost>

This solution will allow you to access API at http://yourdomain.com/api/

Reverse proxy: NGINX

This section explains how to setup reverse proxy in NGINX

Open nginx.conf, find section with your domain. Its under http -> server -> location:

http {
    # some stuff here
    server {
        listen 80;
        server_name api.yourdomain.com;

        # some stuff here
        location / {
            root   html;
            index  index.html index.htm;
        }
        # some stuff here
    }
    # some stuff here
}

Replace contents of "location" with this:

You will need to do this change twice: once for HTTP server, once for HTTPS server. In your nginx.conf look for second "server" section with SSL settings that is listening on port 443 and apply exactly the same changes.

http {
    # some stuff here
    server {
        listen 80;
        server_name api.yourdomain.com;

        # some stuff here
        location / {
            proxy_pass http://127.0.0.1:3000;
            proxy_http_version 1.1;
            proxy_buffering on;
            proxy_buffers 16 1024k;
        }
        # some stuff here
    }
    # some stuff here
}

This configuration will allow you to access API at http://api.yourdomain.com/

If you want to host API in sub-directory, instead of editing default location block add custom location:

http {
    # some stuff here
    server {
        listen 80;
        server_name yourdomain.com;

        # some stuff here
        location / {
            # some stuff here
        }
        location /api/ {
            proxy_pass http://127.0.0.1:3000;
            proxy_http_version 1.1;
            proxy_buffering on;
            proxy_buffers 16 1024k;
        }
        # some stuff here
    }
    # some stuff here
}

This solution will allow you to access API at http://yourdomain.com/api/

Resolving POST errors

If you are using GitHub webhooks to synchronize icons list, you might run into error 500. It is very likely to happen if you have fresh NGINX installation. It happened to most api.iconify.design servers during development and took a while to figure it out.

That error is likely to be caused by NGINX having wrong permissions. Run this to fix it:

sudo chmod +x /var/lib/nginx -R