Since the blob storage migration (3c7c16f), thumbnail generation failed
with "No such file or directory" because the handler constructed logical
file paths that don't exist on disk. Resolve the actual blob path via
get_blob_hash() + dedup_service.blob_path() in both upload and get
thumbnail handlers. Add regression tests.
Self-hosted cloud storage, calendar & contacts — blazingly fast.
NextCloud was too slow on my home server. So I built OxiCloud — a complete cloud platform written in Rust that runs on minimal hardware and stays out of your way.
OxiCloud vs NextCloud
| Metric | OxiCloud | NextCloud |
|---|---|---|
| Language | Rust (compiled, zero-cost abstractions) | PHP (interpreted) |
| Docker image | ~40 MB (Alpine, static binary) | ~1 GB+ (Apache + PHP + modules) |
| Idle RAM | ~30–50 MB | ~250–512 MB |
| Cold start | < 1 s | 5–15 s |
| CPU at idle | ~0 % | 1–5 % (cron, background jobs) |
| Min. hardware | 1 vCPU / 512 MB RAM | 2 vCPU / 2 GB RAM (recommended) |
| Concurrent uploads | Parallel chunked (TUS-like), async I/O | Sequential PHP workers |
| File dedup | SHA-256 content-addressable, ref-counting | None (each user = full copy) |
| DB connections | Dual pool (user + maintenance) | Single pool, background jobs compete |
| LTO + PGO | Fat LTO, codegen-units=1, opt-level=3 | N/A (interpreted) |
| Dependencies | Single binary + PostgreSQL | PHP, Apache/Nginx, Redis, Cron, … |
| WebDAV | Built-in (RFC 4918, PROPFIND streaming) | Built-in |
| CalDAV / CardDAV | Built-in | Via apps |
| WOPI (Office editing) | Built-in (Collabora / OnlyOffice) | Via apps |
| OIDC / SSO | Built-in (Keycloak, Authentik, …) | Via apps |
Note: NextCloud is a mature, feature-rich ecosystem. OxiCloud targets users who prioritise raw performance, simplicity, and low resource usage over plugin breadth.
Features
Storage & Files
- Upload / download / organise — drag-and-drop, multi-file, grid & list views
- Chunked uploads — TUS-like protocol, parallel chunks, resumable, MD5 integrity
- File deduplication — SHA-256 content-addressable blobs with automatic ref-counting
- Adaptive compression — zstd / gzip selected per MIME type
- Trash bin — soft-delete, restore, auto-purge by retention policy
- Favourites & recent files
- Full-text search — by name, type, date range, size, recursive subtree (ltree)
- MIME magic-byte detection —
infercrate, not just extension guessing - Inline preview — images, PDF, text, audio & video player modal
- Thumbnails & transcoding — WebP / AVIF on-the-fly via
imagecrate
Protocols
- WebDAV — RFC 4918, streaming PROPFIND, locking, compatible with all major clients
- CalDAV — calendar sync (Thunderbird, GNOME Calendar, iOS, DAVx⁵, …)
- CardDAV — contacts sync with vCard support
- WOPI — edit Office docs in Collabora Online or OnlyOffice
- REST API — complete JSON API for all operations
Security & Auth
- JWT authentication with refresh tokens
- Argon2id password hashing
- OIDC / SSO — Keycloak, Authentik, Authelia, Google, Azure AD…
- Role-based access — admin / user, per-folder permissions
- Storage quotas per user
- Shared links with optional password protection
Infrastructure
- Single binary — no runtime, no interpreter, no framework overhead
- ~40 MB Docker image (Alpine)
- Dual DB pool — dedicated maintenance pool so background tasks never starve user queries
- LTO-optimised release — fat LTO, 1 codegen-unit,
opt-level = 3, stripped - Write-behind caching (moka) — sub-millisecond hot reads
- 112 automated tests —
cargo teston every push (CI) - 9 languages — EN, ES, DE, FR, IT, PT, NL, ZH, FA
Quick Start
Docker (recommended)
git clone https://github.com/DioCrafts/oxicloud.git
cd oxicloud
# Copy and optionally edit environment
cp example.env .env
docker compose up -d
Open http://localhost:8086. That's it.
From source
Requires Rust 1.93+ and PostgreSQL 13+.
git clone https://github.com/DioCrafts/oxicloud.git
cd oxicloud
# Configure database
echo "DATABASE_URL=postgres://user:pass@localhost/oxicloud" > .env
# Build optimised binary
cargo build --release
# Start the server (migrations run automatically)
cargo run --release
Client Setup
OxiCloud speaks standard protocols — any WebDAV / CalDAV / CardDAV client works:
| Client | Protocol | URL |
|---|---|---|
| Windows Explorer | WebDAV | http://host:8086/webdav/ |
| macOS Finder | WebDAV | http://host:8086/webdav/ |
| Nautilus / Dolphin | WebDAV | dav://host:8086/webdav/ |
| Thunderbird (calendar) | CalDAV | http://host:8086/caldav/ |
| Thunderbird (contacts) | CardDAV | http://host:8086/carddav/ |
| DAVx⁵ (Android) | CalDAV + CardDAV | http://host:8086/ |
| GNOME Calendar | CalDAV | http://host:8086/caldav/ |
| GNOME Contacts | CardDAV | http://host:8086/carddav/ |
| Collabora / OnlyOffice | WOPI | See WOPI docs |
For detailed setup guides: WebDAV · CalDAV · CardDAV · OIDC/SSO
Architecture
Clean / Hexagonal architecture — each layer depends only on the one below:
┌───────────────────────────────────────────────────────────────┐
│ Interfaces │ REST API, WebDAV, CalDAV, CardDAV, WOPI │
├───────────────────────────────────────────────────────────────┤
│ Application │ Use cases, DTOs, port definitions │
├───────────────────────────────────────────────────────────────┤
│ Domain │ Entities, business rules, repository traits │
├───────────────────────────────────────────────────────────────┤
│ Infrastructure│ PostgreSQL, filesystem, caching, auth │
└───────────────────────────────────────────────────────────────┘
Swap the database, add a new protocol, or change auth — without touching business logic.
For a deep dive: Internal Architecture · Caching · DB Transactions
Configuration
All config via environment variables (see example.env):
| Variable | Default | Description |
|---|---|---|
OXICLOUD_STORAGE_PATH |
./storage |
Root directory for file storage |
OXICLOUD_SERVER_PORT |
8086 |
HTTP listen port |
OXICLOUD_DB_CONNECTION_STRING |
— | PostgreSQL connection string |
OXICLOUD_JWT_SECRET |
random | Token signing key (set in production!) |
OXICLOUD_OIDC_ENABLED |
false |
Enable OpenID Connect SSO |
OXICLOUD_WOPI_ENABLED |
false |
Enable Collabora / OnlyOffice editing |
OXICLOUD_ENABLE_AUTH |
true |
Toggle authentication |
OXICLOUD_ENABLE_TRASH |
true |
Toggle trash / recycle bin |
Full reference: example.env · Deployment guide · OIDC examples
Development
cargo build # Dev build
cargo run # Run locally
cargo test --workspace # 112 tests
cargo clippy -- -D warnings # Lint (zero warnings policy)
cargo fmt --all --check # Format check
RUST_LOG=debug cargo run # Debug logging
Project stats
| Metric | Value |
|---|---|
| Rust source files | 170 |
| Lines of code | ~50 000 |
| Automated tests | 112 |
| Documentation pages | 35 |
Documentation
Extensive docs live in doc/:
| Topic | Link |
|---|---|
| Deployment & Docker | deployment.md |
| WebDAV integration | webdav-integration-guide.md |
| CalDAV / CardDAV | caldav-technical-spec.md · carddav-technical-spec.md |
| OIDC / SSO setup | oidc-integration.md · oidc-config-examples.md |
| WOPI (Office editing) | wopi-integration.md |
| Chunked uploads | chunked-uploads.md |
| Deduplication | deduplication.md |
| Search | search.md |
| Caching architecture | caching-architecture.md |
| Storage quotas | storage-quotas.md |
| Trash / recycle bin | trash-feature-summary.md |
| Internationalisation | i18n.md |
| Internal architecture | internal-architecture.md |
Roadmap
Check TODO-LIST.md for the full roadmap. Highlights:
- File versioning & diff viewer
- End-to-end encryption
- Desktop sync client (Rust)
- Android / iOS app
- OCR & intelligent tagging
- Automated workflows
Contributing
The project is actively developed. Contributions welcome!
Read CONTRIBUTING.md before submitting a PR. Follow the Code of Conduct.
License
MIT — see LICENSE.
Star History
Questions? Open an issue. Want to help? PRs welcome.
