# Reverse Proxy
Source: https://dorkos.ai/docs/self-hosting/reverse-proxy

Put DorkOS on your own domain with HTTPS, using nginx or Caddy



# Reverse Proxy [#reverse-proxy]

Want DorkOS to live at `dorkos.example.com` instead of a bare port number, with a real HTTPS certificate? That's what a reverse proxy does: it sits in front of DorkOS and forwards traffic to it. This page covers the two most common ones, Caddy and nginx.

You only need this page if you're self-hosting on your own domain, or running DorkOS alongside other services on the same machine. Just testing on `localhost`? Skip it. Want remote access without setting up a domain at all? See [Tunnel Setup](/docs/self-hosting/tunnel-setup) instead.

DorkOS streams agent output live as it works, using a technique called SSE (Server-Sent Events). Most reverse proxies buffer that stream by default, which turns live output into one big delayed dump at the end. The configs below turn buffering off, so don't skip that part.

<Callout type="warn">
  Default proxy settings will break live streaming. It's a one-line fix, not a rabbit hole: the
  configurations below include the directive you need.
</Callout>

## Proxy Configuration [#proxy-configuration]

<Tabs items="[&#x22;Caddy (Recommended)&#x22;, &#x22;nginx&#x22;]">
  <Tab value="Caddy (Recommended)">
    Caddy handles HTTPS certificates automatically and has good SSE support out of the box.

    ```
    dorkos.example.com {
        reverse_proxy localhost:4242 {
            flush_interval -1
        }
    }
    ```

    `flush_interval -1` disables response buffering, which is required for SSE streams.
  </Tab>

  <Tab value="nginx">
    ```nginx
    server {
        listen 443 ssl;
        server_name dorkos.example.com;

        ssl_certificate /path/to/cert.pem;
        ssl_certificate_key /path/to/key.pem;

        location / {
            proxy_pass http://localhost:4242;
            proxy_http_version 1.1;
            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;

            # Required for SSE: disable buffering and set long timeouts
            proxy_buffering off;
            proxy_cache off;
            proxy_read_timeout 86400s;
            proxy_send_timeout 86400s;

            proxy_set_header Connection '';
            chunked_transfer_encoding off;
        }

    }

    ```
  </Tab>
</Tabs>

<Callout type="info">
  Running DorkOS on your own domain, behind this proxy? Set `DORKOS_PUBLIC_URL` to that domain
  (for example `https://dorkos.example.com`). Without it, DorkOS advertises its internal bind
  address instead of your real URL wherever it needs to share a link to itself. See
  [Deployment](/docs/self-hosting/deployment) for how to set environment variables.

  If DorkOS itself is running in Docker, `localhost:4242` in the configs above needs to become
  the container's name (for example `dorkos:4242`) or its address on the Docker network instead.
  See [Docker](/docs/self-hosting/docker) for a worked example.
</Callout>

## Key SSE Settings (nginx) [#key-sse-settings-nginx]

Most people never touch these once the config above is working. Here's what each line does, if you're curious:

<TypeTable
  type="{
&#x22;proxy_buffering off&#x22;: { type: &#x22;directive&#x22;, description: &#x22;Disables response buffering so SSE events are sent immediately&#x22; },
&#x22;proxy_cache off&#x22;: { type: &#x22;directive&#x22;, description: &#x22;Disables caching, SSE streams must never be cached&#x22; },
&#x22;proxy_read_timeout 86400s&#x22;: { type: &#x22;directive&#x22;, description: &#x22;24-hour timeout for long-lived SSE connections&#x22; },
&#x22;Connection ''&#x22;: { type: &#x22;header&#x22;, description: &#x22;Empty connection header prevents premature connection close&#x22; },
&#x22;chunked_transfer_encoding off&#x22;: { type: &#x22;directive&#x22;, description: &#x22;Disables chunked encoding, SSE uses its own framing&#x22; },
}"
/>

## Common Issues [#common-issues]

<Steps>
  <Step>
    ### SSE events arrive in batches instead of real-time [#sse-events-arrive-in-batches-instead-of-real-time]

    **Cause**: Response buffering is enabled in the proxy.

    **Fix**: Set `proxy_buffering off` (nginx) or `flush_interval -1` (Caddy).
  </Step>

  <Step>
    ### Connection drops after 60 seconds [#connection-drops-after-60-seconds]

    **Cause**: Default proxy timeout is too short for SSE.

    **Fix**: Increase `proxy_read_timeout` to at least `3600s`.
  </Step>

  <Step>
    ### 502 Bad Gateway on long requests [#502-bad-gateway-on-long-requests]

    **Cause**: Upstream timeout is shorter than the Claude response time.

    **Fix**: Increase both `proxy_read_timeout` and `proxy_send_timeout`.
  </Step>
</Steps>

## HTTPS with Let's Encrypt [#https-with-lets-encrypt]

<Tabs items="[&#x22;Caddy (Automatic)&#x22;, &#x22;nginx + certbot&#x22;]">
  <Tab value="Caddy (Automatic)">
    Point your domain's DNS to the server and Caddy obtains and renews certificates automatically. The Caddy config above already handles this: no separate step needed.
  </Tab>

  <Tab value="nginx + certbot">
    ```bash
    sudo certbot --nginx -d dorkos.example.com
    ```

    Certbot modifies your nginx config to add SSL directives and sets up automatic renewal.
  </Tab>
</Tabs>

## Next Steps [#next-steps]

<Cards>
  <Card title="Deployment" href="/docs/self-hosting/deployment">
    Production deployment with systemd, environment variables, and health checks.
  </Card>

  <Card title="Tunnel Setup" href="/docs/self-hosting/tunnel-setup">
    Remote access via ngrok without a reverse proxy.
  </Card>

  <Card title="SSE Protocol" href="/docs/integrations/sse-protocol">
    Full SSE protocol reference for the streaming wire format.
  </Card>
</Cards>
