From cdd5d3ecff8117f79538ff782f148fed838526d5 Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Thu, 27 Aug 2026 12:32:06 -0500 Subject: [PATCH] let services listed in FRIGATE_ROOT_SERVICES skip the privilege drop --- .../main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run | 12 ++++++++++-- docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run | 11 +++++++++-- docker/main/rootfs/etc/s6-overlay/s6-rc.d/nginx/run | 11 +++++++++-- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run index bdd3d7a666..7d060e1723 100755 --- a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run +++ b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run @@ -4,10 +4,18 @@ set -o errexit -o nounset -o pipefail +runs_as_root=0 +if [[ "$(id -u)" -eq 0 ]]; then + if [[ "${FRIGATE_RUN_AS_ROOT:-false}" == "true" ]] || /usr/local/bin/service-runs-as-root frigate; then + runs_as_root=1 + fi +fi + # $HOME is /root from the container env and survives s6-setuidgid, so cache # and telemetry writes (huggingface, openvino) fail after the drop. Set it # before opt_in_out so the opt-out marker lands where the service will look. -if [[ "${FRIGATE_RUN_AS_ROOT:-false}" != "true" ]]; then +# When the service keeps root, /root stays correct. +if [[ "$runs_as_root" -eq 0 ]]; then export HOME=/config fi @@ -37,7 +45,7 @@ cd /opt/frigate || echo "[ERROR] Failed to change working directory to /opt/frig # Replace the bash process with the Frigate process, redirecting stderr to stdout exec 2>&1 -if [[ "$(id -u)" -ne 0 || "${FRIGATE_RUN_AS_ROOT:-false}" == "true" ]]; then +if [[ "$(id -u)" -ne 0 || "$runs_as_root" -eq 1 ]]; then exec python3 -u -m frigate else exec s6-setuidgid frigate python3 -u -m frigate diff --git a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run index f0fea3661a..6c5012feec 100755 --- a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run +++ b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/go2rtc/run @@ -4,6 +4,13 @@ set -o errexit -o nounset -o pipefail +runs_as_root=0 +if [[ "$(id -u)" -eq 0 ]]; then + if [[ "${FRIGATE_RUN_AS_ROOT:-false}" == "true" ]] || /usr/local/bin/service-runs-as-root go2rtc; then + runs_as_root=1 + fi +fi + # Logs should be sent to stdout so that s6 can collect them function get_ip_and_port_from_supervisor() { @@ -110,7 +117,7 @@ fi readonly homekit_config_path="/config/go2rtc_homekit.yml" setup_homekit_config "${homekit_config_path}" -if [[ "$(id -u)" -eq 0 && "${FRIGATE_RUN_AS_ROOT:-false}" != "true" ]]; then +if [[ "$(id -u)" -eq 0 && "$runs_as_root" -eq 0 ]]; then chown go2rtc:go2rtc /dev/shm/go2rtc.yaml 2>/dev/null || true # go2rtc rewrites this in place (os.WriteFile, no rename), so owning the # file is enough; /config grants frigate-data traverse only. Tolerated so @@ -135,7 +142,7 @@ echo "[INFO] Starting go2rtc..." # Use HomeKit config as the primary config so writebacks go there # The main config from Frigate will be loaded as a secondary config exec 2>&1 -if [[ "$(id -u)" -ne 0 || "${FRIGATE_RUN_AS_ROOT:-false}" == "true" ]]; then +if [[ "$(id -u)" -ne 0 || "$runs_as_root" -eq 1 ]]; then exec "${binary_path}" -config="${homekit_config_path}" -config=/dev/shm/go2rtc.yaml else exec s6-setuidgid go2rtc "${binary_path}" -config="${homekit_config_path}" -config=/dev/shm/go2rtc.yaml 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 1367bc6bc5..bed1a8cb85 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 @@ -4,6 +4,13 @@ set -o errexit -o nounset -o pipefail +runs_as_root=0 +if [[ "$(id -u)" -eq 0 ]]; then + if [[ "${FRIGATE_RUN_AS_ROOT:-false}" == "true" ]] || /usr/local/bin/service-runs-as-root nginx; then + runs_as_root=1 + fi +fi + # Logs should be sent to stdout so that s6 can collect them echo "[INFO] Starting NGINX..." @@ -104,7 +111,7 @@ echo "$nginx_settings" | \ tempio -template /usr/local/nginx/templates/listen.gotmpl \ -out /tmp/nginx/conf/listen.conf -if [[ "$(id -u)" -eq 0 && "${FRIGATE_RUN_AS_ROOT:-false}" != "true" ]]; then +if [[ "$(id -u)" -eq 0 && "$runs_as_root" -eq 0 ]]; then chown -R frigate:frigate /tmp/nginx # heal the cache if a root `nginx -t` chowned it (ngx_create_paths chowns # every cycle path to the `user` directive user when run as root) @@ -125,7 +132,7 @@ fi exec 2>&1 # -e stderr: the compile-time default error log under /usr/local/nginx/logs # is not writable by the runtime user and would alert before config load -if [[ "$(id -u)" -ne 0 || "${FRIGATE_RUN_AS_ROOT:-false}" == "true" ]]; then +if [[ "$(id -u)" -ne 0 || "$runs_as_root" -eq 1 ]]; then exec \ s6-notifyoncheck -t 30000 -n 1 \ nginx -e stderr -c /tmp/nginx/conf/nginx.conf