diff --git a/README.md b/README.md index 653d51e8..1049ca53 100644 --- a/README.md +++ b/README.md @@ -46,11 +46,15 @@ cargo run --bin migrate --features migrations cargo run --release ``` -Open `http://localhost:8085` in your browser. +Open `http://localhost:8086` in your browser. ### Docker (alternative) ```bash +# Copy example environment file and customize +cp example.env .env +# Edit .env with your settings (optional - defaults work for quick testing) + docker compose up -d ``` diff --git a/doc/deployment.md b/doc/deployment.md index 1e687b32..df81d868 100644 --- a/doc/deployment.md +++ b/doc/deployment.md @@ -6,11 +6,26 @@ OxiCloud is deployed as a containerized application with PostgreSQL. ## Docker Setup +### Quick Start + +1. **Copy the example environment file and customize it:** + ```bash + cp example.env .env + # Edit .env with your settings + ``` + +2. **Start the services:** + ```bash + docker compose up -d + ``` + +3. **Access OxiCloud:** + Open `http://localhost:8086` in your browser. + ### Docker Compose ```yaml # docker-compose.yml -version: '3' services: postgres: image: postgres:17.4-alpine @@ -31,8 +46,8 @@ services: image: oxicloud:latest ports: - "8086:8086" - environment: - OXICLOUD_DB_CONNECTION_STRING: "postgres://postgres:postgres@postgres/oxicloud" + env_file: + - .env volumes: - storage_data:/app/storage depends_on: @@ -63,8 +78,9 @@ Non-root user: `oxicloud` (UID/GID 1001). Exposed port: `8086`. Entrypoint: `ent |---|---|---| | `OXICLOUD_STORAGE_PATH` | `./storage` | Root storage directory | | `OXICLOUD_STATIC_PATH` | `./static` | Static files directory | -| `OXICLOUD_SERVER_PORT` | `8085` | Server port (note: `main.rs` hardcodes `8086`) | +| `OXICLOUD_SERVER_PORT` | `8086` | Server port | | `OXICLOUD_SERVER_HOST` | `127.0.0.1` | Server bind address | +| `OXICLOUD_BASE_URL` | (auto-detected) | Public base URL for share links. If not set, uses `http://{host}:{port}` | ### Database @@ -112,6 +128,16 @@ Non-root user: `oxicloud` (UID/GID 1001). Exposed port: `8086`. Entrypoint: `ent If **OXICLOUD_OIDC_ENABLED** is `true` but **issuer_url**, **client_id**, or **client_secret** are empty, OIDC is automatically disabled with an error log. +### WOPI (Office Document Editing) + +| Variable | Default | Description | +|---|---|---| +| `OXICLOUD_WOPI_ENABLED` | `false` | Enable WOPI integration for office document editing | +| `OXICLOUD_WOPI_DISCOVERY_URL` | (empty) | WOPI client discovery URL (e.g., Collabora, OnlyOffice) | +| `OXICLOUD_WOPI_SECRET` | (falls back to JWT secret) | Secret key for signing WOPI access tokens | +| `OXICLOUD_WOPI_TOKEN_TTL_SECS` | `86400` (24h) | WOPI access token lifetime | +| `OXICLOUD_WOPI_LOCK_TTL_SECS` | `1800` (30m) | WOPI lock expiration time | + --- ## Internal Configuration (Not Environment-Configurable) diff --git a/doc/wopi-integration.md b/doc/wopi-integration.md index 0fe0f108..51241c34 100644 --- a/doc/wopi-integration.md +++ b/doc/wopi-integration.md @@ -1055,7 +1055,6 @@ services: dockerfile: Dockerfile ports: - "8086:8086" - - "8085:8085" networks: - oxicloud depends_on: diff --git a/docker-compose.yml b/docker-compose.yml index 56452836..a0074d28 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,15 +27,13 @@ services: dockerfile: Dockerfile ports: - "8086:8086" - - "8085:8085" networks: - oxicloud depends_on: postgres: condition: service_healthy - environment: - - "OXICLOUD_DB_CONNECTION_STRING=postgres://postgres:postgres@postgres/oxicloud" - - "DATABASE_URL=postgres://postgres:postgres@postgres/oxicloud" + env_file: + - .env volumes: - storage_data:/app/storage - ./static:/app/static diff --git a/example.env b/example.env new file mode 100644 index 00000000..d16a846b --- /dev/null +++ b/example.env @@ -0,0 +1,149 @@ +# ============================================================================= +# OxiCloud Environment Configuration +# ============================================================================= +# Copy this file to .env and modify as needed for your deployment. +# cp example.env .env +# +# All variables have sensible defaults. Only override what you need. +# ============================================================================= + +# ----------------------------------------------------------------------------- +# SERVER CONFIGURATION +# ----------------------------------------------------------------------------- + +# Root directory for file storage (default: ./storage) +OXICLOUD_STORAGE_PATH=./storage + +# Path to static files directory (default: ./static) +OXICLOUD_STATIC_PATH=./static + +# Server port (default: 8086) +OXICLOUD_SERVER_PORT=8086 + +# Server bind address (default: 127.0.0.1) +# Use 0.0.0.0 to bind to all interfaces in Docker +OXICLOUD_SERVER_HOST=127.0.0.1 + +# Public base URL for generating share links and external URLs +# If not set, defaults to http://{OXICLOUD_SERVER_HOST}:{OXICLOUD_SERVER_PORT} +# Example: https://cloud.example.com +#OXICLOUD_BASE_URL=https://cloud.example.com + +# ----------------------------------------------------------------------------- +# DATABASE CONFIGURATION +# ----------------------------------------------------------------------------- + +# PostgreSQL connection string +# Format: postgres://USER:PASSWORD@HOST:PORT/DATABASE +# For Docker: use 'postgres' as the hostname (the docker-compose service name) +# For local development: use 'localhost:5432' +OXICLOUD_DB_CONNECTION_STRING=postgres://postgres:postgres@postgres/oxicloud + +# Maximum number of database connections in the pool (default: 20) +#OXICLOUD_DB_MAX_CONNECTIONS=20 + +# Minimum number of database connections to maintain (default: 5) +#OXICLOUD_DB_MIN_CONNECTIONS=5 + +# Build-time database URL for SQLx compile-time checks +# Only needed during compilation, not at runtime +DATABASE_URL=postgres://postgres:postgres@localhost:5432/oxicloud + +# ----------------------------------------------------------------------------- +# AUTHENTICATION CONFIGURATION +# ----------------------------------------------------------------------------- + +# JWT secret key for signing authentication tokens +# IMPORTANT: Change this in production! If empty, a random secret is generated +# per session (tokens become invalid on restart). +# Generate a secure secret with: openssl rand -hex 32 +OXICLOUD_JWT_SECRET= + +# Access token lifetime in seconds (default: 3600 = 1 hour) +#OXICLOUD_ACCESS_TOKEN_EXPIRY_SECS=3600 + +# Refresh token lifetime in seconds (default: 2592000 = 30 days) +#OXICLOUD_REFRESH_TOKEN_EXPIRY_SECS=2592000 + +# ----------------------------------------------------------------------------- +# FEATURE FLAGS +# ----------------------------------------------------------------------------- + +# Enable/disable authentication system (default: true) +#OXICLOUD_ENABLE_AUTH=true + +# Enable per-user storage quotas (default: false) +#OXICLOUD_ENABLE_USER_STORAGE_QUOTAS=false + +# Enable file/folder sharing (default: true) +#OXICLOUD_ENABLE_FILE_SHARING=true + +# Enable trash/recycle bin functionality (default: true) +#OXICLOUD_ENABLE_TRASH=true + +# Enable search functionality (default: true) +#OXICLOUD_ENABLE_SEARCH=true + +# ----------------------------------------------------------------------------- +# OPENID CONNECT (OIDC) / SSO CONFIGURATION +# ----------------------------------------------------------------------------- + +# Enable OIDC authentication (default: false) +OXICLOUD_OIDC_ENABLED=false + +# OIDC provider issuer URL (required if OIDC enabled) +# Example: https://auth.example.com/application/o/oxicloud/ +#OXICLOUD_OIDC_ISSUER_URL= + +# OIDC client ID (required if OIDC enabled) +#OXICLOUD_OIDC_CLIENT_ID= + +# OIDC client secret (required if OIDC enabled) +#OXICLOUD_OIDC_CLIENT_SECRET= + +# Callback URL after OIDC authentication (must match IdP config) +# Default: http://localhost:8086/api/auth/oidc/callback +#OXICLOUD_OIDC_REDIRECT_URI=http://localhost:8086/api/auth/oidc/callback + +# OIDC scopes to request (default: openid profile email) +#OXICLOUD_OIDC_SCOPES=openid profile email + +# Frontend URL to redirect after successful OIDC login +# Default: http://localhost:8086 +#OXICLOUD_OIDC_FRONTEND_URL=http://localhost:8086 + +# Auto-create users on first OIDC login (JIT provisioning) (default: true) +#OXICLOUD_OIDC_AUTO_PROVISION=true + +# Comma-separated list of OIDC groups that grant admin role +# Example: admins,cloud-admins +#OXICLOUD_OIDC_ADMIN_GROUPS= + +# Disable password-based login entirely when OIDC is active (default: false) +#OXICLOUD_OIDC_DISABLE_PASSWORD_LOGIN=false + +# Display name for the OIDC provider shown in UI (default: SSO) +#OXICLOUD_OIDC_PROVIDER_NAME=SSO + +# ----------------------------------------------------------------------------- +# WOPI (WEB APPLICATION OPEN PLATFORM INTERFACE) CONFIGURATION +# ----------------------------------------------------------------------------- + +# Enable WOPI integration for office document editing (default: false) +# Used with Collabora, OnlyOffice, or other WOPI-compatible editors +OXICLOUD_WOPI_ENABLED=false + +# URL to the WOPI client's discovery endpoint +# Example for Collabora: http://collabora:9980/hosting/discovery +# Example for OnlyOffice: http://onlyoffice/hosting/discovery +#OXICLOUD_WOPI_DISCOVERY_URL= + +# Secret key for signing WOPI access tokens +# Falls back to OXICLOUD_JWT_SECRET if not set +#OXICLOUD_WOPI_SECRET= + +# WOPI access token lifetime in seconds (default: 86400 = 24 hours) +#OXICLOUD_WOPI_TOKEN_TTL_SECS=86400 + +# WOPI lock expiration in seconds (default: 1800 = 30 minutes) +#OXICLOUD_WOPI_LOCK_TTL_SECS=1800 \ No newline at end of file diff --git a/src/application/services/share_service.rs b/src/application/services/share_service.rs index 99b7697c..d233ee0e 100644 --- a/src/application/services/share_service.rs +++ b/src/application/services/share_service.rs @@ -790,6 +790,6 @@ mod tests { assert_eq!(share_dto.item_id, "test_file_id"); assert_eq!(share_dto.item_type, "file"); assert!(share_dto.has_password); - assert!(share_dto.url.starts_with("http://127.0.0.1:8085/s/")); + assert!(share_dto.url.starts_with("http://127.0.0.1:8086/s/")); } } diff --git a/src/common/config.rs b/src/common/config.rs index b6e076cd..fb065bda 100644 --- a/src/common/config.rs +++ b/src/common/config.rs @@ -439,7 +439,7 @@ impl Default for AppConfig { Self { storage_path: PathBuf::from("./storage"), static_path: PathBuf::from("./static"), - server_port: 8085, + server_port: 8086, server_host: "127.0.0.1".to_string(), cache: CacheConfig::default(), timeouts: TimeoutConfig::default(),