githttp-fs
githttp-fs is a single Rust binary that wraps git repositories and exposes them as a file-system-over-HTTP API. Each tenant gets its own git repository on disk.
Clients can create, read, update, delete, and move eg. .md/.mdx files via REST — which is the initial usecase githttp-fs was written for. Every write produces a Git commit. A configurable webhook fires after each commit so downstream systems (e.g. a read-only SQL database) can update themselves.
Tested at Rust version: rustc 1.94.0 (4a4ef493e 2026-03-02)
🇵🇹 Crafted in Lisbon, Portugal.
How to use it?
Installation
Install from Docker Hub:
You might find it convenient to run githttp-fs via Docker. You can find the pre-built githttp-fs image on Docker Hub as crispim/githttp-fs.
First, pull the crispim/githttp-fs image:
Then, provide a configuration file and run it (replace /path/to/your/githttp-fs/config.toml with the path to your configuration file):
In the configuration file, ensure that:
server.hostis set to0.0.0.0(this lets githttp-fs be reached from outside the container)server.portis set to5355(this lets githttp-fs be reached from outside the container)
githttp-fs will be reachable from http://localhost:5355.
Install from binary:
A pre-built binary of githttp-fs is shared in the releases on GitHub. You can simply download the latest binary version from the releases page, and run it on your server.
You will still need to provide the binary with the configuration file, so make sure you have a githttp-fs config.toml file ready somewhere.
The binary provided is statically-linked, which means that it will be able to run on any Linux-based system. Still, it will not work on MacOS or Windows machines.
Install from Cargo:
If you prefer managing githttp-fs via Rust's Cargo, install it directly via cargo install:
Ensure that your $PATH is properly configured to source the Crates binaries, and then run githttp-fs using the githttp-fs command.
Install from source:
The last option is to pull the source code from Git and compile githttp-fs via cargo:
You can find the built binaries in the ./target/release directory.
Configuration
Use the sample config.toml configuration file and adjust it to your own environment.
Available configuration options are commented below, with allowed values:
[server]
host(type: string, allowed: IPv4 / IPv6, default:0.0.0.0) — Host the githttp-fs server should listen onport(type: string, allowed: TCP ports, default:5355) — Port the githttp-fs server should listen onapi_key(type: string, allowed: any string, no default) — API key for the githttp-fs HTTP APIrepos_path(type: string, allowed: UNIX path, no default) — Path to all Git repositories (all tenants are stored in this path)log_level(type: string, allowed:debug,info,warn,error, default:info) — Verbosity of logging, set it toerrorin productionallowed_extensions(type: array[string], allowed: file extensions eg.["md", "mdx"], default: none) — Optional whitelist of file extensions accepted for file writes and move destinations; when unset, all extensions are accepted
[hooks]
url(type: string, allowed: URL, default: no default) — URL of the hook receiver, eg. HTTP URL (if any)events(type: array[string], allowed:file.created,file.updated,file.deletedorfile.moved, Default: no default) — List of events to send hooks forretry_attempts(type: number, allowed: any number, Default: no default) — Number of re-delivery attempts to run for a Web Hook that failed deliveryretry_backoff_ms(type: number, allowed: time in milliseconds, Default: no default) — How long to back-off between re-delivery attempts
[hooks.auth]
header(type: string, allowed: any HTTP header name, default: no default) — Authorization header name, as sent to the hook receiver (if any)value(type: string, allowed: any HTTP header value, default: no default) — Authorization header value, as sent to the hook receiver (if any)
[maintenance]
enabled(type: boolean, allowed:true,false, default:true) — Whether to run background repository maintenance (repacks Git objects into a single packfile and expires reflogs, so long-lived repositories stay fast and compact)delay_secs(type: number, allowed: seconds, default:86400) — How long after the first write to a repository its maintenance pass should run; the timer re-arms on the next write after each pass, and repositories that receive no writes are never maintaineddestructive_prune(type: boolean, allowed:true,false, default:false) — Whether the maintenance repack may permanently drop unreachable Git objects (garbage left behind by interrupted writes); commit history and past file versions are never affected either way, but with the defaultfalsemaintenance retains every object and can never destroy data
:fire: Report A Vulnerability
If you find a vulnerability in githttp-fs, you are more than welcome to report it directly to @crisp-oss by sending an encrypted email to security@crisp.chat. Do not report vulnerabilities in public GitHub issues, as they may be exploited by malicious people to target production servers running an unpatched githttp-fs server.
:warning: You must encrypt your email using @crisp-oss GPG public key available at: Vulnerability Disclosures.