Docker Deployment
The easiest way to run FsPulse is with Docker. The container runs FsPulse as a background service with the web UI accessible on port 8080. You can manage roots, initiate scans, query data, and view results—all from your browser.
Quick Start
Get FsPulse running in three simple steps:
# 1. Pull the image
docker pull gtunesdev/fspulse:latest
# 2. Run the container
docker run -d \
--name fspulse \
-p 8080:8080 \
-v fspulse-data:/data \
gtunesdev/fspulse:latest
# 3. Access the web UI
open http://localhost:8080
That's it! The web UI is now running.
This basic setup stores all FsPulse data (database, config, logs) in a Docker volume and uses default settings. If you need to customize settings (like running as a specific user for NAS deployments, or changing the port), see the Configuration and NAS Deployments sections below.
Scanning Your Files
To scan directories on your host machine, you need to mount them into the container. FsPulse can then scan these mounted paths.
Mounting Directories
Add -v
flags to mount host directories into the container. We recommend mounting them under /roots
for clarity:
docker run -d \
--name fspulse \
-p 8080:8080 \
-v fspulse-data:/data \
-v ~/Documents:/roots/documents:ro \
-v ~/Photos:/roots/photos:ro \
gtunesdev/fspulse:latest
The :ro
(read-only) flag is recommended for safety—FsPulse only reads files during scans and never modifies them.
Creating Roots in the Web UI
After mounting directories:
- Open http://localhost:8080 in your browser
- Navigate to Manage Roots in the sidebar
- Click Add Root
- Enter the container path:
/roots/documents
(not the host path~/Documents
) - Click Create Root
Important: Always use the container path (e.g., /roots/documents
), not the host path. The container doesn't know about host paths.
Once roots are created, you can scan them from the web UI and monitor progress in real-time.
Docker Compose (Recommended)
For persistent deployments, Docker Compose is cleaner and easier to manage:
version: '3.8'
services:
fspulse:
image: gtunesdev/fspulse:latest
container_name: fspulse
restart: unless-stopped
ports:
- "8080:8080"
volumes:
# Persistent data storage - REQUIRED
# Must map /data to either a Docker volume (shown here) or a host path
# Must support read/write access for database, config, and logs
- fspulse-data:/data
# Alternative: use a host path instead
# - /path/on/host/fspulse-data:/data
# Directories to scan (read-only recommended for safety)
- ~/Documents:/roots/documents:ro
- ~/Photos:/roots/photos:ro
environment:
# Optional: override any configuration setting
# See Configuration section below and https://gtunes-dev.github.io/fspulse/configuration.html
- TZ=America/New_York
volumes:
fspulse-data:
Save as docker-compose.yml
and run:
docker-compose up -d
Configuration
FsPulse creates a default config.toml
on first run with sensible defaults. Most users won't need to change anything, but when you do, there are three ways to customize settings.
Option 1: Use Environment Variables (Easiest)
Override any setting using environment variables. This works with both docker run
and Docker Compose.
Docker Compose example:
services:
fspulse:
image: gtunesdev/fspulse:latest
environment:
- FSPULSE_SERVER_PORT=9090 # Change web UI port
- FSPULSE_LOGGING_FSPULSE=debug # Enable debug logging
- FSPULSE_ANALYSIS_THREADS=16 # Use 16 analysis threads
ports:
- "9090:9090"
Command line example (equivalent to above):
docker run -d \
--name fspulse \
-p 9090:9090 \
-e FSPULSE_SERVER_PORT=9090 \
-e FSPULSE_LOGGING_FSPULSE=debug \
-e FSPULSE_ANALYSIS_THREADS=16 \
-v fspulse-data:/data \
gtunesdev/fspulse:latest
Environment variables follow the pattern FSPULSE_<SECTION>_<FIELD>
and override any settings in config.toml
. See the Configuration chapter for a complete list of available variables and their purposes.
Option 2: Edit the Config File
If you prefer editing the config file directly:
-
Extract the auto-generated config:
docker exec fspulse cat /data/config.toml > config.toml
-
Edit
config.toml
with your preferred settings -
Copy back and restart:
docker cp config.toml fspulse:/data/config.toml docker restart fspulse
Option 3: Pre-Mount Your Own Config (Advanced)
If you want custom settings before first launch, create your own config.toml
and mount it:
volumes:
- fspulse-data:/data
- ./my-config.toml:/data/config.toml:ro
Most users should start with Option 1 (environment variables) or Option 2 (edit after first run).
NAS Deployments (TrueNAS, Unraid)
NAS systems often have specific user IDs for file ownership. By default, FsPulse runs as user 1000, but you may need it to match your file ownership.
Setting User and Group IDs
Use PUID
and PGID
environment variables to run FsPulse as a specific user:
TrueNAS Example (apps user = UID 34):
docker run -d \
--name fspulse \
-p 8080:8080 \
-e PUID=34 \
-e PGID=34 \
-e TZ=America/New_York \
-v /mnt/pool/fspulse/data:/data \
-v /mnt/pool/documents:/roots/docs:ro \
gtunesdev/fspulse:latest
Unraid Example (custom UID 1001):
docker run -d \
--name fspulse \
-p 8080:8080 \
-e PUID=1001 \
-e PGID=100 \
-v /mnt/user/appdata/fspulse:/data \
-v /mnt/user/photos:/roots/photos:ro \
gtunesdev/fspulse:latest
Why PUID/PGID Matters
Even though you mount directories as read-only (:ro
), Linux permissions still apply. If your files are owned by UID 34 and aren't world-readable, FsPulse (running as UID 1000 by default) won't be able to scan them. Setting PUID=34
makes FsPulse run as the same user that owns the files.
When to use PUID/PGID:
- Files have restrictive permissions (not world-readable)
- Using NAS with specific user accounts (TrueNAS, Unraid, Synology)
- You need the
/data
directory to match specific host ownership
Using the CLI
While the web UI provides full functionality, you can also use CLI commands via docker exec
:
# Run a query
docker exec fspulse fspulse query "items where scan:(5)"
# View reports
docker exec fspulse fspulse report scans --last 10
# Interactive menu (requires -it flags)
docker exec -it fspulse fspulse interact
# Data explorer TUI (requires -it flags)
docker exec -it fspulse fspulse explore
The -it
flags are required for interactive modes (interact
and explore
) to properly handle terminal input.
Helper script (optional): Create fspulse-docker.sh
to simplify CLI access:
#!/bin/bash
docker exec fspulse fspulse "$@"
Then use it: ./fspulse-docker.sh query "items limit 10"
Advanced Topics
Custom Network Settings
If you're using macvlan or host networking, ensure the server binds to all interfaces:
services:
fspulse:
image: gtunesdev/fspulse:latest
network_mode: host
environment:
- FSPULSE_SERVER_HOST=0.0.0.0 # Required for non-bridge networking
- FSPULSE_SERVER_PORT=8080
Note: The Docker image sets FSPULSE_SERVER_HOST=0.0.0.0
by default, so this is only needed if your config.toml overrides it to 127.0.0.1
.
Reverse Proxy Setup
For public access with authentication, use a reverse proxy like nginx:
server {
listen 80;
server_name fspulse.example.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# WebSocket support for scan progress
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
Using Bind Mounts Instead of Volumes
By default, we use Docker volumes (-v fspulse-data:/data
) which Docker manages automatically. For NAS deployments, you might prefer bind mounts to integrate with your existing backup schemes:
# Create directory on host
mkdir -p /mnt/pool/fspulse/data
# Use bind mount
docker run -d \
--name fspulse \
-p 8080:8080 \
-v /mnt/pool/fspulse/data:/data \ # Bind mount to host path
gtunesdev/fspulse:latest
Benefits of bind mounts for NAS:
- Included in your NAS snapshot schedule
- Backed up with your existing backup system
- Directly accessible for manual inspection
Trade-off: You need to manage permissions yourself (use PUID/PGID if needed).
Troubleshooting
Cannot Access Web UI
Problem: http://localhost:8080 doesn't respond
Solutions:
-
Check the container is running:
docker ps | grep fspulse
-
Check logs for errors:
docker logs fspulse
Look for "Server started" message.
-
Verify port mapping:
docker port fspulse
Should show
8080/tcp -> 0.0.0.0:8080
Permission Denied Errors
Problem: "Permission denied" when scanning or accessing /data
Solutions:
-
Check file ownership:
ls -ln /path/to/your/files
-
Set PUID/PGID to match file owner:
docker run -e PUID=1000 -e PGID=1000 ...
-
For bind mounts, ensure host directory is writable:
chown -R 1000:1000 /mnt/pool/fspulse/data
Interactive Mode Doesn't Work
Problem: fspulse interact
or fspulse explore
looks broken in docker exec
Solution: Use -it
flags for proper terminal:
# Wrong (missing -it)
docker exec fspulse fspulse interact
# Correct
docker exec -it fspulse fspulse interact
Configuration Changes Don't Persist
Problem: Settings revert after container restart
Solution: Verify /data
volume is mounted:
docker inspect fspulse | grep -A 10 Mounts
If missing, recreate container with volume:
docker stop fspulse
docker rm fspulse
docker run -d --name fspulse -v fspulse-data:/data ...
Database Locked Errors
Problem: "Database is locked" errors
Cause: Multiple containers accessing the same database
Solution: Only run one FsPulse container per database. Don't mount the same /data
volume to multiple containers.
Data Backup
Backing Up Your Data
For Docker volumes:
# Stop container
docker stop fspulse
# Backup volume
docker run --rm \
-v fspulse-data:/data \
-v $(pwd):/backup \
alpine tar czf /backup/fspulse-backup.tar.gz /data
# Restart container
docker start fspulse
For bind mounts:
# Simply backup the host directory
tar czf fspulse-backup.tar.gz /mnt/pool/fspulse/data
Restoring from Backup
For Docker volumes:
# Create volume
docker volume create fspulse-data-restored
# Restore data
docker run --rm \
-v fspulse-data-restored:/data \
-v $(pwd):/backup \
alpine sh -c "cd / && tar xzf /backup/fspulse-backup.tar.gz"
# Use restored volume
docker run -d --name fspulse -v fspulse-data-restored:/data ...
For bind mounts:
tar xzf fspulse-backup.tar.gz -C /mnt/pool/fspulse/data
Image Tags and Updates
FsPulse provides multiple tags for different update strategies:
Tag | Description | When to Use |
---|---|---|
latest | Latest stable release | Production (pinned versions) |
1.2.3 | Specific version | Production (exact control) |
1.2 | Latest patch of minor version | Production (auto-patch updates) |
main | Development builds | Testing new features |
Recommendation: Use specific version tags (1.2.3
) or minor version tags (1.2
) for production. Avoid latest
in production to prevent unexpected updates.
Updating to a new version:
docker pull gtunesdev/fspulse:1.2.3
docker stop fspulse
docker rm fspulse
docker run -d --name fspulse -v fspulse-data:/data ... gtunesdev/fspulse:1.2.3
Your data persists in the volume across updates.
Platform Support
FsPulse images support multiple architectures—Docker automatically pulls the correct one for your platform:
- linux/amd64 - Intel/AMD processors (most common)
- linux/arm64 - ARM processors (Apple Silicon, Raspberry Pi 4, ARM servers)
Next Steps
- Explore the Configuration reference for all available settings
- Learn about Query Syntax for advanced data filtering
- Read Scanning to understand how scans work
- Check Command-Line Interface for all CLI commands
Getting Help
- Issues: GitHub Issues
- Docker Hub: gtunesdev/fspulse
- Documentation: FsPulse Book