dufs is a free, open source file management & sync project written in Rust and released under Apache-2.0. It has 10,756 GitHub stars, 589 forks and 18 open issues, and was last pushed 3 months ago. On this registry it ranks #12 of 20 tracked projects in File Management & Sync, with 5 head-to-head comparisons available.

What is dufs?

Dufs is a Rust command-line file server, released under the Apache-2.0 licence and distributed as dufs, that serves static files, accepts uploads, supports search and access control, and speaks WebDAV from a single binary.

What it is

Dufs is a self-hosted utility file server written in Rust and published through several channels: as a crate on crates.io, as a Homebrew formula, as the Docker image sigoden/dufs, and as prebuilt binaries for macOS, Linux and Windows on GitHub Releases. It lives in the same space as command-line static servers and WebDAV servers, and the registry lists it under Productivity & Utilities / File Management & Sync with topics covering cloud disk, file sharing, file upload serving, static serving and WebDAV.

The concrete problem it solves is fragmentation. Exposing a directory over HTTP normally means running a static web server, adding a separate service to accept uploads, adding another if WebDAV clients must connect, and then scripting against each of them. Dufs collapses all of that into one process: it serves static files, accepts drag-and-drop uploads from the browser, exposes upload, download, delete, move and directory creation over plain HTTP methods that work directly with curl, and answers WebDAV requests such as MKCOL and MOVE. The same server can serve a single file, a folder, a static site or a single-page application.

Key capabilities

  • Static serving with rendering modes controlled by --render-index, --render-try-index and --render-spa, so a directory with index.html or a React/Vue style SPA can be served directly.
  • Uploads and downloads, including drag-and-drop folder upload and resumable or partial transfers, gated by --allow-upload or opened up entirely with -A, --allow-all.
  • Folder download as a zip archive through the ?zip query parameter, with --compress accepting none, low, medium or high.
  • Access control through -a, --auth role strings such as user:pass@/dir1:rw,/dir2, plus granular switches --allow-delete, --allow-search, --allow-symlink, --allow-archive and --allow-hash.
  • HTTPS via --tls-cert and --tls-key, with binding controlled by -b, --bind and -p, --port, including binding to a unix socket such as /tmp/dufs.socket.
  • A curl-friendly API: curl -T path-to-file http://127.0.0.1:5000/new-path/path-to-file uploads, curl -o path-to-folder.zip http://127.0.0.1:5000/path-to-folder?zip downloads an archive, and ?hash returns the file's sha256 hash.
  • Operational controls including -c, --config, --path-prefix, --hidden, --enable-cors, --log-format, --log-file, --assets, and shell completion generation for bash, zsh, fish, powershell and elvish.

Who uses it and how

  • A single person sharing a folder on a local network runs dufs with no arguments, which serves the current working directory read-only on port 5000 as a quick read-only static server.
  • A team needing a shared drop folder runs dufs -A or dufs --allow-upload to permit upload, delete, search, create and edit operations against a directory.
  • Distributing a single large artifact, such as an ISO, is done with dufs linux-distro.iso, which serves one file rather than a directory tree.
  • Web front ends are served with --render-spa for single-page applications or --render-index for static sites, while --enable-cors supports browser clients calling the API from another origin.
  • Automation and CI scripts drive the server over HTTP with curl for uploads, downloads, deletes and moves instead of using a GUI or a dedicated client library.

Getting started

Install with cargo install dufs, brew install dufs, or by unzipping a binary from GitHub Releases. Run via Docker with docker run -v \pwd`:/data -p 5000:5000 --rm sigoden/dufs /data -A, or start the local binary against a path, for example dufs Downloads`.

How it compares

The facts provided name no competing products and no paid tools that this project replaces, so no licence, hosting or cost comparison can be drawn. Dufs therefore stands alone in this registry entry as a Rust single-binary file server with static serving, upload, search, access control and WebDAV combined in one process.

When to use it — and when not to

The README describes no external dependencies such as a database, object storage or SMTP service, so a self-hoster operates only the binary, the served directory, and any TLS certificates passed through --tls-cert and --tls-key. Authentication is expressed as role strings on the command line or in a config file rather than as a user database, so anyone needing per-user accounts, audit trails or database-backed permissions should look elsewhere. The README is short and centred on the CLI reference, so operators who need detailed hardening guidance should expect to work it out themselves.

