Using nginx in front of iocaine
Last updated: 2025-12-09

# Getting started

In here, we’ll assume that `iocaine` has already been set up, and is accepting HTTP connections on port 42069 of `127.0.0.1`. See the Getting Started guides to get there quickly!

We’ll be exploring a few scenarios here, because they integrate with `iocaine` in slightly different ways. The examples shown here can be further tuned, parts of it may be abstracted away to avoid repetition - we’re not doing any of that here. The goal here is to show how; fine-tuning one’s `nginx` configuration is not in scope.

The simplest case, we have an existing service we use `nginx` to front for, a simple `proxy_pass`! It would look something like this:

    server {
      listen 443 ssl http2;
      listen [::]:443 ssl http2;
      server_name blog.example.com;

      location / {
        proxy_set_header Host $host;
        proxy_pass http://127.0.0.1:8080;
      }
    }

Or it could be a static site:

    server {
      listen 443 ssl http2;
      listen [::]:443 ssl http2;
      server_name blog.example.com;

      location / {
        root /srv/www/blog.example.com;
        error_page 404 /404.html;
      }
    }

# Integrating iocaine

`iocaine` expects us to pipe everything through it, and it will send back a result: either a HTTP 421 Misdirected Request response to signal that we should serve real contents, or any other status, which we should serve as is.

As such, we’ll have to wrap the above example to match this expectation. We do so via a fancy `error_page` trick: we’ll send requests through `iocaine`, and if it responds with a 421, we’ll serve the “error page” via a `@fallback` location, which is where we move the original contents. The adjusted configuration will look something like this:

    server {
      listen 443 ssl http2;
      listen [::]:443 ssl http2;
      server_name blog.example.com;

      recursive_error_pages on;

      location / {
        proxy_cache off;
        proxy_intercept_errors on;
        proxy_set_header Host $host;
        proxy_pass http://127.0.0.1:42069;

        error_page 421 = @fallback;
      }

      location @fallback {
        proxy_set_header Host $host;
        proxy_pass http://127.0.0.1:8080;
      }
    }

It is very important to place `recursive_error_pages on;` into the `server` block, not in any `location` one, but directly in the `server`. That lets you use error pages outside of the one used for the fallback, and magically makes other scenarios work too.