diff --git a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run index 677126a6d..273182930 100755 --- a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run +++ b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run @@ -79,6 +79,11 @@ if [ ! \( -f "$letsencrypt_path/privkey.pem" -a -f "$letsencrypt_path/fullchain. -keyout "$letsencrypt_path/privkey.pem" -out "$letsencrypt_path/fullchain.pem" 2>/dev/null fi +# build templates for optional FRIGATE_BASE_PATH environment variable +python3 /usr/local/nginx/get_base_path.py | \ + tempio -template /usr/local/nginx/templates/base_path.gotmpl \ + -out /usr/local/nginx/conf/base_path.conf + # build templates for optional TLS support python3 /usr/local/nginx/get_tls_settings.py | \ tempio -template /usr/local/nginx/templates/listen.gotmpl \ diff --git a/docker/main/rootfs/usr/local/nginx/conf/nginx.conf b/docker/main/rootfs/usr/local/nginx/conf/nginx.conf index 8a98da1f2..64d6396b2 100644 --- a/docker/main/rootfs/usr/local/nginx/conf/nginx.conf +++ b/docker/main/rootfs/usr/local/nginx/conf/nginx.conf @@ -96,6 +96,7 @@ http { gzip_types application/vnd.apple.mpegurl; include auth_location.conf; + include base_path.conf; location /vod/ { include auth_request.conf; @@ -299,6 +300,18 @@ http { add_header Cache-Control "public"; } + location ~ ^/.*-([A-Za-z0-9]+)\.webmanifest$ { + access_log off; + expires 1y; + add_header Cache-Control "public"; + default_type application/json; + proxy_set_header Accept-Encoding ""; + sub_filter_once off; + sub_filter_types application/json; + sub_filter '"start_url": "/"' '"start_url" : "$http_x_ingress_path"'; + sub_filter '"src": "/' '"src": "$http_x_ingress_path/'; + } + sub_filter 'href="/BASE_PATH/' 'href="$http_x_ingress_path/'; sub_filter 'url(/BASE_PATH/' 'url($http_x_ingress_path/'; sub_filter '"/BASE_PATH/dist/' '"$http_x_ingress_path/dist/'; diff --git a/docker/main/rootfs/usr/local/nginx/get_base_path.py b/docker/main/rootfs/usr/local/nginx/get_base_path.py new file mode 100644 index 000000000..e6fc8cfc6 --- /dev/null +++ b/docker/main/rootfs/usr/local/nginx/get_base_path.py @@ -0,0 +1,10 @@ +"""Prints the base path as json to stdout.""" + +import json +import os + +base_path = os.environ.get("FRIGATE_BASE_PATH", "") + +result: dict[str, any] = {"base_path": base_path} + +print(json.dumps(result)) diff --git a/docker/main/rootfs/usr/local/nginx/templates/base_path.gotmpl b/docker/main/rootfs/usr/local/nginx/templates/base_path.gotmpl new file mode 100644 index 000000000..ace4443ee --- /dev/null +++ b/docker/main/rootfs/usr/local/nginx/templates/base_path.gotmpl @@ -0,0 +1,19 @@ +{{ if .base_path }} +location = {{ .base_path }} { + return 302 {{ .base_path }}/; +} + +location ^~ {{ .base_path }}/ { + # remove base_url from the path before passing upstream + rewrite ^{{ .base_path }}/(.*) /$1 break; + + proxy_pass $scheme://127.0.0.1:8971; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Ingress-Path {{ .base_path }}; + + access_log off; +} +{{ end }} diff --git a/docs/docs/configuration/advanced.md b/docs/docs/configuration/advanced.md index c889d2d26..1e128e0e3 100644 --- a/docs/docs/configuration/advanced.md +++ b/docs/docs/configuration/advanced.md @@ -172,6 +172,38 @@ listen [::]:8971 ipv6only=off ssl; listen [::]:5000 ipv6only=off; ``` +## Base path + +By default, Frigate runs at the root path (`/`). However some setups require to run Frigate under a custom path prefix (e.g. `/frigate`), especially when Frigate is located behind a reverse proxy that requires path-based routing. + +### Set Base Path via HTTP Header +The preferred way to configure the base path is through the `X-Ingress-Path` HTTP header, which needs to be set to the desired base path in an upstream reverse proxy. + +For example, in Nginx: +``` +location /frigate { + proxy_set_header X-Ingress-Path /frigate; + proxy_pass http://frigate_backend; +} +``` + +### Set Base Path via Environment Variable +When it is not feasible to set the base path via a HTTP header, it can also be set via the `FRIGATE_BASE_PATH` environment variable in the Docker Compose file. + +For example: +``` +services: + frigate: + image: blakeblackshear/frigate:latest + environment: + - FRIGATE_BASE_PATH=/frigate +``` + +This can be used for example to access Frigate via a Tailscale agent (https), by simply forwarding all requests to the base path (http): +``` +tailscale serve --https=443 --bg --set-path /frigate http://localhost:5000/frigate +``` + ## Custom Dependencies ### Custom ffmpeg build