Edouard Vanbelle 9514f49eed feat(consistency): record what a deep run audited, and make cancel responsive
Two problems a real S3 run exposed, both about a completed run being
unable to answer questions about itself.

## Which storage did this verify?

A finished run recorded `deep`, `verified`, `total_rows` — but not its
target. Findings carry `"backend"`, and a clean run has none, so a green
audit says nothing about what it audited. After switching the active
backend there is no way to tell what a previous run covered.

That is not hypothetical: a 1.5 s local sweep was read as an S3 audit by
both of us for several exchanges, and the run JSON could not settle it.
What settled it was the ABSENCE of a `storage` param, inferred by hand.

Now the outcome carries `backend` (the type), `storage_entry` (the
entry name) and `scoped` (whether `?storage=` was given). The entry name
is read from `admin_settings` at run start rather than snapshotted at
boot, because a migration cutover rewrites it while the process lives —
a cached copy would name the pre-cutover entry, which is the same
staleness trap the `uncached()` unwrap avoids by resolving through
`current()`. Best-effort: it is a label, and failing an audit over one
would be the wrong trade. `ActiveEntry::Unset` stays unlabelled rather
than guessing at the boot fallback.

## Cancel was bounded by a batch, and a batch got 60,000x slower

`BATCH_SIZE`'s comment claimed 500 "keeps the cancel-poll cadence
sub-second (each batch = one backend list + one DB probe + Rust
set-difference)". True when written. Deep mode then moved into this
tenant and added 500 full blob reads per batch: measured at 155 ms each
against OVH S3, so ~63 s per batch. The status poll ran only between
batches, so Pause and Cancel appeared ignored for a minute — on exactly
the run an operator most wants to stop, and one that scales to hours on
a real corpus.

Cancellation is now polled inside the verify loop every
`DEEP_CANCEL_POLL_EVERY` (16) blobs. A poll is one indexed DB read
(~0.1 ms) against a 155 ms remote read, so the cost is under 1% there
and a couple of percent even on a local backend where a verify is
~0.8 ms. `BATCH_SIZE` goes back to being purely about I/O batching, and
its comment now says so.

Pausing mid-batch is safe: the cursor still points at the last completed
batch, so a resume re-verifies this batch's handful of blobs rather than
skipping them. Re-reading a few is the right direction for a check whose
whole purpose is not missing anything.

Measurements quoted throughout are from a live run: 2022 chunks (231
files), 314 s against remote S3 versus 1.567 s local, verified 2022 in
both.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-07 22:23:30 +02:00
2026-05-31 03:53:33 +02:00
2026-05-28 22:37:31 +02:00
2026-06-16 13:51:51 -06:00
2026-08-13 00:30:55 +02:00
2026-08-29 11:57:48 +02:00
2026-06-16 13:51:51 -06:00
2026-06-16 13:51:51 -06:00
2026-08-29 11:57:48 +02:00
2026-09-06 21:52:18 +02:00

OxiCloud logo

A fast self-hosted cloud for people who want files, calendars, contacts, and office editing without dragging a heavy stack behind them.

Documentation · Quick Start · Star OxiCloud · Request a Feature · Supported Clients · Project Status

Latest release CI GitHub stars Docker image size Rust 1.93+ MIT license

If OxiCloud saves you setup time, RAM, or complexity, give it a star. If something is missing, ask for a feature or request a docs improvement.

OxiCloud dashboard

Why People Try OxiCloud

OxiCloud is aimed at self-hosters, home labs, and small teams who want the useful parts of a cloud suite without the operational drag of a traditional PHP stack.

What pulls people in:

  • Standard protocols first: WebDAV, CalDAV, and CardDAV are built in
  • Useful product surface already there: files, previews, sharing, trash, search, favorites, and recent items
  • Modern auth and admin basics: OIDC/SSO, quotas, roles, and shared links
  • Better interoperability: native desktop and mobile clients work without custom sync tooling for basic access
  • Lower deployment friction: Docker Compose, environment-based configuration, Helm chart, and Nix module

OxiCloud is not trying to mirror the full plugin ecosystem of Nextcloud. It is designed for a smaller stack, fast startup, and standards-based interoperability.

Quick Start

Docker Compose

Requires Docker and Docker Compose.

git clone https://github.com/AtalayaLabs/OxiCloud.git
cd OxiCloud
cp example.env .env

# If users will access OxiCloud through a domain or reverse proxy,
# set OXICLOUD_BASE_URL in .env before the first login.
docker compose up -d

Open http://localhost:8086.

Prebuilt binary

