diff --git a/.gitignore b/.gitignore index 200107ae5..33ec9ee24 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,8 @@ debug .vscode/* !.vscode/launch.json -config/config.yml +config/* +!config/*.example models *.mp4 *.ts diff --git a/Makefile b/Makefile index 69455fac0..9035a58f4 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ push: build docker buildx build --push --platform linux/amd64 --target=frigate-tensorrt --tag $(IMAGE_REPO):${GITHUB_REF_NAME}-$(COMMIT_HASH)-tensorrt . run: local - docker run --rm --publish=5000:5000 --volume=${PWD}/config/config.yml:/config/config.yml frigate:latest + docker run --rm --publish=5000:5000 --volume=${PWD}/config:/config frigate:latest run_tests: local docker run --rm --workdir=/opt/frigate --entrypoint= frigate:latest python3 -u -m unittest diff --git a/docker-compose.yml b/docker-compose.yml index 634d99060..cf3613484 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,7 +27,7 @@ services: - .:/workspace/frigate:cached - ./web/dist:/opt/frigate/web:cached - /etc/localtime:/etc/localtime:ro - - ./config/config.yml:/config/config.yml + - ./config:/config - ./debug:/media/frigate # Create the trt-models folder using the documented method of generating TRT models # - ./debug/trt-models:/trt-models diff --git a/docker/install_deps.sh b/docker/install_deps.sh index f92e20514..9a0e80dfe 100755 --- a/docker/install_deps.sh +++ b/docker/install_deps.sh @@ -70,3 +70,9 @@ apt-get purge gnupg apt-transport-https wget xz-utils -y apt-get clean autoclean -y apt-get autoremove --purge -y rm -rf /var/lib/apt/lists/* + +# Install yq, for frigate-prepare and go2rtc echo source +curl -fsSL \ + "https://github.com/mikefarah/yq/releases/download/v4.33.3/yq_linux_$(dpkg --print-architecture)" \ + --output /usr/local/bin/yq +chmod +x /usr/local/bin/yq diff --git a/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/run b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/run index 562081fc5..6c1c1a442 100755 --- a/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/run +++ b/docker/rootfs/etc/s6-overlay/s6-rc.d/frigate/run @@ -9,6 +9,42 @@ set -o errexit -o nounset -o pipefail # Tell S6-Overlay not to restart this service s6-svc -O . +function migrate_db_path() { + # Find config file in yaml or yml, but prefer yaml + local config_file="${CONFIG_FILE:-"/config/config.yml"}" + local config_file_yaml="${config_file//.yaml/.yml}" + if [[ -f "${config_file_yaml}" ]]; then + config_file="${config_file_yaml}" + elif [[ ! -f "${config_file}" ]]; then + echo "[ERROR] Frigate config file not found" + return 1 + fi + unset config_file_yaml + + # Use yq to check if database.path is set + local user_db_path + user_db_path=$(yq eval '.database.path' "${config_file}") + + if [[ "${user_db_path}" == "null" ]]; then + local previous_db_path="/media/frigate/frigate.db" + local new_db_dir="/config" + if [[ -f "${previous_db_path}" ]]; then + if mountpoint --quiet "${new_db_dir}"; then + # /config is a mount point, move the db + echo "[INFO] Moving db from '${previous_db_path}' to the '${new_db_dir}' dir..." + # Move all files that starts with frigate.db to the new directory + mv -vf "${previous_db_path}"* "${new_db_dir}" + else + echo "[ERROR] Trying to migrate the db path from '${previous_db_path}' to the '${new_db_dir}' dir, but '${new_db_dir}' is not a mountpoint, please mount the '${new_db_dir}' dir" + return 1 + fi + fi + fi +} + +echo "[INFO] Preparing Frigate..." +migrate_db_path + echo "[INFO] Starting Frigate..." cd /opt/frigate || echo "[ERROR] Failed to change working directory to /opt/frigate" diff --git a/docs/docs/configuration/advanced.md b/docs/docs/configuration/advanced.md index 7cedfce3c..818c4b9cd 100644 --- a/docs/docs/configuration/advanced.md +++ b/docs/docs/configuration/advanced.md @@ -42,7 +42,7 @@ environment_vars: ### `database` -Event and recording information is managed in a sqlite database at `/media/frigate/frigate.db`. If that database is deleted, recordings will be orphaned and will need to be cleaned up manually. They also won't show up in the Media Browser within Home Assistant. +Event and recording information is managed in a sqlite database at `/config/frigate.db`. If that database is deleted, recordings will be orphaned and will need to be cleaned up manually. They also won't show up in the Media Browser within Home Assistant. If you are storing your database on a network share (SMB, NFS, etc), you may get a `database is locked` error message on startup. You can customize the location of the database in the config if necessary. diff --git a/docs/docs/configuration/hardware_acceleration.md b/docs/docs/configuration/hardware_acceleration.md index c01bf74eb..3c16069cf 100644 --- a/docs/docs/configuration/hardware_acceleration.md +++ b/docs/docs/configuration/hardware_acceleration.md @@ -24,7 +24,7 @@ ffmpeg: hwaccel_args: preset-vaapi ``` -**NOTICE**: With some of the processors, like the J4125, the default driver `iHD` doesn't seem to work correctly for hardware acceleration. You may need to change the driver to `i965` by adding the following environment variable `LIBVA_DRIVER_NAME=i965` to your docker-compose file or [in the frigate.yml for HA OS users](advanced.md#environment_vars). +**NOTICE**: With some of the processors, like the J4125, the default driver `iHD` doesn't seem to work correctly for hardware acceleration. You may need to change the driver to `i965` by adding the following environment variable `LIBVA_DRIVER_NAME=i965` to your docker-compose file or [in the `frigate.yaml` for HA OS users](advanced.md#environment_vars). ### Intel-based CPUs (>=10th Generation) via Quicksync diff --git a/docs/docs/configuration/index.md b/docs/docs/configuration/index.md index 9686e8240..113884d6d 100644 --- a/docs/docs/configuration/index.md +++ b/docs/docs/configuration/index.md @@ -3,7 +3,7 @@ id: index title: Configuration File --- -For Home Assistant Addon installations, the config file needs to be in the root of your Home Assistant config directory (same location as `configuration.yaml`). It can be named `frigate.yml` or `frigate.yaml`, but if both files exist `frigate.yaml` will be preferred and `frigate.yml` will be ignored. +For Home Assistant Addon installations, the config file needs to be in the root of your Home Assistant config directory (same location as `configuration.yaml`). It can be named `frigate.yaml` or `frigate.yml`, but if both files exist `frigate.yaml` will be preferred and `frigate.yml` will be ignored. For all other installation types, the config file should be mapped to `/config/config.yml` inside the container. @@ -105,7 +105,7 @@ detectors: # Optional: Database configuration database: # The path to store the SQLite DB (default: shown below) - path: /media/frigate/frigate.db + path: /config/frigate.db # Optional: model modifications model: diff --git a/docs/docs/frigate/installation.md b/docs/docs/frigate/installation.md index 03481cfd7..78482d153 100644 --- a/docs/docs/frigate/installation.md +++ b/docs/docs/frigate/installation.md @@ -21,12 +21,11 @@ Windows is not officially supported, but some users have had success getting it Frigate uses the following locations for read/write operations in the container. Docker volume mappings can be used to map these to any location on your host machine. +- `/config`: Used to store the Frigate config file and sqlite database. You will also see a few files alongside the database file while Frigate is running. - `/media/frigate/clips`: Used for snapshot storage. In the future, it will likely be renamed from `clips` to `snapshots`. The file structure here cannot be modified and isn't intended to be browsed or managed manually. - `/media/frigate/recordings`: Internal system storage for recording segments. The file structure here cannot be modified and isn't intended to be browsed or managed manually. -- `/media/frigate/frigate.db`: Default location for the sqlite database. You will also see several files alongside this file while Frigate is running. If moving the database location (often needed when using a network drive at `/media/frigate`), it is recommended to mount a volume with docker at `/db` and change the storage location of the database to `/db/frigate.db` in the config file. - `/tmp/cache`: Cache location for recording segments. Initial recordings are written here before being checked and converted to mp4 and moved to the recordings folder. - `/dev/shm`: It is not recommended to modify this directory or map it with docker. This is the location for raw decoded frames in shared memory and it's size is impacted by the `shm-size` calculations below. -- `/config/config.yml`: Default location of the config file. #### Common docker compose storage configurations @@ -38,7 +37,7 @@ services: frigate: ... volumes: - - /path/to/your/config.yml:/config/config.yml + - /path/to/your/config:/config - /path/to/your/storage:/media/frigate - type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear target: /tmp/cache @@ -47,31 +46,6 @@ services: ... ``` -Writing to a network drive with database on a local drive: - -```yaml -version: "3.9" -services: - frigate: - ... - volumes: - - /path/to/your/config.yml:/config/config.yml - - /path/to/network/storage:/media/frigate - - /path/to/local/disk:/db - - type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear - target: /tmp/cache - tmpfs: - size: 1000000000 - ... -``` - -frigate.yml - -```yaml -database: - path: /db/frigate.db -``` - ### Calculating required shm-size Frigate utilizes shared memory to store frames during processing. The default `shm-size` provided by Docker is **64MB**. @@ -123,7 +97,7 @@ services: - /dev/dri/renderD128 # for intel hwaccel, needs to be updated for your hardware volumes: - /etc/localtime:/etc/localtime:ro - - /path/to/your/config.yml:/config/config.yml + - /path/to/your/config:/config - /path/to/your/storage:/media/frigate - type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear target: /tmp/cache @@ -149,7 +123,7 @@ docker run -d \ --device /dev/dri/renderD128 \ --shm-size=64m \ -v /path/to/your/storage:/media/frigate \ - -v /path/to/your/config.yml:/config/config.yml \ + -v /path/to/your/config:/config \ -v /etc/localtime:/etc/localtime:ro \ -e FRIGATE_RTSP_PASSWORD='password' \ -p 5000:5000 \ @@ -182,7 +156,7 @@ HassOS users can install via the addon repository. 2. Add https://github.com/blakeblackshear/frigate-hass-addons 3. Install your desired Frigate NVR Addon and navigate to it's page 4. Setup your network configuration in the `Configuration` tab -5. (not for proxy addon) Create the file `frigate.yml` in your `config` directory with your detailed Frigate configuration +5. (not for proxy addon) Create the file `frigate.yaml` in your `config` directory with your detailed Frigate configuration 6. Start the addon container 7. (not for proxy addon) If you are using hardware acceleration for ffmpeg, you may need to disable "Protection mode" diff --git a/docs/docs/troubleshooting/faqs.md b/docs/docs/troubleshooting/faqs.md index 4b166b037..75ab6df97 100644 --- a/docs/docs/troubleshooting/faqs.md +++ b/docs/docs/troubleshooting/faqs.md @@ -11,7 +11,7 @@ This error message is due to a shm-size that is too small. Try updating your shm By default, Frigate removes audio from recordings to reduce the likelihood of failing for invalid data. If you would like to include audio, you need to set a [FFmpeg preset](/configuration/ffmpeg_presets) that supports audio: -```yaml title="frigate.yml" +```yaml ffmpeg: output_args: record: preset-record-generic-audio-aac diff --git a/frigate/app.py b/frigate/app.py index 05e6c6d9c..8c1cd4433 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -18,7 +18,7 @@ from frigate.comms.dispatcher import Communicator, Dispatcher from frigate.comms.mqtt import MqttClient from frigate.comms.ws import WebSocketClient from frigate.config import FrigateConfig -from frigate.const import CACHE_DIR, CLIPS_DIR, RECORD_DIR +from frigate.const import CACHE_DIR, CLIPS_DIR, CONFIG_DIR, DEFAULT_DB_PATH, RECORD_DIR from frigate.object_detection import ObjectDetectProcess from frigate.events import EventCleanup, EventProcessor from frigate.http import create_app @@ -55,7 +55,7 @@ class FrigateApp: os.environ[key] = value def ensure_dirs(self) -> None: - for d in [RECORD_DIR, CLIPS_DIR, CACHE_DIR]: + for d in [CONFIG_DIR, RECORD_DIR, CLIPS_DIR, CACHE_DIR]: if not os.path.exists(d) and not os.path.islink(d): logger.info(f"Creating directory: {d}") os.makedirs(d) @@ -141,7 +141,7 @@ class FrigateApp: def init_database(self) -> None: # Migrate DB location - old_db_path = os.path.join(CLIPS_DIR, "frigate.db") + old_db_path = DEFAULT_DB_PATH if not os.path.isfile(self.config.database.path) and os.path.isfile( old_db_path ): diff --git a/frigate/config.py b/frigate/config.py index 77b7bbbb0..b83f3cbde 100644 --- a/frigate/config.py +++ b/frigate/config.py @@ -13,8 +13,8 @@ from pydantic import BaseModel, Extra, Field, validator, parse_obj_as from pydantic.fields import PrivateAttr from frigate.const import ( - BASE_DIR, CACHE_DIR, + DEFAULT_DB_PATH, REGEX_CAMERA_NAME, YAML_EXT, ) @@ -731,9 +731,7 @@ class CameraConfig(FrigateBaseModel): class DatabaseConfig(FrigateBaseModel): - path: str = Field( - default=os.path.join(BASE_DIR, "frigate.db"), title="Database path." - ) + path: str = Field(default=DEFAULT_DB_PATH, title="Database path.") class LogLevelEnum(str, Enum): diff --git a/frigate/const.py b/frigate/const.py index 528901783..f0d76d940 100644 --- a/frigate/const.py +++ b/frigate/const.py @@ -1,3 +1,5 @@ +CONFIG_DIR = "/config" +DEFAULT_DB_PATH = f"{CONFIG_DIR}/frigate.db" BASE_DIR = "/media/frigate" CLIPS_DIR = f"{BASE_DIR}/clips" RECORD_DIR = f"{BASE_DIR}/recordings"