project readme (upstream, from github) — read inline

Dufs

CI Crates Docker Pulls

Dufs is a distinctive utility file server that supports static serving, uploading, searching, accessing control, webdav...

demo

Features

  • Serve static files
  • Download folder as zip file
  • Upload files and folders (Drag & Drop)
  • Create/Edit/Search files
  • Resumable/partial uploads/downloads
  • Access control
  • Support https
  • Support webdav
  • Easy to use with curl

Install

With cargo

cargo install dufs

With docker

docker run -v `pwd`:/data -p 5000:5000 --rm sigoden/dufs /data -A

With Homebrew

brew install dufs

Binaries on macOS, Linux, Windows

Download from Github Releases, unzip and add dufs to your $PATH.

CLI

Dufs is a distinctive utility file server - https://github.com/sigoden/dufs

Usage: dufs [OPTIONS] [serve-path]

Arguments:
  [serve-path]  Specific path to serve [default: .]

Options:
  -c, --config <file>        Specify configuration file
  -b, --bind <addrs>         Specify bind address or unix socket
  -p, --port <port>          Specify port to listen on [default: 5000]
      --path-prefix <path>   Specify a path prefix
      --hidden <value>       Hide paths from directory listings, e.g. tmp,*.log,*.lock
  -a, --auth <rules>         Add auth roles, e.g. user:pass@/dir1:rw,/dir2
  -A, --allow-all            Allow all operations
      --allow-upload         Allow upload files/folders
      --allow-delete         Allow delete files/folders
      --allow-search         Allow search files/folders
      --allow-symlink        Allow symlink to files/folders outside root directory
      --allow-archive        Allow download folders as archive file
      --allow-hash           Allow ?hash query to get file sha256 hash
      --enable-cors          Enable CORS, sets `Access-Control-Allow-Origin: *`
      --render-index         Serve index.html when requesting a directory, returns 404 if not found index.html
      --render-try-index     Serve index.html when requesting a directory, returns directory listing if not found index.html
      --render-spa           Serve SPA(Single Page Application)
      --assets <path>        Set the path to the assets directory for overriding the built-in assets
      --log-format <format>  Customize http log format
      --log-file <file>      Specify the file to save logs to, other than stdout/stderr
      --compress <level>     Set zip compress level [default: low] [possible values: none, low, medium, high]
      --completions <shell>  Print shell completion script for <shell> [possible values: bash, elvish, fish, powershell, zsh]
      --tls-cert <path>      Path to an SSL/TLS certificate to serve with HTTPS
      --tls-key <path>       Path to the SSL/TLS certificate's private key
  -h, --help                 Print help
  -V, --version              Print version

Examples

Serve current working directory in read-only mode

dufs

Allow all operations like upload/delete/search/create/edit...

dufs -A

Only allow upload operation

dufs --allow-upload

Serve a specific directory

dufs Downloads

Serve a single file

dufs linux-distro.iso

Serve a single-page application like react/vue

dufs --render-spa

Serve a static website with index.html

dufs --render-index

Require username/password

dufs -a admin:123@/:rw

Listen on specific host:ip

dufs -b 127.0.0.1 -p 80

Listen on unix socket

dufs -b /tmp/dufs.socket

Use https

dufs --tls-cert my.crt --tls-key my.key

API

Upload a file

curl -T path-to-file http://127.0.0.1:5000/new-path/path-to-file

Download a file

curl http://127.0.0.1:5000/path-to-file           # download the file
curl http://127.0.0.1:5000/path-to-file?hash      # retrieve the sha256 hash of the file

Download a folder as zip file

curl -o path-to-folder.zip http://127.0.0.1:5000/path-to-folder?zip

Delete a file/folder

curl -X DELETE http://127.0.0.1:5000/path-to-file-or-folder

Create a directory

curl -X MKCOL http://127.0.0.1:5000/path-to-folder

Move the file/folder to the new path

curl -X MOVE http://127.0.0.1:5000/path -H "Destination: http://127.0.0.1:5000/new-path"

List/search directory contents

