Skip to content

Docker

InfiniDysk ships as a single multi-arch image: ghcr.io/infinidysk/infinidysk. The container runs the frontend (public port 3000) and backend (internal 8080).

The examples use :latest (current stable). See Release channels and tags for the lts, rc, and dev channels — and pin an exact version tag (v1.2.3) when you want reproducible deploys.

Hosted with DUMB

Prefer a batteries-included Arr stack? InfiniDysk is a fully supported core module in Debrid Unlimited Media Bridge (DUMB) — see the InfiniDysk service guide and setup options.

IPv6-only hosts

ghcr.io is not reachable over IPv6. Use the Docker Hub mirror nzbdav/nzbdav instead.

Persistent Compose

services:
  nzbdav:
    image: ghcr.io/infinidysk/infinidysk:latest
    container_name: nzbdav
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "curl -fsSL http://localhost:3000/healthz > /dev/null || exit 1"]
      interval: 30s
      retries: 3
      start_period: 60s
      timeout: 5s
    ports:
      - "3000:3000"
    environment:
      PUID: "1000"
      PGID: "1000"
      TZ: America/New_York
    volumes:
      - ./config:/config
      - /mnt:/mnt
docker compose up -d

Set PUID/PGID from id on the host. Map /mnt (or your media paths) so completed downloads and library folders share paths with *Arr and media servers.

The container fails startup before migrations if /config is missing, is a file, or is not writable by PUID/PGID. Ownership repair is best-effort; ACLs and group-writable mounts are accepted when the runtime user can create and delete a probe file. The image already contains an empty /config directory, so a path existing inside the container is not proof a host volume is mounted. The frontend session key at /config/session.key is mode 0600; if your supervisor repairs ownership using an allowlist, include that file without recursively chowning blobs/.

Headless Settings since 0.9.0

Prefer infrastructure-as-code for Usenet, WebDAV, *Arr, and other Settings? Use authoritative NZBDAV_CONFIG__... variables — see the fully hydrated Compose example. Process variables on this page (PUID, TZ, …) stay separate.

Change the published port

Compose port mappings use HOST_PORT:CONTAINER_PORT. To open InfiniDysk on port 3001 without changing the ports inside the container:

ports:
  - "3001:3000"

Open http://your-server:3001. Keep the container-side port at 3000, including the Compose healthcheck at http://localhost:3000/healthz. A mapping such as 3001:3001 does not work unless the frontend is separately configured to listen on 3001.

Tip

For ordinary bridge-networked Docker and Compose deployments, changing the host side of the port mapping is the recommended approach. Do not set PORT just to avoid a host port conflict.

Host networking and internal port conflicts

With network_mode: host, there is no port mapping layer. Set PORT if the frontend's port conflicts with another host service:

network_mode: host
environment:
  PORT: "3001"

The backend remains on 8080. If that port also conflicts, its listen URL and the frontend's backend URL must change together:

network_mode: host
environment:
  PORT: "3001"
  ASPNETCORE_URLS: "http://127.0.0.1:8081"
  BACKEND_URL: "http://127.0.0.1:8081"

Update the Compose healthcheck to use the effective frontend port (http://localhost:3001/healthz) and update Settings → General → Base URL when generated links should use the new public port.

DUMB deployments

DUMB builds and launches InfiniDysk directly rather than using this image's entrypoint. Change DUMB's nzbdav.frontend_port and nzbdav.backend_port settings instead; DUMB supplies the corresponding process environment automatically. See the DUMB InfiniDysk service guide.

What the image does

  1. Starts the frontend so maintenance progress can be shown.
  2. Runs database migration / restore swap (--db-migration).
  3. Starts the backend and waits for /health before considering startup complete.

Long one-time maintenance does not mark the Compose healthcheck unhealthy — it targets frontend /healthz.

Reverse proxy

TLS and WebSockets

  • Prefer HTTPS in front of port 3000. Do not expose plain HTTP to the internet.
  • Bind 127.0.0.1:3000:3000 when the proxy is on the Docker host.
  • Allow HTTP Upgrade on same-origin /ws (Overview/Queue live updates).
  • Set SECURE_COOKIES=true when the UI is HTTPS-only.
  • Set Base URL in Settings to the public HTTPS address. It supplies STRM/adapter absolute URLs and lets same-origin UI actions such as login work through the proxy without TRUST_PROXY. It never blocks signing in directly over another address (for example http://<lan-ip>:3000); those requests use the standard same-origin check.
  • Alternatively, enable Trust reverse-proxy headers since 1.4.0 under Settings → General and have the proxy send correct X-Forwarded-Host and X-Forwarded-Proto headers. This is preferable when the public origin can vary. TRUST_PROXY=1 enables and locks the same behavior from the container environment.
  • For addurl to Docker-internal indexers, configure Trusted local hosts or TRUSTED_INTERNAL_HOSTS since 0.8.0.

Optional environment

Variable Purpose
TRUST_PROXY=1 Enable and lock proxy X-Forwarded-* trust instead of using the General settings toggle
TRUSTED_PROXY_CIDRS Widen backend proxy trust (split-container)
TRUSTED_INTERNAL_HOSTS since 0.8.0 Allowlist for private addurl targets
SESSION_KEY Stable session secret (else persisted under /config)
THREADPOOL_MIN_THREADS / THREADPOOL_MAX_THREADS Memory-constrained hosts

Full list: Environment variables.

Next

First run — admin account, providers, WebDAV, import strategy.