Binary releases (Linux musl amd64/arm64, macOS Intel/Apple Silicon) are attached to every tagged release on GitHub — the whole SPA + all operator subcommands + migrations bake into a single self-contained executable. See docs/install/binary.md for the download / verify / systemd walkthrough.

cargo binstall oxicloud works too once a release is out.

Run from source

Requires Rust 1.93+ and PostgreSQL.

git clone https://github.com/AtalayaLabs/OxiCloud.git
cd OxiCloud
cp example.env .env

# If PostgreSQL runs on your host instead of Docker, update both
# OXICLOUD_DB_CONNECTION_STRING and DATABASE_URL to use localhost:5432.
cargo run

Deployment details: deployment guide · example.env

What You Get

Area Included
Files Multi-file upload, folders, inline previews, thumbnails, chunked uploads, deduplication, trash
Sync and clients WebDAV, CalDAV, CardDAV, native OS clients, Thunderbird, DAVx5
Security JWT auth, Argon2id, OIDC/SSO, shared links, quotas, admin/user roles
Integrations REST API and WOPI for Collabora or OnlyOffice
Operations Docker image, Docker Compose, env-driven config, PostgreSQL backend
Project tooling Architecture docs, Helm chart, Nix module, CI

Supported Clients

OxiCloud uses standard DAV protocols, so it works with native clients instead of requiring a custom sync stack for basic access.

Use case URL
Files via WebDAV https://your-host/webdav/
Calendars via CalDAV https://your-host/caldav/
Contacts via CardDAV https://your-host/carddav/

Common clients that work well:

  • macOS Finder
  • Windows Explorer
  • GNOME Files and KDE Dolphin
  • Thunderbird
  • Apple Calendar and Contacts
  • DAVx5 on Android

Client setup guides: DAV client setup · WebDAV guide · CalDAV & CardDAV guide

Project Status

OxiCloud is actively developed and already covers the core self-hosted cloud workflow.

Capability Status Notes
File storage and web UI Ready Uploads, previews, sharing, trash, and search
WebDAV Ready Standard file access for desktop and mobile clients
CalDAV and CardDAV Ready Working with Thunderbird, Apple clients, and others
OIDC / SSO Ready Documentation and config examples included
WOPI office editing Ready Works with Collabora or OnlyOffice
DAVx5 Android support Partial File sync works well; calendar and contact behavior is still being refined
Desktop sync client Planned Not yet available
Mobile apps Planned Not yet available
End-to-end encryption Planned Roadmap item

Roadmap: TODO-LIST.md

Help Shape OxiCloud

If you want OxiCloud to get better faster, use the repo like a product feedback loop, not just a code dump.

The best feature ideas usually come from real deployment pain. If you hit friction, open an issue and describe the workflow you want.

Architecture and Deployment

OxiCloud follows a clean, hexagonal architecture so protocol handlers, business logic, and infrastructure stay separated.

  • Backend: Rust + Axum
  • Database: PostgreSQL
  • Configuration: environment variables
  • Default deployment: Docker Compose
  • Additional packaging: Helm chart and Nix module

Architecture docs: internal architecture · caching architecture · database transactions · storage safety

Configuration and Integrations

Start with example.env. The most important settings are:

  • OXICLOUD_BASE_URL for reverse proxies, domains, and external access
  • OXICLOUD_DB_CONNECTION_STRING for PostgreSQL
  • OXICLOUD_OIDC_ENABLED and related settings for SSO
  • OXICLOUD_WOPI_ENABLED and discovery URL for office editing
  • MIMALLOC_PURGE_DELAY=0 for lower idle RSS in constrained environments

Integration docs: OIDC setup · OIDC architecture · OIDC config examples · WOPI integration

Documentation

Development

cargo fmt --all --check
cargo clippy --all-features --all-targets -- -D warnings
cargo test --workspace

Contributing

Contributions are welcome. Read CONTRIBUTING.md before opening a pull request and CODE_OF_CONDUCT.md for community expectations.

If you are not ready to code yet, starring the project and opening a precise feature request is still a meaningful contribution.

Contributors

OxiCloud is a community-driven project, and we appreciate all contributions. Check out the Contributors page to see the amazing people who have helped make OxiCloud better.

Contributors

Star History

Star History Chart

License

MIT. See LICENSE.

OxiCloud is a trademark of the OxiCloud project. All other trademarks are the property of their respective owners.

S
Description
No description provided
Readme MIT 52 MiB
Languages
Rust 63.5%
Hurl 10.2%
TypeScript 8.5%
Svelte 8.2%
Shell 3.8%
Other 5.6%