This directory and the repo-root artifacts (Dockerfile, docker-compose.yml,
install.sh) cover the supported deployment paths. ScorpioFS mounts a FUSE
filesystem, so every path needs a FUSE-capable host.
ScorpioFS cannot run where FUSE is unavailable. On the host (or container) you need:
- the
fusekernel module loaded and the/dev/fusedevice present; - the
fuse3userspace package (provides the setuidfusermount3helper); - permission to mount — either
CAP_SYS_ADMIN, or unprivileged mounting viafusermount3(therfuse3unprivilegedfeature is enabled in this build).
Run scorpio doctor to check these on a given host.
Not every environment can run FUSE (many managed/rootless container platforms block
/dev/fuseorCAP_SYS_ADMIN). There is no workaround — pick a host that allows it.
/api/fs/*, /api/config, /antares/*, and /health have no authentication.
Anyone who can reach the port can trigger mounts/unmounts. Therefore:
- The systemd unit and the compose example bind the HTTP port to loopback
(
127.0.0.1) by default. - The code default (
scorpio serve) is still0.0.0.0:2725; only change the deployment to a routable address when it sits behind a firewall and/or an authenticating reverse proxy. - Never expose port 2725/2726 directly to an untrusted network.
docker build -t scorpiofs .
docker run --rm \
--device /dev/fuse \
--cap-add SYS_ADMIN \
--security-opt apparmor:unconfined \
-e SCORPIO_BASE_URL=http://your-mega:8000 \
-e SCORPIO_LFS_URL=http://your-mega:8000/lfs \
-p 127.0.0.1:2725:2725 \
scorpiofsSCORPIO_BASE_URL and SCORPIO_LFS_URL are required for serve; the
container entrypoint refuses to start without them (so it never silently points
at localhost).
docker compose up brings up ScorpioFS plus a mega backend; set the mega
image in docker-compose.yml to the one you run (the default tag is a
placeholder). Configuration is entirely env-driven (SCORPIO_*); no developer
paths are baked into the image. The image ships a HEALTHCHECK against
GET /health.
CAP_SYS_ADMINis broad. Grant it only to this workload, and prefer a dedicated, otherwise-unprivileged container.--security-opt apparmor:unconfinedis often required for FUSE mount propagation; scope it tightly.- The reverse proxy (if any) only needs the HTTP port — the FUSE mount lives inside the container and cannot be proxied over HTTP.
Unit files live in systemd/. Typical install:
sudo useradd --system --no-create-home --user-group scorpiofs
sudo usermod -aG fuse scorpiofs
sudo install -D -m0644 deploy/systemd/scorpiofs.service /etc/systemd/system/scorpiofs.service
# Install a config whose paths match the unit's /var/lib/scorpiofs tree. Do NOT
# just copy scorpio.toml.example — its /tmp paths and relative config_file are
# for local dev, and the service (User=scorpiofs, no WorkingDirectory) would
# write state relative to `/`, failing with permission denied.
sudo install -d /etc/scorpiofs
sudo tee /etc/scorpiofs/scorpio.toml >/dev/null <<'EOF'
base_url = "http://your-mega:8000"
lfs_url = "http://your-mega:8000/lfs"
workspace = "/var/lib/scorpiofs/mount"
store_path = "/var/lib/scorpiofs/store"
config_file = "/var/lib/scorpiofs/config.toml"
git_author = "MEGA"
git_email = "admin@mega.org"
log_level = "info"
antares_upper_root = "/var/lib/scorpiofs/antares/upper"
antares_cl_root = "/var/lib/scorpiofs/antares/cl"
antares_mount_root = "/var/lib/scorpiofs/antares/mnt"
antares_state_file = "/var/lib/scorpiofs/antares/state.toml"
EOF
sudo "${EDITOR:-vi}" /etc/scorpiofs/scorpio.toml # set base_url / lfs_url
sudo systemctl daemon-reload
sudo systemctl enable --now scorpiofs
systemctl status scorpiofs(install.sh already generates a /var/lib/scorpiofs-based config for you, so
if you used it you can skip the config step above and just edit base_url/lfs_url.)
The unit uses Type=simple with /health as the external readiness probe
(Type=notify is intentionally not used — the daemon does not implement
sd_notify). TimeoutStopSec=45 exceeds the in-process shutdown budget
(daemon join 20s + Antares cleanup 15s) so graceful unmount completes before
SIGKILL. Restart=on-failure with StartLimitBurst rate-limiting handles
crashes; ExecStopPost lazily unmounts any residual mountpoint.
AmbientCapabilities=CAP_SYS_ADMIN(used by the unit): the service user gets the mount capability without running as root. High privilege — review before enabling.- setuid
fusermount3: thefuse3package's helper is setuid root and can perform unprivileged mounts. If your environment allows it, you can dropCAP_SYS_ADMINand rely onfusermount3instead. Verify withscorpio doctor. - This is FUSE (libfuse-fs userspace OverlayFs), not kernel
overlayfs; do not try tomount -t overlaythese paths.
install.sh downloads a release tarball, verifies its SHA256 checksum, and
installs scorpio/antares plus a generated /etc/scorpiofs/scorpio.toml.
- Always supports
--dry-runto preview every action. - It never modifies
/etc/fuse.confunless you pass--enable-user-allow-other. - System packages are installed via apt/dnf/pacman (skip with
--no-deps). --uninstallremoves the binaries and leaves config/data in place.
bash install.sh --version v0.3.0 --dry-run # preview
sudo bash install.sh --version v0.3.0 # installPushing a v* tag triggers .github/workflows/release.yml, which:
- builds
x86_64-unknown-linux-gnu(and best-effortaarch64-unknown-linux-muslviacross; a failure there does not block the x86_64 release); - packages each target as
scorpiofs-<version>-<target>.tar.gzcontainingscorpio,antares,LICENSE-MIT,LICENSE-APACHE, andREADME.md; - generates a
<tarball>.sha256per artifact plus a combinedSHA256SUMS; - creates a GitHub Release with all artifacts attached.
install.sh downloads the per-target tarball and its .sha256, then runs
sha256sum -c and refuses to install on mismatch.
Publishing to crates.io is decoupled from the binary release: the
publish-crate job targets a protected GitHub Environment (crates-io).
Configure a required reviewer on that environment so an ordinary tag push cannot
publish the crate without manual approval, and store CARGO_REGISTRY_TOKEN as an
environment secret (least privilege).
This project is dual-licensed under MIT (LICENSE-MIT) OR Apache-2.0
(LICENSE-APACHE).