# Remote access with nginx or SWAG

Put your *arr stack behind an nginx reverse proxy (including LinuxServer's SWAG), subdomain or subpath routing, and how to configure Kochab for either shape.

Canonical: https://kochab.io/docs/remote-access-nginx-swag/

import Callout from '@components/Callout.astro';

Plain nginx works, and SWAG (LinuxServer's nginx
image with certbot and pre-built app configs baked in) bundles the same nginx with certificate
renewal and templates handled for you. Both use the same server-block syntax, so this guide
covers both. For installing nginx or SWAG and the full directive reference, see the
[nginx docs](https://nginx.org/en/docs/) and
[SWAG's own documentation](https://docs.linuxserver.io/general/swag/).

## Minimal server block

### A subdomain per service

```nginx
server {
    listen 443 ssl;
    server_name sonarr.example.com;

    ssl_certificate     /etc/letsencrypt/live/sonarr.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/sonarr.example.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8989;
        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;
    }
}
```

<Callout>

SWAG ships a ready-made config for most *arr apps under
`/config/nginx/proxy-confs/*.subdomain.conf.sample` - copy the sample and drop the `.sample`
suffix. Most of them work without modification (certbot already manages the certificate paths),
so prefer them over writing the block above by hand.

</Callout>

### One hostname, a path per service

The block below is a `location` fragment, meant to sit inside a `server {}` block you already
have (the one above, with `location /` removed) - not a file on its own.

```nginx
location /sonarr/ {
    proxy_pass http://127.0.0.1:8989;
    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;
}
```

The trailing slash matters twice over. `location /sonarr/` (with the slash) matches only requests
that start with `/sonarr/`. `proxy_pass http://127.0.0.1:8989;` (with no path after the port)
passes the request through with `/sonarr/` still in it, instead of stripping it. Sonarr's own
**URL Base** setting needs to be `/sonarr` too, so the proxy and the service agree on what the
path means.

## Configure Kochab

Follow [Add and configure a service](/docs/add-a-service/):

- **Subdomain shape:** enter `https://sonarr.example.com`, no base path.
- **Subpath shape:** set Sonarr's **URL Base** to `/sonarr` in *Settings > General > Host*
  first, then give Kochab the same path - the `location` block, Sonarr and Kochab all have to
  name the same prefix. See
  [Reverse proxies and remote access](/docs/remote-access/#pick-the-shape-you-already-run) for
  how to enter it.

With a real certificate from certbot (SWAG runs this for you), Kochab validates it with no
prompt. Plain nginx with a self-signed certificate you generated by hand is common too - see
[Certificate trust](/docs/cert-trust/) for what Kochab does with that. If nginx is reachable only
from outside your home network, see [Home and away](/docs/remote-access/#home-and-away) for where
that hostname goes instead of the primary address.

## A login gate in front of nginx

`auth_request` pointed at Authelia or Authentik, or nginx's own `auth_basic`, answers Kochab's
requests the same way it answers a signed-out browser: a login page instead of data. Add a second
`location` block for the API path that skips the `auth_request` or `auth_basic` directive while
the rest of the server block keeps it - see
[the bypass fix in the remote-access guide](/docs/remote-access/#the-fix-let-the-api-through),
which also covers the two gates (Cloudflare Access, Pangolin) Kochab can authenticate against
directly instead.

## Verify and troubleshoot

Run **Test & Add**. If it fails, work through
[Why won't Kochab connect to my service?](/docs/troubleshooting/service-wont-connect/) - for the
subpath shape, check the trailing slashes in nginx first: `location /sonarr/` and a `proxy_pass`
with a path after the port strip the prefix, which then disagrees with the URL Base Sonarr still
expects. See
[It works in a browser but Kochab says it's offline](/docs/troubleshooting/works-in-browser-not-kochab/)
if the service loads fine in a browser but Kochab still reports it offline.