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:
@@ -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 |
|
||||
@@ -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 |
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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`
|
||||
Reference in New Issue
Block a user