Files
ultimate-frisbee/drills/flat-stack-presejpacky/docs/nginx-reverse-proxy.md
Jan Novak c7c6bed56c
All checks were successful
Build and Push Presejpacky Docker Image / build-and-push (push) Successful in 8s
docs: add Nginx reverse proxy configuration guide
2026-06-07 23:55:23 +02:00

4.0 KiB

Nginx Reverse Proxy Configuration Guide

This guide describes how to configure an Nginx reverse proxy to host the flat-stack-presejpacky container, either at the root domain or under a specific subpath (e.g., /presejpacky), using dynamic path rewriting based on HTTP headers.

Overview

The application is built to be path-agnostic at compile time. At runtime, the Express server inspects HTTP headers to dynamically rewrite script and style references in index.html and strip the path prefix from incoming resource requests.

This enables running the same Docker image under any subpath without rebuilds.

The server checks for the presence of the following headers (in order):

  1. X-Forwarded-Prefix
  2. X-Base-Path

1. Hosting under a Subpath (e.g., /presejpacky)

To serve the application on a subpath, configure Nginx to pass the request path prefix in the X-Forwarded-Prefix header.

If your proxy_pass directive has a trailing slash, Nginx automatically strips the matched URI prefix before forwarding the request to the container.

server {
    listen 80;
    server_name drills.home.hrajfrisbee.cz;

    location /presejpacky/ {
        # Forward requests to the container, stripping "/presejpacky"
        proxy_pass http://presejpacky-container:3000/;
        
        # Forward host and IP headers
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        # Pass the subpath prefix so the container can dynamically prefix asset paths
        proxy_set_header X-Forwarded-Prefix /presejpacky;
    }

    # Redirect requests missing a trailing slash (e.g., /presejpacky -> /presejpacky/)
    # to ensure relative browser assets resolve correctly.
    location = /presejpacky {
        return 301 $scheme://$host$request_uri/;
    }
}

Option B: Preserving the prefix in Nginx

If your proxy_pass directive does not have a trailing slash, Nginx forwards the request with the subpath prefix intact. The Express server's built-in middleware will strip it.

server {
    listen 80;
    server_name drills.home.hrajfrisbee.cz;

    location /presejpacky/ {
        # Forward requests with "/presejpacky" intact
        proxy_pass http://presejpacky-container:3000;
        
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        
        proxy_set_header X-Forwarded-Prefix /presejpacky;
    }

    location = /presejpacky {
        return 301 $scheme://$host$request_uri/;
    }
}

2. Hosting on a Root Domain (e.g., https://presejpacky.example.com)

If you want to dedicate an entire domain or subdomain to the application, no prefix stripping or rewriting is required.

server {
    listen 80;
    server_name presejpacky.example.com;

    location / {
        proxy_pass http://presejpacky-container:3000;
        
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

3. Verifying the Setup

You can verify that the headers are being set and processed correctly by inspecting the source of the returned HTML in the browser:

  • If Nginx is correctly sending X-Forwarded-Prefix: /presejpacky, the references in the <head> and <body> tags of index.html should be rendered with the prefix:
    <link rel="stylesheet" href="/presejpacky/assets/index-XYZ.css">
    <script type="module" src="/presejpacky/assets/index-XYZ.js"></script>
    
  • If the headers are not set or not forwarded, the paths will fallback to the root:
    <link rel="stylesheet" href="/assets/index-XYZ.css">
    <script type="module" src="/assets/index-XYZ.js"></script>