How to Configure Reverse Proxy with Nginx for Stirling-PDF

The unified Stirling-PDF Docker image uses nginx to serve the React frontend and proxy API calls to the Spring Boot backend, configurable via the BACKEND_URL environment variable.

Stirling-Tools/Stirling-PDF is an open-source PDF manipulation suite that packages a Spring Boot backend with a Vite-powered React frontend. When you configure reverse proxy with nginx for Stirling-PDF using the unified Docker image, nginx handles both static asset delivery and dynamic API routing to the backend service.

Understanding the Unified Container Architecture

The unified Docker variant combines the frontend and backend into a single container where nginx acts as the primary entry point. According to the Stirling-Tools/Stirling-PDF source code, this architecture exposes port 8080 for all traffic while internally routing API requests to the backend service.

The container startup process defined in docker/unified/entrypoint.sh orchestrates this by copying frontend assets to /usr/share/nginx/html and launching nginx with a dynamically generated configuration.

Key Configuration Files

docker/unified/nginx.conf

The static nginx configuration defines the server block listening on port 8080. Located at docker/unified/nginx.conf, this file contains the reverse proxy logic that forwards API calls to the backend:

server {
    listen 8080;
    root /usr/share/nginx/html;
    index index.html index.htm;

    # Frontend routing

    location / {
        try_files $uri $uri/ /index.html;
    }

    # Proxy API calls to backend

    location /api/ {
        proxy_pass ${BACKEND_URL}/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        ...
        proxy_set_header Connection '';
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_connect_timeout 60s;
        client_max_body_size 100m;
        proxy_request_buffering off;
    }
}

This configuration handles three specific proxy paths: /api/, /swagger-ui, and /v*/api-docs, ensuring OpenAPI documentation and REST endpoints reach the backend.

docker/unified/entrypoint.sh

The configure_nginx() function in docker/unified/entrypoint.sh injects the actual backend address into the nginx configuration before startup. As implemented in Stirling-Tools/Stirling-PDF, this Bash function uses sed to replace the ${BACKEND_URL} placeholder:

configure_nginx() {
    echo "Configuring nginx with backend URL: $backend_url"
    sed -i "s|\${BACKEND_URL}|${backend_url}|g" /etc/nginx/nginx.conf
}

# Internal backend

configure_nginx "http://localhost:${BACKEND_INTERNAL_PORT:-8081}"

# External backend

configure_nginx "$BACKEND_URL"

The script supports two operational modes: internal mode for co-located backend services, and external mode for separate backend deployments.

How the Reverse Proxy Works

When the container initializes, the entrypoint executes four critical steps:

  1. Sets up required directories and permissions for file processing.
  2. Copies compiled frontend assets from /app/dist to /usr/share/nginx/html.
  3. Invokes configure_nginx() to substitute the ${BACKEND_URL} placeholder with the target backend address.
  4. Launches nginx in the foreground (daemon off;) to keep the container alive.

This design allows you to expose only port 8080 externally while the backend operates on a separate internal port, simplifying network security and load balancer configuration.

Configuration Scenarios

Internal Backend Mode (Default)

By default, the container runs both nginx and the backend together. The BACKEND_INTERNAL_PORT environment variable (defaulting to 8081) determines where the backend listens, and nginx proxies requests to http://localhost:8081.

External Backend Mode

For deployments where the backend runs separately—such as behind a load balancer or in a different container—set the BACKEND_URL environment variable:

docker run -e BACKEND_URL="http://my-backend.example.com:8081" -p 80:8080 stirlingtools/stirling-pdf:latest-unified

The configure_nginx() function will replace the placeholder with your specified URL before nginx starts.

Custom TLS Termination

Terminate TLS at an upstream reverse proxy (such as Traefik, Cloudflare, or another nginx instance) and configure Stirling-PDF's internal nginx to serve HTTP only. The existing proxy_set_header directives in docker/unified/nginx.conf ensure the backend receives proper forwarding headers including X-Forwarded-Proto.

Implementation Examples

Docker Compose with External Backend

This configuration separates the frontend proxy from the backend service:

version: "3.8"
services:
  stirling-pdf:
    image: stirlingtools/stirling-pdf:latest-unified
    ports:
      - "80:8080"
    environment:
      - BACKEND_URL=http://backend:8081
    depends_on:
      - backend

  backend:
    image: stirlingtools/stirling-pdf:latest
    ports:
      - "8081:8080"

Standalone Docker Run

For a single-container deployment with default internal backend:

docker run -e BACKEND_INTERNAL_PORT=8081 -p 8080:8080 \
  stirlingtools/stirling-pdf:latest-unified

For connecting to an existing external backend:

docker run -e BACKEND_URL="http://my-backend:8081" -p 80:8080 \
  stirlingtools/stirling-pdf:latest-unified

Summary

  • The unified Stirling-PDF image uses docker/unified/nginx.conf to define reverse proxy rules for /api/, /swagger-ui, and OpenAPI documentation paths.
  • The configure_nginx() function in docker/unified/entrypoint.sh dynamically injects backend URLs using sed replacement of the ${BACKEND_URL} placeholder.
  • Internal mode proxies to localhost:${BACKEND_INTERNAL_PORT:-8081} when running the backend inside the same container.
  • External mode uses the BACKEND_URL environment variable to target remote backend services.
  • The default configuration supports 100MB upload sizes via client_max_body_size 100m and disables request buffering for large file handling.

Frequently Asked Questions

How do I change the backend URL in Stirling-PDF?

Set the BACKEND_URL environment variable when starting the container. The configure_nginx() function in docker/unified/entrypoint.sh will substitute this value into the nginx configuration before the server starts, allowing you to point to external backend instances.

What paths does the nginx reverse proxy handle?

According to docker/unified/nginx.conf, nginx proxies three specific patterns to the backend: /api/ for REST endpoints, /swagger-ui for API documentation, and /v*/api-docs for OpenAPI specification files. All other requests serve static frontend files from /usr/share/nginx/html.

Can I use an external reverse proxy like Traefik or Cloudflare?

Yes. Deploy the unified container with BACKEND_URL pointing to your backend, then place your external reverse proxy in front of port 8080. The internal nginx configuration preserves X-Forwarded-* headers, ensuring the Spring Boot backend receives correct client IP and protocol information.

How do I increase the file upload size limit?

Modify the client_max_body_size directive in docker/unified/nginx.conf (currently set to 100m) or mount a custom nginx configuration file. For temporary testing, you can also use a custom nginx config mounted to /etc/nginx/nginx.conf in the container.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →