feat: add VitePress docs site, music file picker modal, Dockerfile optimization, i18n keys for 14 locales

- Add docs/ with VitePress site (19 pages): guide, config, architecture, FAQ
- Add GitHub Actions workflow for auto-deploy to GitHub Pages
- Replace music 'Add Tracks' upload picker with in-app audio file browser modal
- Add music picker CSS styles with dark theme support
- Add missing i18n keys (search_audio, no_audio_files, etc.) to all 14 locales
- Optimize Dockerfile: shared base stage, COPY --chmod, consolidated RUN, HEALTHCHECK
- Improve README: docs links, updated stats (222+ tests, 14 languages), feature status
This commit is contained in:
Diocrafts
2026-04-11 20:58:34 +02:00
parent 1bb65e6448
commit f08cffc0e8
42 changed files with 4313 additions and 95 deletions
+70
View File
@@ -0,0 +1,70 @@
# CalDAV & CardDAV
OxiCloud provides built-in CalDAV (calendar) and CardDAV (contacts) servers — no extra apps or plugins needed.
## CalDAV (Calendars)
### Endpoint
```
https://your-server:8086/caldav/
```
### Protocol Compliance
- RFC 4791 (Calendar Access)
- RFC 5545 (iCalendar format)
- DAV capabilities: `1, 2, calendar-access`
### Client Setup
| Client | URL |
|--------|-----|
| Thunderbird | `https://your-server:8086/caldav/` |
| GNOME Calendar | `https://your-server:8086/caldav/` |
| Apple Calendar (macOS/iOS) | `https://your-server:8086/caldav/` |
| DAVx⁵ (Android) | `https://your-server:8086/` (auto-discovery) |
### Thunderbird Setup
1. Open Thunderbird → **Calendar** tab
2. Right-click → **New Calendar** → **On the Network**
3. Format: **CalDAV**
4. URL: `https://your-server:8086/caldav/`
5. Enter your OxiCloud credentials
---
## CardDAV (Contacts)
### Endpoint
```
https://your-server:8086/carddav/
```
### Protocol Compliance
- RFC 6352 (CardDAV)
- RFC 6350 (vCard 4.0)
### Client Setup
| Client | URL |
|--------|-----|
| Thunderbird | `https://your-server:8086/carddav/` |
| GNOME Contacts | `https://your-server:8086/carddav/` |
| Apple Contacts (macOS/iOS) | `https://your-server:8086/carddav/` |
| DAVx⁵ (Android) | `https://your-server:8086/` (auto-discovery) |
### DAVx⁵ (Android) Setup
1. Install [DAVx⁵](https://www.davx5.com/) from F-Droid or Play Store
2. Add account → **Login with URL and user name**
3. Base URL: `https://your-server:8086/`
4. Enter your OxiCloud credentials
5. DAVx⁵ auto-discovers both CalDAV and CardDAV endpoints
::: info
DAVx⁵ file sync works. CalDAV/CardDAV support on DAVx⁵ is still being refined.
:::
+63
View File
@@ -0,0 +1,63 @@
# Chunked Uploads
OxiCloud supports TUS-like chunked uploads for large files. Uploads are parallel, resumable, and have MD5 integrity checks.
## How It Works
1. Client sends `POST /api/files/upload/init` with file metadata → receives an `upload_id`
2. Client splits the file into chunks and uploads them in parallel via `POST /api/files/upload/chunk`
3. Each chunk includes its index, MD5 hash, and the `upload_id`
4. When all chunks are uploaded, client calls `POST /api/files/upload/complete`
5. Server reassembles the file, verifies integrity, and runs deduplication
## API Endpoints
### Initialize Upload
```http
POST /api/files/upload/init
Content-Type: application/json
{
"file_name": "large-video.mp4",
"folder_id": "folder-uuid",
"total_size": 524288000,
"chunk_size": 8388608,
"total_chunks": 63
}
```
### Upload Chunk
```http
POST /api/files/upload/chunk
Content-Type: multipart/form-data
upload_id: "uuid"
chunk_index: 0
chunk_hash: "md5-hex"
file: <binary>
```
### Complete Upload
```http
POST /api/files/upload/complete
Content-Type: application/json
{
"upload_id": "uuid"
}
```
## Configuration
| Parameter | Default | Description |
|---|---|---|
| Max parallel chunks | 8 | Concurrent chunk uploads |
| Min size for chunking | 200 MB | Below this, single-shot upload is used |
| Chunk size | 8 MB | Default chunk size |
## Frontend Behaviour
The OxiCloud web UI automatically selects chunked upload for large files. A progress bar shows overall completion and current chunk status.
+46
View File
@@ -0,0 +1,46 @@
# File Deduplication
OxiCloud uses **SHA-256 content-addressable storage** to avoid storing duplicate files. If two users upload the same file, only one copy is stored on disk.
## How It Works
1. When a file is uploaded, its SHA-256 hash is computed
2. The hash is checked against the blob store (`.blobs/{prefix}/{hash}.blob`)
3. If a blob with that hash already exists, the file metadata points to the existing blob (no extra disk usage)
4. If not, the content is saved as a new blob
5. A reference counter tracks how many files point to each blob
## Automatic Cleanup
When a file is permanently deleted:
1. The blob's reference count is decremented
2. If the reference count reaches zero, the blob is removed from disk
This means disk space is only freed when the **last** reference to a blob is removed.
## Storage Layout
```
storage/
├── .blobs/
│ ├── a1/
│ │ └── a1b2c3d4...sha256.blob
│ ├── f8/
│ │ └── f8e7d6c5...sha256.blob
│ └── ...
```
The first two hex characters of the hash are used as a directory prefix to avoid having millions of files in a single directory.
## Benefits
- **Disk savings** — identical files across users consume storage only once
- **Instant uploads** — if the blob already exists, the upload completes immediately
- **Integrity** — SHA-256 ensures bit-for-bit correctness
## Limitations
- Deduplication is based on exact content match (byte-identical files)
- Near-duplicate files (e.g., a JPEG re-saved at slightly different quality) are stored separately
- Encryption at rest would require per-user keys, which breaks deduplication (planned as opt-in)
+81
View File
@@ -0,0 +1,81 @@
# What is OxiCloud?
OxiCloud is a self-hosted cloud platform written in Rust. It provides file storage, calendar sync (CalDAV), contacts sync (CardDAV), and office document editing (WOPI) — all from a single binary.
NextCloud was too slow on a home server. So OxiCloud was built to run on minimal hardware and stay out of the 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 |
| **File dedup** | SHA-256 content-addressable | None |
| **Dependencies** | Single binary + PostgreSQL | PHP, Apache/Nginx, Redis, Cron, … |
| **WebDAV** | Built-in (RFC 4918) | Built-in |
| **CalDAV / CardDAV** | Built-in | Via apps |
| **WOPI** | Built-in | Via apps |
| **OIDC / SSO** | Built-in | Via apps |
> NextCloud is a mature, feature-rich ecosystem. OxiCloud targets users who prioritise raw performance, simplicity, and low resource usage over plugin breadth.
## Key Features
### Storage & Files
- Drag-and-drop upload, multi-file, grid & list views
- Chunked uploads (TUS-like, parallel, resumable, MD5 integrity)
- SHA-256 content-addressable file deduplication with ref-counting
- Adaptive compression (zstd / gzip per MIME type)
- Trash bin with soft-delete and auto-purge
- Favourites, recent files, full-text search
- Inline preview for images, PDF, text, audio & video
- On-the-fly thumbnails & transcoding (WebP / AVIF)
### Protocols
- **WebDAV** — RFC 4918, streaming PROPFIND, locking
- **CalDAV** — calendar sync (Thunderbird, GNOME Calendar, iOS, DAVx⁵)
- **CardDAV** — contacts sync with vCard support
- **WOPI** — Collabora Online / OnlyOffice
- **REST API** — complete JSON API
### Security
- JWT + Argon2id password hashing
- OIDC / SSO (Keycloak, Authentik, Authelia, Google, Azure AD)
- Role-based access, per-folder permissions, storage quotas
- Shared links with optional password protection
### Infrastructure
- Single binary, ~40 MB Docker image
- Dual DB pool (user queries never starved by background tasks)
- Write-behind caching (moka) for sub-millisecond reads
- LTO-optimised release builds
- 222+ automated tests
## Feature Status
| Feature | Status |
|---------|--------|
| File storage & upload | ✅ Working |
| WebDAV | ✅ Working |
| CalDAV | ✅ Working |
| CardDAV | ✅ Working |
| WOPI / Office editing | ✅ Working |
| OIDC / SSO | ✅ Working |
| Trash / recycle bin | ✅ Working |
| Full-text search | ✅ Working |
| Shared links | ✅ Working |
| Music library & playlists | ✅ Working |
| Photo gallery | ✅ Working |
| Desktop sync client | ❌ Planned |
| Android / iOS app | ❌ Planned |
| E2E encryption | ❌ Planned |
## Next Steps
- [Quick Start →](/guide/installation)
- [Deployment & Docker →](/config/deployment)
- [Architecture →](/architecture/)
+94
View File
@@ -0,0 +1,94 @@
# Quick Start
## Docker (recommended)
```bash
git clone https://github.com/DioCrafts/oxicloud.git
cd oxicloud
cp example.env .env
docker compose up -d
```
Open **http://localhost:8086**. That's it.
### Docker Compose
```yaml
services:
postgres:
image: postgres:17.4-alpine
environment:
POSTGRES_DB: oxicloud
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- pg_data:/var/lib/postgresql/data
- ./db/schema.sql:/docker-entrypoint-initdb.d/schema.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
oxicloud:
image: oxicloud:latest
ports:
- "8086:8086"
env_file:
- .env
volumes:
- storage_data:/app/storage
depends_on:
postgres:
condition: service_healthy
volumes:
pg_data:
storage_data:
```
## From Source
Requires **Rust 1.93+** and **PostgreSQL 13+**.
```bash
git clone https://github.com/DioCrafts/oxicloud.git
cd oxicloud
echo "DATABASE_URL=postgres://user:pass@localhost/oxicloud" > .env
cargo build --release
cargo run --release
```
## Kubernetes (Helm)
```bash
helm upgrade --install oxicloud charts/oxicloud \
-f charts/oxicloud/values.yaml
```
Verify:
```bash
kubectl get pods -n oxicloud
kubectl logs statefulset/oxicloud -n oxicloud
```
## Client Setup
| 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 configuration](/config/wopi) |
## What's Next?
- [Environment Variables →](/config/env)
- [OIDC / SSO Setup →](/config/oidc)
- [WebDAV Guide →](/guide/webdav)
+43
View File
@@ -0,0 +1,43 @@
# Search
OxiCloud provides full-text search across your files with multiple filter options.
## Endpoint
```http
GET /api/search?q=report&type_filter=pdf,docx&recursive=true
```
## Query Parameters
| Parameter | Description |
|---|---|
| `q` | Search query (matches file name) |
| `type_filter` | Comma-separated file extensions to filter by |
| `folder_id` | Restrict search to a specific folder |
| `recursive` | `true` to search subfolders |
| `date_from` / `date_to` | Filter by modification date |
| `size_min` / `size_max` | Filter by file size (bytes) |
| `limit` | Maximum results to return |
| `offset` | Pagination offset |
## How It Works
OxiCloud stores file metadata in PostgreSQL with an `ltree` path column, enabling efficient recursive subtree queries:
```sql
SELECT * FROM storage.files
WHERE path <@ 'root.folder_id'
AND LOWER(name) LIKE '%query%'
AND LOWER(extension) = ANY('{pdf,docx}')
ORDER BY updated_at DESC
LIMIT 50;
```
## Frontend
The web UI includes a search bar in the toolbar. Results appear instantly with file name, path, size, and type. Clicking a result navigates to the file's location.
## Feature Flag
Search can be disabled via `OXICLOUD_ENABLE_SEARCH=false`.
+27
View File
@@ -0,0 +1,27 @@
# Trash & Recycle Bin
OxiCloud provides a trash system that soft-deletes files and folders, allowing users to restore or permanently remove them.
## How It Works
1. When a file or folder is deleted, it's **soft-deleted** — a flag (`is_trashed`) is set and a `trashed_at` timestamp is recorded
2. Trashed items are hidden from normal file listings but remain on disk and in the database
3. Users can browse the trash, restore items, or permanently delete them
4. Items older than the retention period (default: **30 days**) are automatically purged
## API Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/trash` | List trashed items |
| POST | `/api/trash/restore/{id}` | Restore a trashed item |
| DELETE | `/api/trash/{id}` | Permanently delete |
| DELETE | `/api/trash/empty` | Empty the entire trash |
## Deduplication Interaction
Permanent deletion decrements the blob reference count. If no other file points to the same blob, the blob is removed from disk.
## Feature Flag
Trash can be disabled via `OXICLOUD_ENABLE_TRASH=false`. When disabled, deletions are permanent.
+80
View File
@@ -0,0 +1,80 @@
# WebDAV
OxiCloud exposes a fully RFC 4918 compliant WebDAV interface at `/webdav/`. It works with all major file managers and sync clients.
## Base URL
```
https://your-server:8086/webdav/
```
## Authentication
HTTP Basic Authentication:
```
Authorization: Basic base64(username:password)
```
::: tip
Always use HTTPS in production — Basic auth sends credentials in every request.
:::
## Supported Methods
| Method | Description |
|--------|-------------|
| `PROPFIND` | List directory contents / get file properties |
| `GET` | Download a file |
| `PUT` | Upload a file |
| `MKCOL` | Create a folder |
| `MOVE` | Move or rename a file/folder |
| `COPY` | Copy a file/folder |
| `DELETE` | Delete a file/folder |
| `LOCK` / `UNLOCK` | File locking |
## Client Setup
### Windows Explorer
1. Open **This PC** → **Map network drive**
2. Enter: `https://your-server:8086/webdav/`
3. Check **Connect using different credentials**
4. Enter your OxiCloud username and password
### macOS Finder
1. **Go** → **Connect to Server** (⌘K)
2. Enter: `https://your-server:8086/webdav/`
3. Enter credentials when prompted
### Linux (Nautilus / Files)
1. Open Files → **Other Locations**
2. In the address bar, type: `davs://your-server:8086/webdav/`
3. Enter credentials
### Linux (Dolphin / KDE)
1. In the address bar, type: `webdavs://your-server:8086/webdav/`
### Command Line (curl)
```bash
# List root directory
curl -u user:pass -X PROPFIND https://your-server:8086/webdav/ \
-H "Depth: 1"
# Download a file
curl -u user:pass https://your-server:8086/webdav/document.pdf -o document.pdf
# Upload a file
curl -u user:pass -T localfile.txt https://your-server:8086/webdav/remotefile.txt
# Create a folder
curl -u user:pass -X MKCOL https://your-server:8086/webdav/new-folder/
```
## Streaming PROPFIND
OxiCloud streams PROPFIND responses, so listing directories with thousands of files doesn't consume excessive memory.