Open felixc opened 2 years ago
I am well aware that running as root isn't a best security practice, but t isn't that simple since frigate requires access to Coral hardware and GPU for decoding video.
@blakeblackshear it should just be adding the group permission to the user and mounting/adding the device to the container.
Probably video
or dialout
.
Are you able to do a ls -l
on the coral device under /dev
?
EDIT:
Having a look at the TensorFlow Docker page it might even just be adding --gpus all
.
Yep. I know how to do it.
OK I must be misunderstanding or missing some information. What is the bit that makes it not simple?
Different users run different hardware. Each user will need to know which groups to pass to the container. If you don't install the driver on the host, the groups aren't created for the USB device. Some users will need to modify udev rules to make things sure the group is applied to the device.
video
group
udev
and relies on the host for the hardwareintel
, amd
, coral and nvidia
for drivers
I miss read your reply, sorry about that. I can also see you have done a lot of work in the documentation around this.
I think there is wriggle room here though:
intel
and amd
For that second image it should just be what @felixc said above and --gpus all
or am I still missing something here?
You can set the user and groups at runtime with docker to override the default in the container. There isn't really a need to build a separate container. I would still like to eventually use non-root users by default, but it's just not a priority.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
You can set the user and groups at runtime with docker to override the default in the container. There isn't really a need to build a separate container. I would still like to eventually use non-root users by default, but it's just not a priority.
This doesn't work. Container start up fails for the following:
frigate | chown: changing ownership of '/dev/shm/logs/frigate': Operation not permitted
frigate | chown: changing ownership of '/dev/shm/logs/go2rtc': Operation not permitted
frigate | chown: changing ownership of '/dev/shm/logs/nginx': Operation not permitted
So we have to run frigate as root
for now.
Yeah, I get the same thing as @patrickli when setting user:
in docker compose to my local (non-root) user.
Is there any way around this?
I really want the recordings/snapshots frigate makes to save as my user, so I don't need root (or sudo) to move them to my backup setup. (frigate doesn't notice the move as it's behind mergerfs)
I haven't tested this but in the start up script, just don't do chown
if the running user is not root. The culprit is this line https://github.com/blakeblackshear/frigate/blob/dev/docker/rootfs/etc/s6-overlay/s6-rc.d/log-prepare/run#L10. It basically tries to make these directories unprivileged. But we are already running unprivileged.
Good point. I tried commenting out the chown
there, but seems to cause other issues.
frigate | s6-rc: info: service go2rtc: starting
frigate | s6-rc: info: service go2rtc successfully started
frigate | s6-rc: info: service go2rtc-healthcheck: starting
frigate | s6-rc: info: service frigate: starting
frigate | s6-applyuidgid: fatal: unable to set supplementary group list: Operation not permitted
frigate | s6-rc: info: service frigate successfully started
frigate | s6-rc: info: service nginx: starting
frigate | s6-applyuidgid: fatal: unable to set supplementary group list: Operation not permitted
frigate | s6-rc: info: service go2rtc-healthcheck successfully started
frigate | s6-rc: info: service nginx successfully started
frigate | s6-rc: info: service legacy-services: starting
frigate | s6-applyuidgid: fatal: unable to set supplementary group list: Operation not permitted
frigate | s6-rc: info: service legacy-services successfully started
frigate | s6-rc: info: service legacy-services: stopping
frigate | s6-rc: info: service legacy-services successfully stopped
frigate | s6-rc: info: service nginx: stopping
frigate | s6-rc: info: service go2rtc-healthcheck: stopping
frigate | s6-rc: info: service nginx successfully stopped
frigate | s6-rc: info: service nginx-log: stopping
Yeah just need to take some time and find them all I guess.
Has anyone figured this out? I'm running mine in K8s and can't run as root.
@maxirus depending how you configured your k8s, you can run it as privilleged
Unfortunately it does work without it.
has any one get it work
Also interested in this, if anyone has managed to get it working.
Any progress on allowing frigate to run as a user
and not root
in docker? I ran as user: $PUID:$PGID
but am getting the following errors:
chown: changing ownership of '/dev/shm/logs/frigate': Operation not permitted
chown: changing ownership of '/dev/shm/logs/go2rtc': Operation not permitted
chown: changing ownership of '/dev/shm/logs/nginx': Operation not permitted
I’ve managed to get this working to some satisfaction with a USB Coral & Intel iGPU, but it isn’t pretty. For anyone wanting to dive down the non-root rabbit hole, this may serve as a starting point. However bear in mind that this customization may break or need modification with newer versions.
The following script needs to be executable and mounted within the container, ideally as read-only. Then configure the container’s environment;
S6_STAGE2_HOOK
needs to contain the path to the script inside the container. UID
& GID
should be set respectively to the numeric ids of your preferred user. GIDLIST
is optional, but should contain comma separated numeric group ids needed to access any hardware, such as supplementary render or plugdev groups.This script disables Go2RTC simply because I run it outside of Frigate. But with some s6-rc.d modifications similar to what I’ve done for Frigate, theoretically it could also run without root.
#!/bin/bash
# {{ ansible_managed }}
# Disable Go2RTC
rm -r /etc/s6-overlay/s6-rc.d/{go2rtc,go2rtc-healthcheck,go2rtc-log}
rm /etc/s6-overlay/s6-rc.d/user/contents.d/go2rtc-pipeline
rm /etc/s6-overlay/s6-rc.d/frigate/dependencies.d/go2rtc
touch /etc/s6-overlay/s6-rc.d/frigate/dependencies.d/base
# Nginx Drop Privileges
sed -i 's/^user root;$/user www-data;/' /usr/local/nginx/conf/nginx.conf
# Frigate Drop Privileges
mv /etc/s6-overlay/s6-rc.d/frigate/run /etc/s6-overlay/s6-rc.d/frigate/run.upstream
sed -i '1c #!/bin/bash' /etc/s6-overlay/s6-rc.d/frigate/run.upstream
sed -i 's/^\(s6-svc -O \.\)$/#\1/' /etc/s6-overlay/s6-rc.d/frigate/run.upstream
cat << EOF > /etc/s6-overlay/s6-rc.d/frigate/run
#!/command/with-contenv /bin/bash
# Migrated from upstream, needs to be in the run file
s6-svc -O .
# User friendly reminder, suppress file not found errors
echo 'Go2RTC is disabled within the container' > /dev/shm/logs/go2rtc/current
# Handle warning about inability to use directory in /root
export MPLCONFIGDIR=/tmp/matplotlib
# https://skarnet.org/software/s6/s6-applyuidgid.html
chown "\${UID}:\${GID}" /config /media/frigate
exec s6-applyuidgid -z -U /etc/s6-overlay/s6-rc.d/frigate/run.upstream
EOF
chmod +x /etc/s6-overlay/s6-rc.d/frigate/run
# Frigate Disable PID 1 Kill
sed -i 's/proc\.name() == "s6-svscan"/False/' /opt/frigate/frigate/util/services.py
# Frigate Exit Halts Container
cat << EOF > /etc/s6-overlay/s6-rc.d/frigate/finish
#!/bin/bash
/run/s6/basedir/bin/halt
EOF
chmod +x /etc/s6-overlay/s6-rc.d/frigate/finish
For additional reference, my (ansible) container configuration & host udev rules.
- name: Create Frigate Container
containers.podman.podman_container:
name: frigate
image: ghcr.io/blakeblackshear/frigate:stable
cap_drop: [ALL]
capabilities: [SETUID, SETGID, CHOWN, FOWNER, DAC_OVERRIDE, KILL]
env:
UID: "{{ getent_passwd['frigate'][1] }}"
GID: "{{ getent_passwd['frigate'][2] }}"
GIDLIST: "{{ getent_group['render'][1] }},{{ getent_group['plugdev'][1] }}"
S6_STAGE2_HOOK: '/frigate-s6-stage2-hook'
env_file: /root/.secrets/pzznr38yyqzcyv2wwa6iua6cj0rfjpwasx1hq6bltxipqw0af8b0nlhdvcutqml
device:
- /dev/bus/usb:/dev/bus/usb
- /dev/dri/renderD128:/dev/dri/renderD128
ports:
- 127.0.0.1:5000:5000/tcp
tmpfs:
/dev/shm: rw,noexec,nosuid,size=256m
/tmp/cache: rw,noexec,nosuid,size=1024m
volumes:
- /usr/local/lib/frigate-s6-stage2-hook:/frigate-s6-stage2-hook:ro
- /usr/local/etc/frigate.yml:/config/config.yml:ro
- /data/srv/frigate:/data/srv/frigate
- /srv/frigate:/media/frigate
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1a6e", ATTRS{idProduct}=="089a", MODE="0664", GROUP="plugdev"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="18d1", ATTRS{idProduct}=="9302", MODE="0664", GROUP="plugdev"
Has anyone come around to a simpler workaround yet?
I'm not an expert in Docker stuff, but I believe I've read that it's a good practice to run processes inside the container as a non-root user (defence in depth, and all that).
Might this be as simple as adding something like this to the Dockerfile?
If some of the processes do in fact need to run as root, perhaps instead of using
USER
to change the settings across the board, the processes that do not need root could be launched as a dedicated user?I did see https://github.com/blakeblackshear/frigate/issues/1233 but the discussion seems to be about
--privileged
rather than the root user, despite the title, so I'm not sure if it applies here? Apologies if I misunderstood and this is a duplicate. For what it's worth, I haven't been able to get hold of any Coral hardware, so although I am running everything just fine without--privileged
, I can't confirm whether any of this would work with an actual Coral accelerator present.