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
+96
View File
@@ -0,0 +1,96 @@
# Deployment & Docker
## Docker Image
OxiCloud uses a multi-stage Alpine build producing a **~40 MB** image:
1. **Base** — shared build dependencies (`musl-dev`, `pkgconfig`, `openssl-dev`, `libpq-dev`)
2. **Cacher** — pre-builds the dependency layer for fast rebuilds
3. **Builder** — compiles OxiCloud (`rust:1.94.0-alpine3.23`)
4. **Runtime** — minimal Alpine (`alpine:3.23.3`) with `libgcc`, `ca-certificates`, `libpq`, `tzdata`, `su-exec`
The final image runs as non-root user `oxicloud` (UID/GID 1001). Exposed port: **8086**.
## Docker Compose
```yaml
services:
postgres:
image: postgres:17.4-alpine
environment:
POSTGRES_DB: oxicloud
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres # change in production!
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: ghcr.io/diocrafts/oxicloud:latest
ports:
- "8086:8086"
env_file:
- .env
volumes:
- storage_data:/app/storage
depends_on:
postgres:
condition: service_healthy
volumes:
pg_data:
storage_data:
```
## Kubernetes (Helm)
### Prerequisites
- Kubernetes cluster
- Default StorageClass
- Ingress Controller
- Helm 3+
### Install
```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
```
### WOPI Verification
If Collabora/OnlyOffice is enabled:
```bash
kubectl logs statefulset/oxicloud -n oxicloud | grep "WOPI discovery loaded"
```
## Feature Dependency Matrix
| Feature | Requires DB | Requires Auth | Feature Flag |
|---|---|---|---|
| File storage | Yes | No | Always on |
| Authentication | Yes | — | `OXICLOUD_ENABLE_AUTH` |
| OIDC / SSO | Yes | Yes | `OXICLOUD_OIDC_ENABLED` |
| File sharing | Yes | Yes | `OXICLOUD_ENABLE_FILE_SHARING` |
| Trash | Yes | No | `OXICLOUD_ENABLE_TRASH` |
| Search | Yes | No | `OXICLOUD_ENABLE_SEARCH` |
| Favorites | Yes | Yes | Always on |
| Storage quotas | Yes | Yes | `OXICLOUD_ENABLE_USER_STORAGE_QUOTAS` |
| WebDAV | Yes | Optional | Always on |
| CalDAV / CardDAV | Yes | Yes | Always on |
| Deduplication | No | No | Always on |
| Thumbnails | No | No | Always on |
| Chunked uploads | No | No | Always on |
+83
View File
@@ -0,0 +1,83 @@
# Environment Variables
All variables use the `OXICLOUD_` prefix.
## Server
| Variable | Default | Description |
|---|---|---|
| `OXICLOUD_STORAGE_PATH` | `./storage` | Root storage directory |
| `OXICLOUD_STATIC_PATH` | `./static` | Static files directory |
| `OXICLOUD_SERVER_PORT` | `8086` | Server port |
| `OXICLOUD_SERVER_HOST` | `127.0.0.1` | Server bind address |
| `OXICLOUD_BASE_URL` | (auto) | Public base URL for share links |
## Database
| Variable | Default | Description |
|---|---|---|
| `OXICLOUD_DB_CONNECTION_STRING` | `postgres://postgres:postgres@localhost:5432/oxicloud` | PostgreSQL connection string |
| `OXICLOUD_DB_MAX_CONNECTIONS` | `20` | Max pool connections |
| `OXICLOUD_DB_MIN_CONNECTIONS` | `5` | Min pool connections |
## Authentication
| Variable | Default | Description |
|---|---|---|
| `OXICLOUD_JWT_SECRET` | (random) | JWT signing secret |
| `OXICLOUD_ACCESS_TOKEN_EXPIRY_SECS` | `3600` | Access token lifetime (seconds) |
| `OXICLOUD_REFRESH_TOKEN_EXPIRY_SECS` | `2592000` | Refresh token lifetime (seconds) |
## Feature Flags
| Variable | Default | Description |
|---|---|---|
| `OXICLOUD_ENABLE_AUTH` | `true` | Enable authentication |
| `OXICLOUD_ENABLE_USER_STORAGE_QUOTAS` | `false` | Per-user storage quotas |
| `OXICLOUD_ENABLE_FILE_SHARING` | `true` | File/folder sharing |
| `OXICLOUD_ENABLE_TRASH` | `true` | Trash / recycle bin |
| `OXICLOUD_ENABLE_SEARCH` | `true` | Search |
## OIDC / SSO
See the [OIDC configuration guide](/config/oidc) for details.
| Variable | Default | Description |
|---|---|---|
| `OXICLOUD_OIDC_ENABLED` | `false` | Enable OIDC |
| `OXICLOUD_OIDC_ISSUER_URL` | — | OIDC issuer URL |
| `OXICLOUD_OIDC_CLIENT_ID` | — | Client ID |
| `OXICLOUD_OIDC_CLIENT_SECRET` | — | Client secret |
| `OXICLOUD_OIDC_REDIRECT_URI` | `http://localhost:8086/api/auth/oidc/callback` | Callback URL |
| `OXICLOUD_OIDC_SCOPES` | `openid profile email` | Requested scopes |
| `OXICLOUD_OIDC_FRONTEND_URL` | `http://localhost:8086` | Frontend URL |
| `OXICLOUD_OIDC_AUTO_PROVISION` | `true` | Auto-create users on first SSO login |
| `OXICLOUD_OIDC_ADMIN_GROUPS` | — | Groups that grant admin role |
| `OXICLOUD_OIDC_DISABLE_PASSWORD_LOGIN` | `false` | Hide password form when OIDC enabled |
| `OXICLOUD_OIDC_PROVIDER_NAME` | `SSO` | Display name for the provider |
## WOPI (Office Editing)
See the [WOPI configuration guide](/config/wopi) for details.
| Variable | Default | Description |
|---|---|---|
| `OXICLOUD_WOPI_ENABLED` | `false` | Enable WOPI |
| `OXICLOUD_WOPI_DISCOVERY_URL` | — | Collabora/OnlyOffice discovery URL |
| `OXICLOUD_WOPI_SECRET` | (JWT secret) | WOPI token signing key |
| `OXICLOUD_WOPI_TOKEN_TTL_SECS` | `86400` | Token lifetime |
| `OXICLOUD_WOPI_LOCK_TTL_SECS` | `1800` | Lock expiration |
## Internal Defaults (not configurable via env)
| Parameter | Default |
|---|---|
| File cache TTL | 60 s |
| Directory cache TTL | 120 s |
| Max cache entries | 10 000 |
| Large file threshold | 100 MB |
| Streaming chunk size | 1 MB |
| Max parallel chunks | 8 |
| Trash retention | 30 days |
| Argon2id memory cost | 64 MB |
| Argon2id time cost | 3 iterations |
+21
View File
@@ -0,0 +1,21 @@
# Configuration
OxiCloud is configured entirely via **environment variables** (no config files needed).
## Sections
- [Deployment & Docker](/config/deployment) — Docker Compose, Kubernetes Helm chart, image details
- [Environment Variables](/config/env) — complete reference of all `OXICLOUD_*` variables
- [OIDC / SSO](/config/oidc) — single sign-on with Keycloak, Authentik, Authelia, Google, Azure AD
- [WOPI (Office Editing)](/config/wopi) — Collabora Online / OnlyOffice integration
## Minimal `.env`
```bash
OXICLOUD_DB_CONNECTION_STRING=postgres://postgres:postgres@postgres:5432/oxicloud
OXICLOUD_STORAGE_PATH=/app/storage
OXICLOUD_SERVER_HOST=0.0.0.0
OXICLOUD_SERVER_PORT=8086
```
That's enough to get started. All other settings have sensible defaults.
+95
View File
@@ -0,0 +1,95 @@
# OIDC / SSO
OxiCloud supports OpenID Connect for single sign-on with providers like **Keycloak**, **Authentik**, **Authelia**, **Google**, and **Azure AD**.
## How It Works
1. User clicks "Sign in with SSO" on the login page
2. Browser redirects to the identity provider (IdP)
3. User authenticates with their existing credentials
4. IdP redirects back to OxiCloud with an auth code
5. OxiCloud exchanges the code for user info and issues its own JWT tokens
## Configuration
```bash
OXICLOUD_OIDC_ENABLED=true
OXICLOUD_OIDC_ISSUER_URL="https://authentik.example.com/application/o/oxicloud/"
OXICLOUD_OIDC_CLIENT_ID="your-client-id"
OXICLOUD_OIDC_CLIENT_SECRET="your-client-secret"
OXICLOUD_OIDC_REDIRECT_URI="https://oxicloud.example.com/api/auth/oidc/callback"
OXICLOUD_OIDC_SCOPES="openid profile email"
OXICLOUD_OIDC_FRONTEND_URL="https://oxicloud.example.com"
OXICLOUD_OIDC_AUTO_PROVISION=true
OXICLOUD_OIDC_ADMIN_GROUPS="oxicloud-admins"
OXICLOUD_OIDC_PROVIDER_NAME="Authentik"
```
### Variable Reference
| Variable | Default | Description |
|---|---|---|
| `OXICLOUD_OIDC_ENABLED` | `false` | Master switch |
| `OXICLOUD_OIDC_ISSUER_URL` | — | Provider's OIDC issuer URL |
| `OXICLOUD_OIDC_CLIENT_ID` | — | OAuth client ID |
| `OXICLOUD_OIDC_CLIENT_SECRET` | — | OAuth client secret |
| `OXICLOUD_OIDC_REDIRECT_URI` | `http://localhost:8086/api/auth/oidc/callback` | Callback URL registered with the IdP |
| `OXICLOUD_OIDC_SCOPES` | `openid profile email` | Requested scopes |
| `OXICLOUD_OIDC_FRONTEND_URL` | `http://localhost:8086` | Where to redirect the browser after auth |
| `OXICLOUD_OIDC_AUTO_PROVISION` | `true` | Auto-create users on first login |
| `OXICLOUD_OIDC_ADMIN_GROUPS` | — | OIDC groups that grant admin role |
| `OXICLOUD_OIDC_DISABLE_PASSWORD_LOGIN` | `false` | Hide password login when OIDC is active |
| `OXICLOUD_OIDC_PROVIDER_NAME` | `SSO` | Label shown on the login button |
::: warning
If `OXICLOUD_OIDC_ENABLED=true` but `issuer_url`, `client_id`, or `client_secret` are empty, OIDC is automatically disabled with an error log.
:::
## API Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/auth/oidc/providers` | Returns OIDC provider info |
| GET | `/api/auth/oidc/authorize` | Authorization URL for redirect to IdP |
| GET | `/api/auth/oidc/callback` | Callback from IdP with auth code |
| POST | `/api/auth/oidc/exchange` | Exchange auth code for JWT tokens |
## Provider Examples
### Keycloak
```yaml
# docker-compose.yml
services:
oxicloud:
environment:
OXICLOUD_OIDC_ENABLED: "true"
OXICLOUD_OIDC_ISSUER_URL: "https://keycloak.example.com/realms/your-realm"
OXICLOUD_OIDC_CLIENT_ID: "oxicloud"
OXICLOUD_OIDC_CLIENT_SECRET: "your-client-secret"
OXICLOUD_OIDC_REDIRECT_URI: "https://oxicloud.example.com/api/auth/oidc/callback"
OXICLOUD_OIDC_FRONTEND_URL: "https://oxicloud.example.com"
OXICLOUD_OIDC_PROVIDER_NAME: "Keycloak"
```
### Authentik
```bash
OXICLOUD_OIDC_ISSUER_URL="https://authentik.example.com/application/o/oxicloud/"
OXICLOUD_OIDC_PROVIDER_NAME="Authentik"
```
### Google
```bash
OXICLOUD_OIDC_ISSUER_URL="https://accounts.google.com"
OXICLOUD_OIDC_PROVIDER_NAME="Google"
```
## Notes
- Always use **HTTPS** for OIDC connections
- One OIDC provider per instance (single-provider model)
- OIDC users share the same permissions model as local users
- After OIDC auth, the backend issues its own JWT tokens (no IdP token dependency)
- Use the admin settings UI (`/admin.html`) to configure and test OIDC at runtime
+78
View File
@@ -0,0 +1,78 @@
# WOPI (Office Document Editing)
OxiCloud integrates with **Collabora Online** and **OnlyOffice** via the WOPI protocol, letting users edit documents, spreadsheets, and presentations directly in the browser.
## How It Works
1. User opens a document (`.docx`, `.xlsx`, `.pptx`, `.odt`, etc.)
2. OxiCloud generates a WOPI access token and redirects to the editor
3. The editor fetches the file from OxiCloud via WOPI endpoints
4. Edits are saved back via `PutFile`
## Configuration
```bash
OXICLOUD_WOPI_ENABLED=true
OXICLOUD_WOPI_DISCOVERY_URL="http://collabora:9980/hosting/discovery"
```
| Variable | Default | Description |
|---|---|---|
| `OXICLOUD_WOPI_ENABLED` | `false` | Enable WOPI integration |
| `OXICLOUD_WOPI_DISCOVERY_URL` | — | Editor's WOPI discovery URL |
| `OXICLOUD_WOPI_SECRET` | (JWT secret) | Token signing key |
| `OXICLOUD_WOPI_TOKEN_TTL_SECS` | `86400` | Access token lifetime |
| `OXICLOUD_WOPI_LOCK_TTL_SECS` | `1800` | Lock expiration |
## Docker Compose with Collabora
```yaml
services:
collabora:
image: collabora/code:latest
environment:
- domain=oxicloud\\.example\\.com
- extra_params=--o:ssl.enable=false
ports:
- "9980:9980"
cap_add:
- MKNOD
oxicloud:
environment:
OXICLOUD_WOPI_ENABLED: "true"
OXICLOUD_WOPI_DISCOVERY_URL: "http://collabora:9980/hosting/discovery"
```
## Docker Compose with OnlyOffice
```yaml
services:
onlyoffice:
image: onlyoffice/documentserver:latest
environment:
- JWT_ENABLED=false
ports:
- "8443:443"
oxicloud:
environment:
OXICLOUD_WOPI_ENABLED: "true"
OXICLOUD_WOPI_DISCOVERY_URL: "http://onlyoffice/hosting/discovery"
```
## WOPI Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/wopi/files/{id}` | CheckFileInfo — file metadata |
| GET | `/wopi/files/{id}/contents` | GetFile — download file content |
| POST | `/wopi/files/{id}/contents` | PutFile — save edited content |
| POST | `/wopi/files/{id}` | Lock / Unlock / RefreshLock |
## Supported Formats
Any format supported by your Collabora or OnlyOffice installation, typically:
- Documents: `.docx`, `.odt`, `.doc`, `.rtf`
- Spreadsheets: `.xlsx`, `.ods`, `.xls`, `.csv`
- Presentations: `.pptx`, `.odp`, `.ppt`