- Shell 85.3%
- Makefile 8.3%
- Dockerfile 6.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
| .github/workflows | ||
| docs | ||
| examples | ||
| scripts | ||
| tests | ||
| .dockerignore | ||
| .gitignore | ||
| CONTRIBUTING.md | ||
| Dockerfile | ||
| entrypoint.sh | ||
| LICENSE | ||
| Makefile | ||
| README.md | ||
| SECURITY.md | ||
truenas-ncdu
Run ncdu against TrueNAS SCALE datasets from a small container.
TrueNAS SCALE does not ship ncdu on the host appliance. This repository packages ncdu in a container so you can inspect dataset usage without installing packages on TrueNAS itself.
What This Provides
- Alpine-based container with
ncduandtini. - Safe default scan path:
/mnt. ncdu -xenabled by default to avoid crossing filesystem boundaries..zfssnapshot directories excluded by default so ZFS snapshots do not inflate normal folder totals.- Browser terminal mode through
ttyd, backed by a persistenttmuxsession. - Read-only mount examples for TrueNAS datasets.
- GitHub Actions CI and Docker Hub publishing workflow.
- TrueNAS SCALE direct Docker and Custom App/YAML instructions.
Quick Use
Run this from a TrueNAS SCALE shell:
docker run --rm -it \
--network none \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=64m \
--cap-drop ALL \
--security-opt no-new-privileges \
-v /mnt:/mnt:ro \
docker.io/joanmarcriera/truenas-ncdu:latest \
/mnt
Scan one dataset:
docker run --rm -it \
--network none \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=64m \
--cap-drop ALL \
--security-opt no-new-privileges \
-v /mnt:/mnt:ro \
docker.io/joanmarcriera/truenas-ncdu:latest \
/mnt/tank/media
The /mnt host mount is read-only, so this mode is for inspection rather than deletion.
Build Locally
make build
make run SCAN_PATH=/mnt
Or without make:
docker build -t truenas-ncdu:dev .
docker run --rm -it -v /mnt:/mnt:ro truenas-ncdu:dev
TrueNAS SCALE Web App Setup
Use this path when you want ncdu available in a browser as a TrueNAS app. The container starts a detached tmux session running ncdu, then serves that TUI through ttyd on port 7681.
In the TrueNAS SCALE web UI:
- Open Apps.
- Click Discover Apps.
- Click Custom App.
- Set Application Name to
truenas-ncdu. - In Image Configuration, set:
Repository: joanmarcriera/truenas-ncdu
Tag: 0.2.2
Pull Policy: Always pull an image even if it is present on the host
- In Container Configuration, leave Entrypoint empty and leave Command empty.
The image defaults to web mode, so the browser terminal server starts when the app boots.
- Set:
Restart Policy: Unless Stopped
TTY and Stdin are not required for web mode.
- Add environment variables. Choose your own
TTYD_PASSWORDbefore saving the app:
NCDU_PATH=/mnt/BigDisk
NCDU_ONE_FILESYSTEM=true
NCDU_EXCLUDE_ZFS=true
TTYD_USER=admin
TTYD_PASSWORD=<choose-a-password>
Change NCDU_PATH if you mount a different dataset path. Keep NCDU_EXCLUDE_ZFS=true for normal scans; set it to false only when you deliberately want to inspect ZFS snapshot contents under .zfs/snapshot.
- In Network Configuration, add a TCP port:
Container Port: 7681
Host Port: 7681
Protocol: TCP
If host port 7681 is already in use, choose another host port and keep the container port as 7681.
- Optional: in Portal Configuration, add an HTTP portal pointing at host port
7681. - In Storage Configuration, click Add and choose Host Path.
- Select only the dataset or pool path you want
ncduto read. For the BigDisk scenario:
Type: Host Path
Host Path: /mnt/BigDisk
Mount Path: /mnt/BigDisk
Read Only: enabled
Use read-only mounts for normal inspection. If you want to scan multiple datasets, add one Host Path entry per dataset, or mount /mnt to /mnt read-only if you deliberately want broad visibility.
- Save the app.
- Open the browser terminal:
http://<truenas-ip>:7681
Log in with TTYD_USER and TTYD_PASSWORD. The browser attaches to the running ncdu TUI. To restart the scan from inside the browser terminal, press q to quit ncdu, then run:
truenas-ncdu
If the app shell shows permission errors, check the dataset ACL for the mounted path and make sure the app user can read and traverse the dataset. The mount should still stay read-only unless you intentionally want delete support from inside ncdu.
TrueNAS YAML for BigDisk
TrueNAS also supports installing custom apps from YAML. Go to Apps > Discover Apps, open the menu at the top right, choose Install via YAML, name the app truenas-ncdu, and paste this Compose YAML:
services:
truenas-ncdu:
image: docker.io/joanmarcriera/truenas-ncdu:0.2.2
container_name: truenas-ncdu
read_only: true
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
tmpfs:
- /tmp:rw,noexec,nosuid,size=64m
environment:
NCDU_PATH: /mnt/BigDisk
NCDU_ONE_FILESYSTEM: "true"
NCDU_EXCLUDE_ZFS: "true"
TTYD_USER: admin
TTYD_PASSWORD: change-this-password
ports:
- "7681:7681"
volumes:
- type: bind
source: /mnt/BigDisk
target: /mnt/BigDisk
read_only: true
This same YAML is available at examples/compose.bigdisk.yaml. The generic /mnt example remains at examples/compose.truenas.yaml.
After the app starts, open http://<truenas-ip>:7681 and log in with admin plus the password you configured.
See docs/truenas-scale.md for extra TrueNAS notes, including permissions and interactive terminal trade-offs.
If Time Machine or other ZFS-backed datasets look impossibly large, see docs/time-machine-zfs-snapshots.md. The usual cause is ncdu counting visible .zfs/snapshot trees, not live files.
Publish to Docker Hub
The repository includes .github/workflows/docker-publish.yml.
Add this GitHub repository secret:
DOCKERHUB_TOKEN
Then run the workflow manually. To tag a release in git:
git tag v0.1.0
git push origin v0.1.0
More detail is in docs/dockerhub-publish.md.
Container Interface
truenas-ncdu [SCAN_PATH] [NCDU_OPTIONS...]
Environment variables:
NCDU_PATH: default scan path. Defaults to/mnt.NCDU_ONE_FILESYSTEM:trueorfalse. Defaults totrue.NCDU_EXCLUDE_ZFS:trueorfalse. Defaults totrue; excludes.zfssnapshot directories.NCDU_BIN: override the binary, mainly for tests.
Examples:
docker run --rm -it -v /mnt:/mnt:ro docker.io/joanmarcriera/truenas-ncdu:latest /mnt/tank/media
docker run --rm -it -v /mnt:/mnt:ro -e NCDU_ONE_FILESYSTEM=false docker.io/joanmarcriera/truenas-ncdu:latest /mnt
docker run --rm -it -v /mnt:/mnt:ro -e NCDU_EXCLUDE_ZFS=false docker.io/joanmarcriera/truenas-ncdu:latest /mnt/tank/media
docker run --rm -it -v /mnt:/mnt:ro docker.io/joanmarcriera/truenas-ncdu:latest sh
docker run --rm docker.io/joanmarcriera/truenas-ncdu:latest --version
docker run --rm -p 7681:7681 -v /mnt:/mnt:ro -e TTYD_PASSWORD=change-me docker.io/joanmarcriera/truenas-ncdu:latest
Development
sh scripts/test.sh
The tests cover the shell entrypoint and build the Docker image when Docker is available.