mirror of
				https://github.com/scottlamb/moonfire-nvr.git
				synced 2025-10-30 00:05:03 -04:00 
			
		
		
		
	several documentation improvements
* prefix docker/nvr commands with sudo (fixes #142). I was just going to link to the docker documentation on setting up non-root access, but that's kind of a personal preference. I included a `<details>` about it instead and made all the commands work with sudo. * take better advantage of github markdown's code block syntax highlighting. Use "console" for shell session stuff, put the "nvr" wrapper script in its own block with "bash". * add some comments to nvr wrapper script where people need to make changes and/or will be confused. * add a `<details>` that talks about shutting down and restarting the session around `nvr config` (see #151). Still not user-friendly but at least it's better documented now.
This commit is contained in:
		
							parent
							
								
									a16bda8fb1
								
							
						
					
					
						commit
						30cea5cfcb
					
				| @ -23,7 +23,7 @@ See the [github page](https://github.com/scottlamb/moonfire-nvr) (in case | ||||
| you're not reading this text there already). You can download the | ||||
| bleeding-edge version from the commandline via git: | ||||
| 
 | ||||
| ``` | ||||
| ```console | ||||
| $ git clone https://github.com/scottlamb/moonfire-nvr.git | ||||
| $ cd moonfire-nvr | ||||
| ``` | ||||
| @ -32,8 +32,8 @@ $ cd moonfire-nvr | ||||
| 
 | ||||
| This command should prepare a deployment image for your local machine: | ||||
| 
 | ||||
| ``` | ||||
| $ docker buildx build --load --tag=moonfire-nvr -f docker/Dockerfile . | ||||
| ```console | ||||
| $ sudo docker buildx build --load --tag=moonfire-nvr -f docker/Dockerfile . | ||||
| ``` | ||||
| 
 | ||||
| <details> | ||||
| @ -47,8 +47,8 @@ $ docker buildx build --load --tag=moonfire-nvr -f docker/Dockerfile . | ||||
|     due to an error in `libseccomp`, as described [in this askubuntu.com answer](https://askubuntu.com/a/1264921/1365248). | ||||
|     Try running in a privileged builder. As described in [`docker buildx build` documentation](https://docs.docker.com/engine/reference/commandline/buildx_build/#allow), | ||||
|     run this command once: | ||||
|     ``` | ||||
|     $ docker buildx create --use --name insecure-builder --buildkitd-flags '--allow-insecure-entitlement security.insecure' | ||||
|     ```console | ||||
|     $ sudo docker buildx create --use --name insecure-builder --buildkitd-flags '--allow-insecure-entitlement security.insecure' | ||||
|     ``` | ||||
|     then add `--allow security.insecure` to your `docker buildx build` commandlines. | ||||
| </details> | ||||
| @ -59,11 +59,11 @@ helpful to use the `dev` target. This is a self-contained developer environment | ||||
| which you can use from its shell via `docker run` or via something like | ||||
| Visual Studio Code's Docker plugin. | ||||
| 
 | ||||
| ``` | ||||
| $ docker buildx build \ | ||||
| ```console | ||||
| $ sudo docker buildx build \ | ||||
|         --load --tag=moonfire-dev --target=dev -f docker/Dockerfile . | ||||
| ... | ||||
| $ docker run \ | ||||
| $ sudo docker run \ | ||||
|         --rm --interactive=true --tty \ | ||||
|         --mount=type=bind,source=$(pwd),destination=/var/lib/moonfire-nvr/src \ | ||||
|         moonfire-dev | ||||
| @ -86,8 +86,8 @@ architecture. | ||||
| On the author's macOS machine with Docker desktop 3.0.4, building for | ||||
| multiple platforms at once will initially fail with the following error: | ||||
| 
 | ||||
| ``` | ||||
| $ docker buildx build ... --platform=linux/arm64/v8,linux/arm/v7,linux/amd64 | ||||
| ```console | ||||
| $ sudo docker buildx build ... --platform=linux/arm64/v8,linux/arm/v7,linux/amd64 | ||||
| [+] Building 0.0s (0/0) | ||||
| error: multiple platforms feature is currently not supported for docker driver. Please switch to a different driver (eg. "docker buildx create --use") | ||||
| ``` | ||||
| @ -107,8 +107,8 @@ caveats: | ||||
|     suggests a workaround of building all three then using caching to quickly | ||||
|     load the one of immediate interest: | ||||
|     ``` | ||||
|     $ docker buildx build --platform=linux/arm64/v8,linux/arm/v7,linux/amd64 ... | ||||
|     $ docker buildx build --load --platform=arm64/v8 ... | ||||
|     $ sudo docker buildx build --platform=linux/arm64/v8,linux/arm/v7,linux/amd64 ... | ||||
|     $ sudo docker buildx build --load --platform=arm64/v8 ... | ||||
|     ``` | ||||
| 
 | ||||
| On Linux hosts (as opposed to when using Docker Desktop on macOS/Windows), | ||||
| @ -190,7 +190,7 @@ in "Maintenance LTS" or "Active LTS" status: currently v12 or v14. | ||||
| On recent Ubuntu or Raspbian Linux, the following command will install | ||||
| most non-Rust dependencies: | ||||
| 
 | ||||
| ``` | ||||
| ```console | ||||
| $ sudo apt-get install \ | ||||
|                build-essential \ | ||||
|                libavcodec-dev \ | ||||
| @ -212,7 +212,7 @@ manager](https://nodejs.org/en/download/package-manager/#debian-and-ubuntu-based | ||||
| On macOS with [Homebrew](https://brew.sh/) and Xcode installed, try the | ||||
| following command: | ||||
| 
 | ||||
| ``` | ||||
| ```console | ||||
| $ brew install ffmpeg node | ||||
| ``` | ||||
| 
 | ||||
| @ -224,7 +224,7 @@ your Linux distribution's Rust packages, which tend to be too old. | ||||
| Once prerequisites are installed, you can build the server and find it in | ||||
| `target/release/moonfire-nvr`: | ||||
| 
 | ||||
| ``` | ||||
| ```console | ||||
| $ cd server | ||||
| $ cargo test | ||||
| $ cargo build --release | ||||
| @ -233,7 +233,7 @@ $ sudo install -m 755 target/release/moonfire-nvr /usr/local/bin | ||||
| 
 | ||||
| You can build the UI via `npm` and find it in the `ui/build` directory: | ||||
| 
 | ||||
| ``` | ||||
| ```console | ||||
| $ cd ui | ||||
| $ npm install | ||||
| $ npm run build | ||||
| @ -246,7 +246,7 @@ $ sudo rsync --recursive --delete --chmod=D755,F644 ui/build/ /usr/local/lib/moo | ||||
| The author finds it convenient for local development to set up symlinks so that | ||||
| the binaries in the working copy will run via just `nvr`: | ||||
| 
 | ||||
| ``` | ||||
| ```console | ||||
| $ sudo mkdir /usr/local/lib/moonfire-nvr | ||||
| $ sudo ln -s `pwd`/ui/build /usr/local/lib/moonfire-nvr/ui | ||||
| $ sudo mkdir /var/lib/moonfire-nvr | ||||
| @ -308,7 +308,7 @@ Internet](secure.md). | ||||
| 
 | ||||
| Some handy commands: | ||||
| 
 | ||||
| ``` | ||||
| ```console | ||||
| $ sudo systemctl daemon-reload                                  # reload configuration files | ||||
| $ sudo systemctl start moonfire-nvr                             # start the service now | ||||
| $ sudo systemctl stop moonfire-nvr                              # stop the service now (but don't wait for it finish stopping) | ||||
|  | ||||
| @ -13,7 +13,16 @@ instead want to build Moonfire NVR yourself, see the [Build | ||||
| instructions](build.md). | ||||
| 
 | ||||
| First, install [Docker](https://www.docker.com/) if you haven't already, | ||||
| and verify `docker run --rm hello-world` works. | ||||
| and verify `sudo docker run --rm hello-world` works. | ||||
| 
 | ||||
| <details> | ||||
|   <summary><tt>sudo</tt> or not?</summary> | ||||
| 
 | ||||
| If you prefer to save typing by not prefixing all `docker` and `nvr` commands | ||||
| with `sudo`, see [Docker docs: Manage Docker as a non-root | ||||
| user](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user). | ||||
| Note `docker` access is equivalent to root access security-wise. | ||||
| </details> | ||||
| 
 | ||||
| Next, you'll need to set up your filesystem and the Moonfire NVR user. | ||||
| 
 | ||||
| @ -30,7 +39,7 @@ Moonfire NVR keeps two kinds of state: | ||||
| 
 | ||||
| On most Linux systems, you can create the user as follows: | ||||
| 
 | ||||
| ``` | ||||
| ```console | ||||
| $ sudo useradd --user-group --create-home --home /var/lib/moonfire-nvr moonfire-nvr | ||||
| ``` | ||||
| 
 | ||||
| @ -41,19 +50,44 @@ and managing a long-lived Docker container for its web interface. | ||||
| As you set up this script, adjust the `tz` variable as appropriate for your | ||||
| time zone. | ||||
| 
 | ||||
| Use your favorite editor to create `/usr/local/bin/nvr`, starting from the | ||||
| configuration below: | ||||
| 
 | ||||
| ```console | ||||
| $ sudo nano /usr/local/bin/nvr | ||||
| (see below for contents) | ||||
| $ sudo chmod a+rx /usr/local/bin/nvr | ||||
| ``` | ||||
| sudo sh -c 'cat > /usr/local/bin/nvr' <<'EOF' | ||||
| 
 | ||||
| `/usr/local/bin/nvr`: | ||||
| ```bash | ||||
| #!/bin/bash -e | ||||
| 
 | ||||
| # Set your timezone here. | ||||
| tz="America/Los_Angeles" | ||||
| container_name="moonfire-nvr" | ||||
| 
 | ||||
| # or eg "scottlamb/moonfire-nvr:v0.6.5" to specify a particular version. | ||||
| image_name="scottlamb/moonfire-nvr:latest" | ||||
| container_name="moonfire-nvr" | ||||
| common_docker_run_args=( | ||||
|         --mount=type=bind,source=/var/lib/moonfire-nvr,destination=/var/lib/moonfire-nvr | ||||
| 
 | ||||
|         # Add additional mount lines here for each sample file directory | ||||
|         # outside of /var/lib/moonfire-nvr, eg: | ||||
|         # --mount=type=bind,source=/media/nvr/sample,destination=/media/nvr/sample | ||||
| 
 | ||||
|         --user="$(id -u moonfire-nvr):$(id -g moonfire-nvr)" | ||||
| 
 | ||||
|         # This avoids errors with broken seccomp on Raspberry Pi OS. | ||||
|         --security-opt=seccomp:unconfined | ||||
| 
 | ||||
|         # docker's default log driver won't rotate logs properly, and will throw | ||||
|         # away logs when you destroy and recreate the container. Using journald | ||||
|         # solves these problems. | ||||
|         # https://docs.docker.com/config/containers/logging/configure/ | ||||
|         --log-driver=journald | ||||
|         --log-opt="tag=moonfire-nvr" | ||||
| 
 | ||||
|         --env=RUST_BACKTRACE=1 | ||||
|         --env=TZ=":${tz}" | ||||
| ) | ||||
| @ -65,11 +99,20 @@ run) | ||||
|                 --detach=true \ | ||||
|                 --restart=unless-stopped \ | ||||
|                 "${common_docker_run_args[@]}" \ | ||||
| 
 | ||||
|                 # This is the simplest way of configuring networking, although | ||||
|                 # you can use eg --publish=8080:8080 if you prefer. | ||||
|                 --network=host \ | ||||
| 
 | ||||
|                 --name="${container_name}" \ | ||||
|                 "${image_name}" \ | ||||
|                 run \ | ||||
| 
 | ||||
|                 # Add any additional `moonfire-nvr run` arguments here, eg | ||||
|                 # "--rtsp-library=ffmpeg" if the default "--rtsp-library=retina" | ||||
|                 # isn't working. | ||||
|                 --allow-unauthenticated-permissions='view_video: true' \ | ||||
| 
 | ||||
|                 "$@" | ||||
|         ;; | ||||
| start|stop|logs|rm) | ||||
| @ -88,14 +131,12 @@ pull) | ||||
|                 "$@" | ||||
|         ;; | ||||
| esac | ||||
| EOF | ||||
| sudo chmod a+rx /usr/local/bin/nvr | ||||
| ``` | ||||
| 
 | ||||
| then try it out by initializing the database: | ||||
| 
 | ||||
| ``` | ||||
| $ nvr init | ||||
| ```console | ||||
| $ sudo nvr init | ||||
| ``` | ||||
| 
 | ||||
| This will create a directory `/var/lib/moonfire-nvr/db` with a SQLite3 database | ||||
| @ -113,7 +154,7 @@ using UAS, as described there. UAS has been linked to filesystem corruption. | ||||
| 
 | ||||
| Set up the mount point: | ||||
| 
 | ||||
| ``` | ||||
| ```console | ||||
| $ sudo vim /etc/fstab | ||||
| $ sudo mkdir /media/nvr | ||||
| $ sudo mount /media/nvr | ||||
| @ -126,12 +167,7 @@ In `/etc/fstab`, add a line similar to this: | ||||
| UUID=23d550bc-0e38-4825-acac-1cac8a7e091f    /media/nvr   ext4    nofail,noatime,lazytime,data=writeback,journal_async_commit  0       2 | ||||
| ``` | ||||
| 
 | ||||
| You'll have to lookup the correct uuid for your disk. One way to do that is | ||||
| via the following command: | ||||
| 
 | ||||
| ``` | ||||
| $ ls -l /dev/disk/by-uuid | ||||
| ``` | ||||
| You can look up the correct uuid for your disk via `blkid`. | ||||
| 
 | ||||
| If you use the `nofail` attribute in `/etc/fstab` as described above, your | ||||
| system will boot successfully even when the hard drive is unavailable (such as | ||||
| @ -140,18 +176,14 @@ recovering from problems. | ||||
| 
 | ||||
| Create the sample directory. | ||||
| 
 | ||||
| ``` | ||||
| sudo mkdir /media/nvr/sample | ||||
| sudo chown -R moonfire-nvr:moonfire-nvr /media/nvr | ||||
| ```console | ||||
| $ sudo mkdir /media/nvr/sample | ||||
| $ sudo chown -R moonfire-nvr:moonfire-nvr /media/nvr | ||||
| ``` | ||||
| 
 | ||||
| Add a new `--mount` line to your Docker wrapper script `/usr/local/bin/nvr` | ||||
| to expose this new volume to the Docker container, directly below the other | ||||
| mount lines. It will look similar to this: | ||||
| 
 | ||||
| ``` | ||||
|         --mount=type=bind,source=/media/nvr/sample,destination=/media/nvr/sample | ||||
| ``` | ||||
| to expose this new volume to the Docker container, right where a comment | ||||
| mentions "Additional mount lines". | ||||
| 
 | ||||
| ### Completing configuration through the UI | ||||
| 
 | ||||
| @ -159,9 +191,18 @@ Once your system is set up, it's time to initialize an empty database | ||||
| and add the cameras and sample directories. You can do this | ||||
| by using the `moonfire-nvr` binary's text-based configuration tool. | ||||
| 
 | ||||
| ```console | ||||
| $ sudo nvr config 2>debug-log | ||||
| ``` | ||||
| $ nvr config 2>debug-log | ||||
| ``` | ||||
| 
 | ||||
| <details> | ||||
|   <summary>Did it just return?</summary> | ||||
| 
 | ||||
| If `nvr config` returns you to the console prompt right away, look in the | ||||
| `debug-log` file for why. One common reason is that you have Moonfire NVR | ||||
| running; you'll need to shut it down first. Try `nvr stop` before `nvr config` | ||||
| and `nvr start` afterward. | ||||
| </details> | ||||
| 
 | ||||
| In the user interface, | ||||
| 
 | ||||
| @ -229,12 +270,12 @@ system](secure.md) first. | ||||
| This command will start a detached Docker container for the web interface. | ||||
| It will automatically restart when your system does. | ||||
| 
 | ||||
| ``` | ||||
| $ nvr run | ||||
| ```console | ||||
| $ sudo nvr run | ||||
| ``` | ||||
| 
 | ||||
| You can temporarily disable the service via `nvr stop` and restart it later via | ||||
| `nvr start`. | ||||
| `nvr start`. You'll need to do this before and after using `nvr config`. | ||||
| 
 | ||||
| The HTTP interface is accessible on port 8080; if your web browser is running | ||||
| on the same machine, you can access it at | ||||
|  | ||||
| @ -64,14 +64,14 @@ Next ensure Moonfire NVR is not running and does not automatically restart if | ||||
| the system is rebooted during the upgrade. If you followed the Docker | ||||
| instructions, you can do this as follows: | ||||
| 
 | ||||
| ``` | ||||
| $ nvr stop | ||||
| ```console | ||||
| $ sudo nvr stop | ||||
| ``` | ||||
| 
 | ||||
| Then back up your SQLite database. If you are using the default path, you can | ||||
| do so as follows: | ||||
| 
 | ||||
| ``` | ||||
| ```console | ||||
| $ sudo -u moonfire-nvr cp /var/lib/moonfire-nvr/db/db{,.pre-upgrade} | ||||
| ``` | ||||
| 
 | ||||
| @ -91,9 +91,9 @@ manual for write-ahead logging](https://www.sqlite.org/wal.html): | ||||
| 
 | ||||
| Run the upgrade procedure using the new software binary. | ||||
| 
 | ||||
| ``` | ||||
| $ nvr pull     # updates the docker image to the latest binary | ||||
| $ nvr upgrade  # runs the upgrade | ||||
| ```console | ||||
| $ sudo nvr pull     # updates the docker image to the latest binary | ||||
| $ sudo nvr upgrade  # runs the upgrade | ||||
| ``` | ||||
| 
 | ||||
| As a rule of thumb, on a Raspberry Pi 4 with a 1 GiB database, an upgrade might | ||||
| @ -102,9 +102,9 @@ take about four minutes for each schema version and for the final vacuum. | ||||
| Next, you can run the system in read-only mode, although you'll find this only | ||||
| works in the "insecure" setup. (Authorization requires writing the database.) | ||||
| 
 | ||||
| ``` | ||||
| $ nvr rm | ||||
| $ nvr run --read-only | ||||
| ```console | ||||
| $ sudo nvr rm | ||||
| $ sudo nvr run --read-only | ||||
| ``` | ||||
| 
 | ||||
| Go to the web interface and ensure the system is operating correctly. If | ||||
| @ -115,10 +115,10 @@ more complicated. | ||||
| 
 | ||||
| Once you're satisfied, restart the system in read-write mode: | ||||
| 
 | ||||
| ``` | ||||
| $ nvr stop | ||||
| $ nvr rm | ||||
| $ nvr run | ||||
| ```console | ||||
| $ sudo nvr stop | ||||
| $ sudo nvr rm | ||||
| $ sudo nvr run | ||||
| ``` | ||||
| 
 | ||||
| Hopefully your system is functioning correctly. If not, there are two options | ||||
|  | ||||
| @ -190,10 +190,10 @@ effectively allowing them to lie about the client's IP and protocol. | ||||
| To make this take effect, you'll need to stop the running Docker container, | ||||
| delete it, and create/run a new one: | ||||
| 
 | ||||
| ``` | ||||
| $ nvr stop | ||||
| $ nvr rm | ||||
| $ nvr run | ||||
| ```console | ||||
| $ sudo nvr stop | ||||
| $ sudo nvr rm | ||||
| $ sudo nvr run | ||||
| ``` | ||||
| 
 | ||||
| ## 7. Configure the webserver | ||||
|  | ||||
| @ -106,13 +106,13 @@ Moonfire NVR names a few important thread types as follows: | ||||
| You can use the following command to teach [`lnav`](http://lnav.org/) Moonfire | ||||
| NVR's log format: | ||||
| 
 | ||||
| ``` | ||||
| ```console | ||||
| $ lnav -i misc/moonfire_log.json | ||||
| ``` | ||||
| 
 | ||||
| `lnav` versions prior to 0.9.0 print a (harmless) warning message on startup: | ||||
| 
 | ||||
| ``` | ||||
| ```console | ||||
| $ lnav -i git/moonfire-nvr/misc/moonfire_log.json | ||||
| warning:git/moonfire-nvr/misc/moonfire_log.json:line 2 | ||||
| warning:  unexpected path -- | ||||
| @ -151,7 +151,7 @@ This log message is packed with debugging information: | ||||
|     file `/media/14tb/sample/00000003001c1ba6`. On-disk files are named by | ||||
|     a fixed eight hexadecimal digits for the stream id and eight hexadecimal | ||||
|     digits for the recording id. You can convert with `printf`: | ||||
|     ``` | ||||
|     ```console | ||||
|     $ printf '%08x%08x\n' 3 1842086 | ||||
|     00000003001c1ba6 | ||||
|     ``` | ||||
| @ -242,8 +242,8 @@ problem in more detail. The simplest solution is to add | ||||
| If you are using the recommended `/usr/local/bin/nvr` wrapper script, | ||||
| add this option to the `common_docker_run_args` section. | ||||
| 
 | ||||
| ``` | ||||
| $ docker run --rm -it moonfire-nvr:latest | ||||
| ```console | ||||
| $ sudo docker run --rm -it moonfire-nvr:latest | ||||
| clock_gettime failed: EPERM: Operation not permitted | ||||
| 
 | ||||
| This indicates a broken environment. See the troubleshooting guide. | ||||
| @ -273,7 +273,7 @@ clean up the excess files. Moonfire NVR will start working again immediately. | ||||
| If Moonfire NVR's own files are too large, follow this procedure: | ||||
| 
 | ||||
| 1.  Shut it down via `SIGKILL`: | ||||
|     ``` | ||||
|     ```console | ||||
|     $ sudo killall -KILL moonfire-nvr | ||||
|     ``` | ||||
|     (Be sure to use `-KILL`. It won't shut down properly on `SIGTERM` or `SIGINT` | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user