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:
Scott Lamb 2021-08-23 12:40:14 -07:00
parent a16bda8fb1
commit 30cea5cfcb
5 changed files with 111 additions and 70 deletions

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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`