Skip to content

Commit d8fcb22

Browse files
committed
fix(frigate): s6 management
1 parent 5526727 commit d8fcb22

6 files changed

Lines changed: 108 additions & 10 deletions

File tree

kubernetes/apps/frigate/config.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@ objects:
3737

3838
record:
3939
enabled: true
40-
retain:
40+
# 0.17 replaced record.retain with continuous/motion blocks.
41+
continuous:
4142
days: 3
42-
mode: motion
43+
motion:
44+
days: 7
4345
alerts:
4446
retain:
4547
days: 30

kubernetes/apps/frigate/flux-kustomization.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ spec:
1717
substitute:
1818
APP: *app
1919
CLAIM: config-frigate-0
20-
VOLSYNC_PUID: "0"
21-
VOLSYNC_PGID: "0"
20+
VOLSYNC_PUID: "1026"
21+
VOLSYNC_PGID: "100"
2222
VOLSYNC_CAPACITY: "5Gi"
2323
VOLSYNC_CACHE_CAPACITY: "5Gi"
2424
patches:

kubernetes/apps/frigate/helm-release.yml

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,38 @@ spec:
3434
name: "${APP}"
3535
globalMounts:
3636
- path: /config
37-
containers:
38-
app:
39-
image:
37+
initContainers:
38+
# Copy the GitOps-managed config into the writable /config PVC.
39+
init-config:
40+
image: &image
4041
repository: ghcr.io/blakeblackshear/frigate
4142
tag: 0.17.2
4243
pullPolicy: IfNotPresent
44+
command:
45+
- /bin/bash
46+
- -c
47+
- cp -f /tmp/frigate-config/config.yml /config/config.yml
48+
# Seed a writable copy of nginx's tree so the non-root user can
49+
# write runtime/log/temp files under /usr/local/nginx.
50+
init-nginx:
51+
image: *image
52+
command:
53+
- /bin/bash
54+
- -c
55+
- cp -Rf /usr/local/nginx/. /nginx/
56+
containers:
57+
app:
58+
image: *image
4359
envFrom:
4460
- secretRef:
4561
name: frigate
4662
env:
4763
TZ: America/New_York
64+
# Non-root (s6-overlay) plumbing — see s6-* override scripts.
65+
HOME: /tmp/home
66+
USER: &uid "1026"
67+
S6_CATCHALL_USER: *uid
68+
S6_YES_I_WANT_A_WORLD_WRITABLE_RUN_BECAUSE_KUBERNETES: "1"
4869
probes:
4970
liveness: &probes
5071
enabled: true
@@ -67,6 +88,11 @@ spec:
6788
port: *port
6889
failureThreshold: 30
6990
periodSeconds: 10
91+
securityContext:
92+
allowPrivilegeEscalation: false
93+
capabilities:
94+
drop:
95+
- ALL
7096
resources:
7197
requests:
7298
gpu.intel.com/i915: 1
@@ -77,7 +103,18 @@ spec:
77103
memory: 4Gi
78104
defaultPodOptions:
79105
automountServiceAccountToken: false
80-
# hostUsers: false
106+
# Run as the NAS-owning user (1026:100) — matching the arr apps — so
107+
# Frigate writes recordings to NFS under standard root_squash instead
108+
# of running as root. Frigate's s6-overlay image needs the s6-* script
109+
# overrides + HOME/S6_* env + writable /run,/usr/local/nginx,/tmp/home.
110+
securityContext:
111+
runAsUser: 1026
112+
runAsGroup: &gid 100
113+
fsGroup: *gid
114+
fsGroupChangePolicy: OnRootMismatch
115+
runAsNonRoot: true
116+
seccompProfile:
117+
type: RuntimeDefault
81118
service:
82119
app:
83120
controller: frigate
@@ -105,8 +142,19 @@ spec:
105142
type: configMap
106143
name: frigate-configmap
107144
globalMounts:
108-
- path: /config/config.yml
109-
subPath: config.yml
145+
- path: /tmp/frigate-config
146+
readOnly: true
147+
# s6-overlay override scripts (executable) for non-root operation.
148+
s6-scripts:
149+
type: configMap
150+
name: frigate-s6-scripts
151+
defaultMode: 0555
152+
globalMounts:
153+
- path: /etc/s6-overlay/s6-rc.d/log-prepare/run
154+
subPath: run
155+
readOnly: true
156+
- path: /package/admin/s6/command/s6-applyuidgid
157+
subPath: s6-applyuidgid
110158
readOnly: true
111159
media:
112160
type: nfs
@@ -126,3 +174,25 @@ spec:
126174
sizeLimit: 512Mi
127175
globalMounts:
128176
- path: /dev/shm
177+
# Writable dirs the non-root user needs (stock image expects root here).
178+
run:
179+
type: emptyDir
180+
medium: Memory
181+
globalMounts:
182+
- path: /run
183+
home:
184+
type: emptyDir
185+
globalMounts:
186+
- path: /tmp/home
187+
letsencrypt:
188+
type: emptyDir
189+
globalMounts:
190+
- path: /etc/letsencrypt
191+
nginx:
192+
type: emptyDir
193+
advancedMounts:
194+
frigate:
195+
init-nginx:
196+
- path: /nginx
197+
app:
198+
- path: /usr/local/nginx

kubernetes/apps/frigate/kustomization.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ configMapGenerator:
99
- name: frigate-configmap
1010
files:
1111
- config.yml=./config.yml
12+
# s6-overlay override scripts required to run Frigate as a non-root UID.
13+
- name: frigate-s6-scripts
14+
files:
15+
- run=./s6-log-prepare-run
16+
- s6-applyuidgid=./s6-applyuidgid
1217
generatorOptions:
1318
disableNameSuffixHash: true
1419
annotations:
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash
2+
# Non-root override for /package/admin/s6/command/s6-applyuidgid.
3+
# s6 cannot switch uid/gid without privileges when the container already
4+
# runs as a non-root user, so drop the leading uid/gid args and exec the
5+
# target program directly.
6+
ARGS=( "$@" )
7+
exec ${ARGS[@]:2}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/command/with-contenv bash
2+
set -o errexit -o nounset -o pipefail
3+
4+
# Non-root override for /etc/s6-overlay/s6-rc.d/log-prepare/run.
5+
# The stock script chowns/chmods the log dirs, which fails when Frigate
6+
# runs as a non-root UID. Just create the directories.
7+
dirs=(
8+
/dev/shm/logs/frigate
9+
/dev/shm/logs/go2rtc
10+
/dev/shm/logs/nginx
11+
/dev/shm/logs/certsync
12+
)
13+
14+
mkdir -p "${dirs[@]}"

0 commit comments

Comments
 (0)