Run with Docker2.x
This sets up a new 2.x install. Coming from 1.x? Follow Upgrade from 1.x instead, so your library and history carry over.
Compose file
Section titled “Compose file”services: infinidysk: image: ghcr.io/infinidysk/infinidysk-next:edge container_name: infinidysk restart: unless-stopped # pid: host # optional: name the processes that read the mount, see Logs and traces environment: PUID: 1000 PGID: 1000 TZ: Etc/UTC # your time zone, e.g. Europe/Oslo; the maintenance window follows it ports: - "3000:3000" volumes: - ./config:/config - /mnt:/mnt:rshared - /sys/devices/virtual/bdi:/sys/devices/virtual/bdi:rw devices: - /dev/fuse:/dev/fuse cap_add: - SYS_ADMIN security_opt: - apparmor:unconfinededge follows the latest 2.x build. There is no latest tag until 2.0 ships.
First start
Section titled “First start”- Run
docker compose up -d. - Open
http://<host>:3000and create the admin account. - Add your providers. See Providers.
Where things are
Section titled “Where things are”- Port 3000 serves the UI, the SABnzbd API and WebDAV.
- The library is mounted at
/mnt/infinidyskby default. Change it under Settings > Platform > Mount, or withINFINIDYSK__MOUNT__DIR. - The database is
/config/infinidysk.sqlite. SetINFINIDYSK_DATABASE_URLto apostgres://…URL to use PostgreSQL instead. - Logs go to
/config/logs/infinidysk.logand the System page.
The full list is in Ports, paths and mount layout.
FUSE in Docker
Section titled “FUSE in Docker”/dev/fuse,SYS_ADMINandapparmor:unconfinedlet the container mount. Without/dev/fuse, 2.x logs a warning and serves WebDAV only.:rsharedon the parent directory makes the mount visible on the host and in other containers. They bind it with:rslave; see Connect your media server.- The
/sys/devices/virtual/bdivolume lets the preset under Settings > Platform > Performance set the kernel’s readahead. Docker mounts/sysread-only, so without it readahead stays at the kernel’s 128 KB.
Health check
Section titled “Health check”The image has a built-in health check, so the compose file needs no healthcheck: block. docker ps shows the container as starting, healthy or unhealthy.
Healthy means all of these hold:
- The server answers on its port.
- The database answers.
- The import worker runs.
- The mount is mounted and answers. Without
/dev/fusethe mount is not checked.
A normal start turns healthy within seconds. The first start after an upgrade from 1.x stays starting until the import is done. If the import takes longer than the 10-minute start period, the container shows unhealthy until it ends.
The check runs inside the container, so it cannot see whether :rshared carries the mount to the host. Check that once from your media server; see Connect your media server.
Wait for the mount
Section titled “Wait for the mount”Containers that read the mount can wait until infinidysk is healthy:
services: plex: depends_on: infinidysk: condition: service_healthydocker compose up then starts the media server after the mount is up. If infinidysk turns unhealthy first, for example during a long 1.x import, Compose does not start the media server. Run docker compose up -d again once infinidysk is healthy.
Change the timing
Section titled “Change the timing”The built-in check runs every 30 seconds and marks the container unhealthy after 3 failures in a row. Override it in the compose file:
services: infinidysk: healthcheck: interval: 15s retries: 5What it asks
Section titled “What it asks”The check runs infinidysk healthcheck, which asks GET /healthz on the address in INFINIDYSK_LISTEN and exits 0 when healthy, 1 otherwise. It needs no curl and never reads the mount itself, so a stuck mount cannot hang it.
/healthz answers without sign-in and shows no settings or secrets. It answers 200 when healthy and 503 while starting or unhealthy:
{"status":"healthy","checks":{"database":"pass","mount":"pass","queue":"pass"}}Each check is pass, fail, pending (not ready yet) or off (does not apply, for example mount without /dev/fuse). During the first start after an upgrade, the body has one import check instead. The reason a check fails is in the log, not in the answer.