---
title: Reverse Proxy
description: "Serve your documentation at /docs using nginx, Apache, Caddy, Traefik, or HAProxy. Includes tested configuration snippets for each reverse proxy."
---

> **For AI agents:** the complete documentation index is at [llms.txt](/docs/llms.txt). Append `.md` to any page URL for its markdown version.

If you already run nginx, Apache, Caddy, Traefik, or HAProxy, add a location/route block that forwards `/docs` traffic to your Jamdesk subdomain.

## Prerequisites

- Access to your web server configuration
- Your Jamdesk subdomain (found in dashboard settings)

## nginx

Add a location block to proxy `/docs` requests to Jamdesk:

```nginx nginx.conf
server {
    listen 443 ssl;
    server_name yoursite.com;

    # Your existing configuration...

    # Proxy /docs to Jamdesk
    location /docs {
        proxy_pass https://YOUR_SLUG.jamdesk.app;
        proxy_ssl_server_name on;

        proxy_set_header Host YOUR_SLUG.jamdesk.app;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        # Required for domain verification
        proxy_set_header X-Jamdesk-Forwarded-Host $host;
    }

    # Next.js static assets (JS, CSS)
    location /_next/ {
        proxy_pass https://YOUR_SLUG.jamdesk.app;
        proxy_ssl_server_name on;
        proxy_set_header Host YOUR_SLUG.jamdesk.app;
    }

    # Jamdesk assets (fonts, images, branding)
    location /_jd/ {
        proxy_pass https://YOUR_SLUG.jamdesk.app;
        proxy_ssl_server_name on;
        proxy_set_header Host YOUR_SLUG.jamdesk.app;
    }

}
```

<Note>
Replace `YOUR_SLUG` with your actual Jamdesk subdomain.
</Note>

<Warning>
**Path handling matters.** The `proxy_pass` URL has no trailing path, so nginx preserves the original request path. A request to `/docs/page` proxies to `jamdesk.app/docs/page`. If you add a trailing slash (`proxy_pass https://...jamdesk.app/`), the `/docs` prefix gets stripped. Keep it exactly as shown above.
</Warning>

After updating your configuration, reload nginx:

```bash
sudo nginx -t && sudo systemctl reload nginx
```

## Apache

Use `mod_proxy` to forward `/docs` requests to Jamdesk:

```apache httpd.conf or .htaccess
<VirtualHost *:443>
    ServerName yoursite.com

    # Your existing configuration...

    # Enable proxy modules
    ProxyRequests Off
    SSLProxyEngine On

    # Proxy /docs to Jamdesk
    ProxyPass /docs https://YOUR_SLUG.jamdesk.app/docs
    ProxyPassReverse /docs https://YOUR_SLUG.jamdesk.app/docs

    # Next.js static assets (JS, CSS)
    ProxyPass /_next https://YOUR_SLUG.jamdesk.app/_next
    ProxyPassReverse /_next https://YOUR_SLUG.jamdesk.app/_next

    # Jamdesk assets (fonts, images, branding)
    ProxyPass /_jd https://YOUR_SLUG.jamdesk.app/_jd
    ProxyPassReverse /_jd https://YOUR_SLUG.jamdesk.app/_jd

    <Location /docs>
        RequestHeader set X-Forwarded-Host "yoursite.com"
        RequestHeader set X-Forwarded-Proto "https"
        # Required for domain verification
        RequestHeader set X-Jamdesk-Forwarded-Host "yoursite.com"
    </Location>
</VirtualHost>
```

Ensure the required modules are enabled:

```bash
sudo a2enmod proxy proxy_http ssl headers
sudo systemctl reload apache2
```

## Caddy