curl http://127.0.0.1:5000?q=Dockerfile           # search for files, similar to `find -name Dockerfile`
curl http://127.0.0.1:5000?simple                 # output names only, similar to `ls -1`
curl http://127.0.0.1:5000?json                   # output paths in json format

With authorization (Both basic or digest auth works)

curl http://127.0.0.1:5000/file --user user:pass                 # basic auth
curl http://127.0.0.1:5000/file --user user:pass --digest        # digest auth

Resumable downloads

curl -C- -o file http://127.0.0.1:5000/file

Resumable uploads

upload_offset=$(curl -I -s http://127.0.0.1:5000/file | tr -d '\r' | sed -n 's/content-length: //p')
dd skip=$upload_offset if=file status=none ibs=1 | \
  curl -X PATCH -H "X-Update-Range: append" --data-binary @- http://127.0.0.1:5000/file

Health checks

curl http://127.0.0.1:5000/__dufs__/health

Advanced Topics

Access Control

Dufs supports account based access control. You can control who can do what on which path with --auth/-a.

dufs -a admin:admin@/:rw -a guest:guest@/
dufs -a user:pass@/:rw,/dir1 -a @/
  1. Use @ to separate the account and paths. No account means anonymous user.
  2. Use : to separate the username and password of the account.
  3. Use , to separate paths.
  4. Use path suffix :rw/:ro set permissions: read-write/read-only. :ro can be omitted.
  • -a admin:admin@/:rw: admin has complete permissions for all paths.
  • -a guest:guest@/: guest has read-only permissions for all paths.
  • -a user:pass@/:rw,/dir1: user has read-write permissions for /*, has read-only permissions for /dir1/*.
  • -a @/: All paths is publicly accessible, everyone can view/download it.

Auth permissions are restricted by dufs global permissions. If dufs does not enable upload permissions via --allow-upload, then the account will not have upload permissions even if it is granted read-write(:rw) permissions.

Hashed Password

DUFS supports the use of sha-512 hashed password.

Create hashed password:

$ openssl passwd -6 123456 # or `mkpasswd -m sha-512 123456`
$6$tWMB51u6Kb2ui3wd$5gVHP92V9kZcMwQeKTjyTRgySsYJu471Jb1I6iHQ8iZ6s07GgCIO69KcPBRuwPE5tDq05xMAzye0NxVKuJdYs/

Use hashed password:

dufs -a 'admin:$6$tWMB51u6Kb2ui3wd$5gVHP92V9kZcMwQeKTjyTRgySsYJu471Jb1I6iHQ8iZ6s07GgCIO69KcPBRuwPE5tDq05xMAzye0NxVKuJdYs/@/:rw'

The hashed password contains $6, which can expand to a variable in some shells, so you have to use single quotes to wrap it.

Two important things for hashed passwords:

  1. Dufs only supports sha-512 hashed passwords, so ensure that the password string always starts with $6$.
  2. Digest authentication does not function properly with hashed passwords.

Hide Paths

Dufs supports hiding paths from directory listings via option --hidden ,....

dufs --hidden .git,.DS_Store,tmp

The glob used in --hidden only matches file and directory names, not paths. So --hidden dir1/file is invalid.

dufs --hidden '.*'                          # hidden dotfiles
dufs --hidden '*/'                          # hidden all folders
dufs --hidden '*.log,*.lock'                # hidden by exts
dufs --hidden '*.log' --hidden '*.lock'

Log Format

Dufs supports customize http log format with option --log-format.

The log format can use following variables.

variable description
$remote_addr client address
$remote_user user name supplied with authentication
$request full original request line
$status response status
$http_ arbitrary request header field. examples: $http_user_agent, $http_referer

The default log format is '$time_iso8601 $log_level - $remote_addr "$request" $status.

2022-08-06T06:59:31+0

readme truncated — read the full docs on github

Frequently asked questions

Is dufs free to use?

dufs is open source under the Apache-2.0 licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does dufs do?

A file server that supports static serving, uploading, searching, accessing control, webdav...

What is dufs written in?

dufs is primarily written in Rust. Its source is publicly available at https://github.com/sigoden/dufs, and it has 10,756 GitHub stars.