mirror of
https://github.com/calibrain/shelfmark.git
synced 2026-04-19 21:39:17 -04:00
205 lines
7.1 KiB
Markdown
205 lines
7.1 KiB
Markdown
# Reverse Proxy & Subpath Hosting
|
|
|
|
Shelfmark can run behind a reverse proxy at the root path (recommended) or under a subpath like `/shelfmark`.
|
|
|
|
## Root path setup (Recommended)
|
|
|
|
If you can serve Shelfmark at the root path (`https://shelfmark.example.com/`), leave `URL_BASE` empty. This is the simplest option and avoids extra subpath configuration.
|
|
|
|
Define this once in your Nginx `http` block so websocket upgrades are only sent when the client actually requests them:
|
|
|
|
```nginx
|
|
map $http_upgrade $connection_upgrade {
|
|
default upgrade;
|
|
'' close;
|
|
}
|
|
```
|
|
|
|
```nginx
|
|
server {
|
|
listen 443 ssl;
|
|
server_name shelfmark.example.com;
|
|
|
|
location / {
|
|
proxy_pass http://shelfmark:8084;
|
|
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;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection $connection_upgrade;
|
|
}
|
|
}
|
|
```
|
|
|
|
## Subpath setup
|
|
|
|
Running Shelfmark under a subpath like `/shelfmark` is supported without extra rewrite rules.
|
|
|
|
### 1. Set the base path in Shelfmark
|
|
|
|
- **UI**: Settings → Advanced → Base Path → `/shelfmark/`
|
|
- **Environment variable**: `URL_BASE=/shelfmark/`
|
|
|
|
### 2. Configure your reverse proxy
|
|
|
|
All Shelfmark paths (UI, API, assets, Socket.IO) are served under the base path. A single location block is enough.
|
|
|
|
---
|
|
|
|
### Without Authentication Proxy
|
|
|
|
**Complete Nginx configuration for subpath deployment:**
|
|
|
|
```nginx
|
|
location /shelfmark/ {
|
|
proxy_pass http://shelfmark:8084/shelfmark/;
|
|
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;
|
|
proxy_set_header X-Forwarded-Host $host;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection $connection_upgrade;
|
|
proxy_read_timeout 86400;
|
|
proxy_send_timeout 86400;
|
|
proxy_buffering off;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### With Authentication Proxy (Authelia, Authentik, etc.)
|
|
|
|
Shelfmark supports Proxy Authentication. When enabled, Shelfmark trusts the authenticated user from headers set by your auth proxy.
|
|
|
|
#### Shelfmark Settings
|
|
|
|
Configure in Settings → Security:
|
|
|
|
| Setting | Value |
|
|
|---------|-------|
|
|
| Authentication Method | Proxy Authentication |
|
|
| Proxy Auth User Header | `Remote-User` |
|
|
| Proxy Auth Logout URL | `https://auth.example.com/logout` |
|
|
| Proxy Auth Admin Group Header | `Remote-Groups` |
|
|
| Proxy Auth Admin Group Name | `admins` (or your admin group) |
|
|
|
|
#### Nginx Configuration with Authelia
|
|
|
|
This example uses Authelia snippets. Adapt for your auth proxy.
|
|
|
|
**Authelia auth request snippet** (`/etc/nginx/snippets/authelia-authrequest.conf`):
|
|
|
|
```nginx
|
|
location /authelia {
|
|
internal;
|
|
proxy_pass http://authelia:9091/api/authz/auth-request;
|
|
proxy_pass_request_body off;
|
|
proxy_set_header Content-Length "";
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
|
|
proxy_set_header X-Original-Method $request_method;
|
|
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;
|
|
}
|
|
```
|
|
|
|
**Authelia location snippet** (`/etc/nginx/snippets/authelia-location.conf`):
|
|
|
|
```nginx
|
|
auth_request /authelia;
|
|
auth_request_set $target_url $scheme://$http_host$request_uri;
|
|
auth_request_set $user $upstream_http_remote_user;
|
|
auth_request_set $groups $upstream_http_remote_groups;
|
|
auth_request_set $name $upstream_http_remote_name;
|
|
auth_request_set $email $upstream_http_remote_email;
|
|
proxy_set_header Remote-User $user;
|
|
proxy_set_header Remote-Groups $groups;
|
|
proxy_set_header Remote-Name $name;
|
|
proxy_set_header Remote-Email $email;
|
|
error_page 401 =302 https://auth.example.com/?rd=$target_url;
|
|
```
|
|
|
|
**Complete Nginx configuration with Authelia:**
|
|
|
|
```nginx
|
|
# Include Authelia auth endpoint in your server block
|
|
include /etc/nginx/snippets/authelia-authrequest.conf;
|
|
|
|
# Main shelfmark location
|
|
location /shelfmark/ {
|
|
include /etc/nginx/snippets/authelia-location.conf;
|
|
|
|
proxy_pass http://shelfmark:8084/shelfmark/;
|
|
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;
|
|
proxy_set_header X-Forwarded-Host $host;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection $connection_upgrade;
|
|
proxy_read_timeout 86400;
|
|
proxy_send_timeout 86400;
|
|
proxy_buffering off;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting false network errors
|
|
|
|
If login, settings saves, or downloads appear to fail in the browser but the action still completes on the server, check your proxy headers first.
|
|
|
|
- Do not force `Connection: upgrade` on every request. That can break normal `POST` and `PUT` responses while the backend still processes them.
|
|
- If your proxy UI does not support conditional websocket headers, remove the forced websocket headers entirely and let Shelfmark fall back to polling.
|
|
- Keep the standard forwarded headers: `Host`, `X-Forwarded-For`, `X-Forwarded-Proto`, and `X-Forwarded-Host` when using a subpath or OIDC.
|
|
|
|
This is especially relevant for Nginx Proxy Manager or custom advanced config snippets that add websocket headers globally.
|
|
|
|
### Nginx Proxy Manager
|
|
|
|
If you are using Nginx Proxy Manager and see errors like "proxy interrupted the response", slow UI interactions, or missing real-time updates:
|
|
|
|
- Do not force `Connection: upgrade` in the main proxy host config.
|
|
- Keep the normal Shelfmark proxy host for `/` or `/shelfmark/`.
|
|
- Add a dedicated Socket.IO location block in the Proxy Host's Advanced config so Socket.IO can negotiate correctly.
|
|
- Match the location to your public path: use `location /socket.io/` at the root path, or `location /shelfmark/socket.io/` if you run Shelfmark under `/shelfmark`.
|
|
- If you use an auth proxy such as Authentik or Authelia, keep the same `auth_request` logic inside the `/socket.io/` block too.
|
|
|
|
Example Advanced config snippet for a root-path install:
|
|
|
|
```nginx
|
|
location /socket.io/ {
|
|
auth_request /authelia;
|
|
auth_request_set $target_url $scheme://$http_host$request_uri;
|
|
auth_request_set $user $upstream_http_remote_user;
|
|
auth_request_set $groups $upstream_http_remote_groups;
|
|
auth_request_set $name $upstream_http_remote_name;
|
|
auth_request_set $email $upstream_http_remote_email;
|
|
proxy_set_header Remote-User $user;
|
|
proxy_set_header Remote-Groups $groups;
|
|
proxy_set_header Remote-Name $name;
|
|
proxy_set_header Remote-Email $email;
|
|
|
|
proxy_pass http://shelfmark:8084;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
proxy_set_header Host $host;
|
|
proxy_cache_bypass $http_upgrade;
|
|
}
|
|
```
|
|
|
|
Adapt the auth-related lines for your setup. If you are not using proxy authentication, you can omit the `auth_request` and `Remote-*` header lines.
|
|
|
|
---
|
|
|
|
## Health checks
|
|
|
|
Health checks work at `/shelfmark/api/health` when using a subpath configuration.
|