[Caddy](https://caddyserver.com/) provides simple reverse proxy configuration with automatic HTTPS:

```caddy Caddyfile
yoursite.com {
    # Your existing configuration...

    handle /docs* {
        reverse_proxy https://YOUR_SLUG.jamdesk.app {
            header_up Host {upstream_hostport}
            header_up X-Forwarded-Host {host}
            # Required for domain verification
            header_up X-Jamdesk-Forwarded-Host {host}
        }
    }

    # Next.js static assets and Jamdesk assets
    handle /_next/* {
        reverse_proxy https://YOUR_SLUG.jamdesk.app {
            header_up Host {upstream_hostport}
        }
    }

    handle /_jd/* {
        reverse_proxy https://YOUR_SLUG.jamdesk.app {
            header_up Host {upstream_hostport}
        }
    }

    # Handle other routes
    handle {
        # Your main site configuration
    }
}
```

Reload Caddy after changes:

```bash
sudo systemctl reload caddy
```

## Traefik

For [Traefik](https://traefik.io/) users, configure a router and service:

```yaml traefik.yml
http:
  routers:
    docs-router:
      rule: "Host(`yoursite.com`) && (PathPrefix(`/docs`) || PathPrefix(`/_next`) || PathPrefix(`/_jd`))"
      service: jamdesk-docs
      tls: {}

  services:
    jamdesk-docs:
      loadBalancer:
        servers:
          - url: "https://YOUR_SLUG.jamdesk.app"
        passHostHeader: false
```

## HAProxy

For [HAProxy](https://www.haproxy.org/), add backend and ACL rules:

```haproxy haproxy.cfg
frontend https
    bind *:443 ssl crt /etc/ssl/certs/yoursite.pem

    # Route /docs and assets to Jamdesk backend
    acl is_docs path_beg /docs
    acl is_next path_beg /_next
    acl is_jd path_beg /_jd
    use_backend jamdesk_docs if is_docs or is_next or is_jd

    # Default backend for other requests
    default_backend main_site

backend jamdesk_docs
    server jamdesk YOUR_SLUG.jamdesk.app:443 ssl verify none
    http-request set-header Host YOUR_SLUG.jamdesk.app
    http-request set-header X-Forwarded-Host %[req.hdr(host)]
    # Required for domain verification
    http-request set-header X-Jamdesk-Forwarded-Host %[req.hdr(host)]
```

## Required Headers

Regardless of which proxy you use, ensure these headers are set:

| Header | Value | Purpose |
|--------|-------|---------|
| `Host` | `YOUR_SLUG.jamdesk.app` | Identifies the request to Jamdesk |
| `X-Forwarded-Host` | Your domain | Tells Jamdesk which domain to use in URLs |
| `X-Forwarded-Proto` | `https` | Ensures secure URL generation |
| `X-Jamdesk-Forwarded-Host` | Your domain | Required for domain verification |

<Warning>
The `X-Jamdesk-Forwarded-Host` header is **required**. It enables:
- Domain verification (your domain must be registered in the dashboard)
- Correct URL generation for links and assets
- Proper configuration from your dashboard settings

Without this header, requests will be rejected with a 403 error.
</Warning>

<Tip>
The proxy configuration is a **one-time setup**. If you later change your custom domain or configuration in the Jamdesk dashboard, the proxy doesn't need to be updated - all routing decisions are made server-side based on your dashboard settings.
</Tip>

## Troubleshooting

<Accordion title="502 Bad Gateway">
Verify the proxy can reach `YOUR_SLUG.jamdesk.app` over HTTPS. Check firewall rules and DNS resolution.
</Accordion>

<Accordion title="SSL certificate errors">
Enable SSL/TLS for the upstream connection. For nginx, add `proxy_ssl_server_name on;`. For Apache, enable `SSLProxyEngine On`.
</Accordion>

<Accordion title="Assets loading from wrong domain">
Ensure the `X-Forwarded-Host` header is set correctly. This tells Jamdesk which domain to use for asset URLs and internal links.
</Accordion>

<Accordion title="Redirect loops">
Check that your proxy isn't following redirects. The proxy should forward the response as-is without additional redirect handling.
</Accordion>

<Accordion title="403 Domain not authorized error">
If you see "Domain is not authorized to serve this content":

1. Verify your domain is registered in the Jamdesk dashboard
2. Complete DNS verification (TXT record) for your domain
3. Ensure the `X-Jamdesk-Forwarded-Host` header is set in your proxy configuration
4. Check that your domain maps to the correct project

The domain must be verified before the proxy can serve documentation.
</Accordion>

## What's Next?

<Columns cols={3}>
  <Card title="Deployment Overview" icon="cloud-arrow-up" href="/deploy/overview">
    Compare hosting options
  </Card>
  <Card title="Subpath Hosting" icon="folder-tree" href="/deploy/subpath-hosting">
    Serve docs at /docs
  </Card>
  <Card title="Custom Domains" icon="globe" href="/deploy/custom-domains">
    Verify DNS and troubleshoot
  </Card>
</Columns>
