update 26.7.27

This commit is contained in:
kun
2026-07-27 10:24:21 +08:00
parent db3ab96e58
commit 25fa270597
4 changed files with 439 additions and 20 deletions
+39 -20
View File
@@ -4,13 +4,9 @@
<option name="autoReloadType" value="ALL" /> <option name="autoReloadType" value="ALL" />
</component> </component>
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="ae3fb6a0-aca4-4c0a-858b-91952e6dcdd3" name="更改" comment=""> <list default="true" id="ae3fb6a0-aca4-4c0a-858b-91952e6dcdd3" name="更改" comment="update 26.7.27">
<change beforePath="$PROJECT_DIR$/.idea/.gitignore" beforeDir="false" /> <change afterPath="$PROJECT_DIR$/480T/yuvomi/.env" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/iStore_Docker_Compose.iml" beforeDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/inspectionProfiles/profiles_settings.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/modules.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/vcs.xml" beforeDir="false" />
<change beforePath="$PROJECT_DIR$/480T/RAGFlow/docker-compose.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/480T/ragflow/docker-compose.yaml" afterDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -29,20 +25,27 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent">{ <component name="PropertiesComponent"><![CDATA[{
&quot;keyToString&quot;: { "keyToString": {
&quot;ASKED_SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;, "ASKED_SHARE_PROJECT_CONFIGURATION_FILES": "true",
&quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;, "ModuleVcsDetector.initialDetectionPerformed": "true",
&quot;RunOnceActivity.git.unshallow&quot;: &quot;true&quot;, "RunOnceActivity.ShowReadmeOnStart": "true",
&quot;RunOnceActivity.typescript.service.memoryLimit.init&quot;: &quot;true&quot;, "RunOnceActivity.git.unshallow": "true",
&quot;SHARE_PROJECT_CONFIGURATION_FILES&quot;: &quot;true&quot;, "RunOnceActivity.typescript.service.memoryLimit.init": "true",
&quot;codeWithMe.voiceChat.enabledByDefault&quot;: &quot;false&quot;, "SHARE_PROJECT_CONFIGURATION_FILES": "true",
&quot;git-widget-placeholder&quot;: &quot;main&quot;, "codeWithMe.voiceChat.enabledByDefault": "false",
&quot;node.js.detected.package.jshint&quot;: &quot;true&quot;, "git-widget-placeholder": "main",
&quot;node.js.selected.package.jshint&quot;: &quot;&quot;, "last_opened_file_path": "/Users/kun/PycharmProjects/Docker_Compose/480T/yuvomi",
&quot;nodejs_package_manager_path&quot;: &quot;npm&quot; "node.js.detected.package.jshint": "true",
"node.js.selected.package.jshint": "",
"nodejs_package_manager_path": "npm"
} }
}</component> }]]></component>
<component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/480T/yuvomi" />
</key>
</component>
<component name="SharedIndexes"> <component name="SharedIndexes">
<attachedChunks> <attachedChunks>
<set> <set>
@@ -61,10 +64,26 @@
<workItem from="1785115065245" duration="1091000" /> <workItem from="1785115065245" duration="1091000" />
<workItem from="1785116797216" duration="42000" /> <workItem from="1785116797216" duration="42000" />
<workItem from="1785116865103" duration="229000" /> <workItem from="1785116865103" duration="229000" />
<workItem from="1785117096824" duration="55000" />
<workItem from="1785117158260" duration="1000" />
<workItem from="1785118558426" duration="499000" />
</task> </task>
<task id="LOCAL-00001" summary="update 26.7.27">
<option name="closed" value="true" />
<created>1785117134273</created>
<option name="number" value="00001" />
<option name="presentableId" value="LOCAL-00001" />
<option name="project" value="LOCAL" />
<updated>1785117134273</updated>
</task>
<option name="localTasksCounter" value="2" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" /> <option name="version" value="3" />
</component> </component>
<component name="VcsManagerConfiguration">
<MESSAGE value="update 26.7.27" />
<option name="LAST_COMMIT_MESSAGE" value="update 26.7.27" />
</component>
</project> </project>
+184
View File
@@ -0,0 +1,184 @@
# Yuvomi - Environment Variables
# Copy this file to .env and adjust the values.
# Server
PORT=3600
NODE_ENV=production
# LOG_LEVEL=info # debug, info, warn, error (default: info)
# Container host port mapping (compose maps OIKOS_HTTP_PORT:3000).
# The app inside the container always listens on 3000; change only the host port here.
OIKOS_HTTP_PORT=3600
# Host bind address for the published port (podman-compose.yml only; default 0.0.0.0).
# Set to 127.0.0.1 for rootless Podman behind a reverse proxy on the same host.
# OIKOS_HTTP_BIND=0.0.0.0
# TZ=Europe/Berlin # Container timezone (default: UTC). Also the fallback zone for
# # events pushed to Google Calendar when the target calendar
# # reports no time zone of its own.
# Container storage paths (bind mounts)
DATA_DIR=/volume1/docker/docker_projects/yuvomi/data
# Host folder for the database and stored app data
BACKUP_DIR=/volume1/docker/docker_projects/yuvomi/backups
# Host folder for scheduled backups
# These two are HOST paths, used only by docker-compose.yml / podman-compose.yml to
# build the volume mapping. Inside the container the app always writes to /data and
# /backups (the compose files set DB_PATH and BACKUP_DIR accordingly). Do not pass
# this file to a bare `docker run --env-file`: BACKUP_DIR=./backups would then point
# the app at /app/backups, which is outside the mounted volume and not writable.
# On SELinux systems (RHEL/Fedora/CentOS Stream) use podman-compose.yml — it adds
# the :Z relabel automatically so the container can access these folders.
MODULES_DIR=/volume1/docker/docker_projects/yuvomi/modules
DOCUMENT_STORAGE_LOCAL_DIR=/volume1/docker/docker_projects/yuvomi/documents
# Session
SESSION_SECRET=6JHynEHERoq8F
# SESSION_SECURE=true # Set when running behind an HTTPS reverse proxy (Caddy, Nginx, Traefik)
# Database (SQLite/SQLCipher)
# Legacy installs may still have /data/oikos.db — the app auto-migrates it to yuvomi.db on boot.
DB_PATH=/volume1/docker/docker_projects/yuvomi/data/yuvomi.db
DB_ENCRYPTION_KEY=7wGeb6jm3KAoe
# NOTE: The optional integrations below (weather, Google/OIDC, WebDAV backup) may
# transmit data to third parties, some outside the EU/EEA. If you run Yuvomi under
# the GDPR, see docs/PRIVACY-FOR-SELFHOSTERS.md for per-service third-country
# assessments, data-processing-agreement notes and log-retention guidance.
# Weather widget — Open-Meteo (recommended, free, no API key). Set your coordinates:
WEATHER_LAT=
WEATHER_LON=
WEATHER_CITY=
WEATHER_UNITS=metric
# Weather widget — OpenWeatherMap (legacy, optional; only if you already use it):
OPENWEATHER_API_KEY=YOUR_API_KEY
OPENWEATHER_CITY=Berlin
OPENWEATHER_UNITS=metric
OPENWEATHER_LANG=de
# Google Calendar (optional)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=https://your-domain.com/api/v1/calendar/google/callback
# Google Drive document storage (optional)
# Enable the Google Drive API in the same Cloud project. Yuvomi requests only
# https://www.googleapis.com/auth/drive.file and accesses files it creates.
# Leave both Drive-specific credentials empty to reuse GOOGLE_CLIENT_ID and
# GOOGLE_CLIENT_SECRET. The Drive redirect URI is always separate and exact.
GOOGLE_DRIVE_CLIENT_ID=
GOOGLE_DRIVE_CLIENT_SECRET=
GOOGLE_DRIVE_REDIRECT_URI=https://your-domain.com/api/v1/documents/storage/google-drive/callback
# After deployment, connect Drive and explicitly select it under
# Settings -> Documents -> Storage. Connecting alone never activates uploads.
# OIDC / SSO (optional — alle vier Werte müssen gesetzt sein um OIDC zu aktivieren)
OIDC_ISSUER=https://authentik.example.com/application/o/yuvomi/
OIDC_CLIENT_ID=
OIDC_CLIENT_SECRET=
OIDC_REDIRECT_URI=https://your-domain.com/api/v1/auth/oidc/callback
# Opt-in: Bestehende Accounts per E-Mail verknüpfen, wenn der IdP keinen
# email_verified-Claim sendet. Nur setzen wenn der IdP vollständig unter eigener
# Kontrolle steht und keine unverifizierten E-Mails zulässt (z. B. ältere
# Authentik-Versionen ohne explizites email_verified-Mapping).
# OIDC_TRUST_EMAIL_WITHOUT_VERIFIED_CLAIM=true
# Apple Calendar CalDAV (optional)
APPLE_CALDAV_URL=https://caldav.icloud.com
APPLE_USERNAME=
APPLE_APP_SPECIFIC_PASSWORD=
# Sync interval in minutes for calendars and contacts (default: 15)
SYNC_INTERVAL_MINUTES=15
# ICS calendar subscriptions: allow http:// and private/local network feeds
# (e.g. Sonarr/Radarr/Home Assistant in the same LAN). Set true to lift the
# SSRF protection for ICS subscriptions — only in controlled environments.
# ICS_SUBSCRIPTION_ALLOW_PRIVATE_NETWORK=false
# Budget → Subscriptions (optional)
# Live currency conversion:
# FIXER_API_KEY=
# Automatic Backups
# BACKUP_ENABLED=true # Enable/disable automated backups (default: true)
# BACKUP_SCHEDULE=0 2 * * * # Cron schedule (default: 2 AM daily)
# BACKUP_KEEP=7 # Number of backups to keep (default: 7)
# TZ=Europe/Berlin # Timezone for scheduled backups (default: UTC, see above)
# WebDAV Backup Target (optional — uploads each backup to a WebDAV server)
# Supported: Nextcloud, ownCloud, Hetzner Storage Box, Infomaniak kDrive, etc.
# If set here, these values take precedence over the UI configuration in Settings → Backup.
# WEBDAV_BACKUP_ENABLED=true
# WEBDAV_BACKUP_URL=https://cloud.example.com/remote.php/dav/files/username/
# WEBDAV_BACKUP_USERNAME=username
# WEBDAV_BACKUP_PASSWORD=secret
# WEBDAV_BACKUP_PATH=/yuvomi/backups/
# WEBDAV_BACKUP_KEEP=10 # Remote backups to keep (default: 7)
# Local Folder Document Storage (optional — stores newly uploaded document files on a mounted host folder)
# When enabled, uploads are written to DOCUMENT_STORAGE_LOCAL_PATH/<key> instead of the database BLOB,
# and this backend takes precedence over WebDAV. Mount the folder into the container (see docker-compose.yml).
# Existing database/WebDAV documents remain readable; no automatic migration is performed.
# DOCUMENT_STORAGE_LOCAL_ENABLED=false
# DOCUMENT_STORAGE_LOCAL_PATH=/documents
# WebDAV Document Storage (optional — stores newly uploaded document files remotely)
# Non-empty values override the corresponding database settings. Existing WebDAV
# documents remain readable when new WebDAV uploads are disabled. Use this trusted
# deployment configuration for private/LAN WebDAV targets; UI-managed URLs must be public.
# DOCUMENT_STORAGE_WEBDAV_ENABLED=false
# DOCUMENT_STORAGE_WEBDAV_URL=https://cloud.example.com/remote.php/dav/files/username/
# DOCUMENT_STORAGE_WEBDAV_USERNAME=username
# DOCUMENT_STORAGE_WEBDAV_PASSWORD=secret
# DOCUMENT_STORAGE_WEBDAV_PATH=yuvomi-documents
# DOCUMENT_STORAGE_WEBDAV_ALLOW_PRIVATE_NETWORK=false # Set true to allow local/private network WebDAV targets (e.g. Nextcloud in same Docker network)
# Web Push (PWA notifications, optional)
# Delivers due reminders as system notifications even when the app is closed (requires HTTPS).
# VAPID keys are generated automatically on first use and stored in the database — leave these
# unset for a zero-config setup. Set them only to pin a fixed key pair across redeployments
# (generate with: npx web-push generate-vapid-keys).
# VAPID_PUBLIC_KEY=
# VAPID_PRIVATE_KEY=
# VAPID_SUBJECT=mailto:admin@example.com # Contact URI sent to push services (default: mailto:admin@localhost)
# Email / SMTP (optional)
# Configure an SMTP server to enable the "Forgot password" self-service flow.
# Can also be set in Settings → Administration → Email; non-empty values here override the DB.
# EMAIL_SMTP_HOST=smtp.example.com
# EMAIL_SMTP_PORT=587
# EMAIL_SMTP_SECURE=starttls # ssl | starttls | none
# EMAIL_SMTP_USER=
# EMAIL_SMTP_PASS=
# EMAIL_FROM_ADDRESS=yuvomi@example.com
# EMAIL_FROM_NAME=Yuvomi
# Absolute origin for password-reset links and calendar export-feed URLs. REQUIRED for
# reset emails: links are only sent when this is set (the request Host header is never
# trusted, to prevent reset poisoning). The export feed falls back to the request's
# protocol/host when unset.
# BASE_URL=https://yuvomi.example.com
# Security
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_ATTEMPTS=5
RATE_LIMIT_BLOCK_DURATION_MS=900000
# API documentation (/docs, /openapi.json) is admin-only and hidden entirely in
# production (NODE_ENV=production). Set to "true" to expose it to signed-in admins
# in production as well. Leave unset to keep it hidden.
# ENABLE_API_DOCS=true
# MCP endpoint (/mcp): the built-in Model Context Protocol bridge (call_api_operation)
# calls the REST API back over a loopback request. Override the base URL only for
# non-standard bind addresses; defaults to BASE_URL or http://127.0.0.1:<PORT>.
# MCP_INTERNAL_BASE_URL=http://127.0.0.1:3000
# Reverse proxy trust (controls which X-Forwarded-For / X-Real-IP values Express accepts)
# Default: 1 (trust one hop — correct for Caddy, nginx, Traefik in Docker)
# Set to a subnet when behind multiple proxy layers, e.g.:
# TRUST_PROXY=172.16.0.0/12,10.0.0.0/8
# Set to "loopback" for direct (no proxy) deployments.
# TRUST_PROXY=1
+37
View File
@@ -0,0 +1,37 @@
services:
yuvomi:
image: ghcr.io/ulsklyc/yuvomi:latest
build: . # optional: use --build to build locally instead
container_name: yuvomi
restart: unless-stopped
ports:
# Host-Port aus .env (OIKOS_HTTP_PORT); App im Container bleibt auf 3000.
- "0.0.0.0:${OIKOS_HTTP_PORT:-3000}:3000"
volumes:
- ${DATA_DIR:-./data}:/data
- ${BACKUP_DIR:-./backups}:/backups
# Drop Yuvomi modules into ./modules, or set MODULES_DIR=/path/to/modules.
- ${MODULES_DIR:-./modules}:/app/modules
# Optional local documents folder: mount a host directory to /documents inside the container
- ${DOCUMENT_STORAGE_LOCAL_DIR:-./documents}:/documents
env_file:
- .env
environment:
- NODE_ENV=production
- DB_PATH=${DB_PATH:-/data/yuvomi.db}
- BACKUP_DIR=/backups
# Local document storage (optional): set to true to store uploaded documents on the mounted /documents folder.
- DOCUMENT_STORAGE_LOCAL_ENABLED=${DOCUMENT_STORAGE_LOCAL_ENABLED:-false}
- DOCUMENT_STORAGE_LOCAL_PATH=${DOCUMENT_STORAGE_LOCAL_PATH:-/documents}
# Secure cookies come from .env (the installer sets them):
# - Reverse proxy + HTTPS → SESSION_SECURE=true, TRUST_PROXY=1
# - Direct HTTP access → SESSION_SECURE=false, TRUST_PROXY=loopback
# Default when unset (e.g. bare `docker compose up` without .env): false,
# so direct HTTP login keeps working out of the box.
- SESSION_SECURE=${SESSION_SECURE:-false}
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', r => process.exit(r.statusCode === 200 ? 0 : 1))"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
+179
View File
@@ -0,0 +1,179 @@
# Yuvomi - Environment Variables
# Copy this file to .env and adjust the values.
# Server
PORT=3000
NODE_ENV=production
# LOG_LEVEL=info # debug, info, warn, error (default: info)
# Container host port mapping (compose maps OIKOS_HTTP_PORT:3000).
# The app inside the container always listens on 3000; change only the host port here.
OIKOS_HTTP_PORT=3000
# Host bind address for the published port (podman-compose.yml only; default 0.0.0.0).
# Set to 127.0.0.1 for rootless Podman behind a reverse proxy on the same host.
# OIKOS_HTTP_BIND=0.0.0.0
# TZ=Europe/Berlin # Container timezone (default: UTC). Also the fallback zone for
# # events pushed to Google Calendar when the target calendar
# # reports no time zone of its own.
# Container storage paths (bind mounts)
# DATA_DIR=./data # Host folder for the database and stored app data
# BACKUP_DIR=./backups # Host folder for scheduled backups
# These two are HOST paths, used only by docker-compose.yml / podman-compose.yml to
# build the volume mapping. Inside the container the app always writes to /data and
# /backups (the compose files set DB_PATH and BACKUP_DIR accordingly). Do not pass
# this file to a bare `docker run --env-file`: BACKUP_DIR=./backups would then point
# the app at /app/backups, which is outside the mounted volume and not writable.
# On SELinux systems (RHEL/Fedora/CentOS Stream) use podman-compose.yml — it adds
# the :Z relabel automatically so the container can access these folders.
# Session
SESSION_SECRET=REPLACE_WITH_A_LONG_RANDOM_STRING
# SESSION_SECURE=true # Set when running behind an HTTPS reverse proxy (Caddy, Nginx, Traefik)
# Database (SQLite/SQLCipher)
# Legacy installs may still have /data/oikos.db — the app auto-migrates it to yuvomi.db on boot.
DB_PATH=/data/yuvomi.db
DB_ENCRYPTION_KEY=REPLACE_WITH_A_STRONG_ENCRYPTION_KEY
# NOTE: The optional integrations below (weather, Google/OIDC, WebDAV backup) may
# transmit data to third parties, some outside the EU/EEA. If you run Yuvomi under
# the GDPR, see docs/PRIVACY-FOR-SELFHOSTERS.md for per-service third-country
# assessments, data-processing-agreement notes and log-retention guidance.
# Weather widget — Open-Meteo (recommended, free, no API key). Set your coordinates:
WEATHER_LAT=
WEATHER_LON=
WEATHER_CITY=
WEATHER_UNITS=metric
# Weather widget — OpenWeatherMap (legacy, optional; only if you already use it):
OPENWEATHER_API_KEY=YOUR_API_KEY
OPENWEATHER_CITY=Berlin
OPENWEATHER_UNITS=metric
OPENWEATHER_LANG=de
# Google Calendar (optional)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=https://your-domain.com/api/v1/calendar/google/callback
# Google Drive document storage (optional)
# Enable the Google Drive API in the same Cloud project. Yuvomi requests only
# https://www.googleapis.com/auth/drive.file and accesses files it creates.
# Leave both Drive-specific credentials empty to reuse GOOGLE_CLIENT_ID and
# GOOGLE_CLIENT_SECRET. The Drive redirect URI is always separate and exact.
GOOGLE_DRIVE_CLIENT_ID=
GOOGLE_DRIVE_CLIENT_SECRET=
GOOGLE_DRIVE_REDIRECT_URI=https://your-domain.com/api/v1/documents/storage/google-drive/callback
# After deployment, connect Drive and explicitly select it under
# Settings -> Documents -> Storage. Connecting alone never activates uploads.
# OIDC / SSO (optional — alle vier Werte müssen gesetzt sein um OIDC zu aktivieren)
OIDC_ISSUER=https://authentik.example.com/application/o/yuvomi/
OIDC_CLIENT_ID=
OIDC_CLIENT_SECRET=
OIDC_REDIRECT_URI=https://your-domain.com/api/v1/auth/oidc/callback
# Opt-in: Bestehende Accounts per E-Mail verknüpfen, wenn der IdP keinen
# email_verified-Claim sendet. Nur setzen wenn der IdP vollständig unter eigener
# Kontrolle steht und keine unverifizierten E-Mails zulässt (z. B. ältere
# Authentik-Versionen ohne explizites email_verified-Mapping).
# OIDC_TRUST_EMAIL_WITHOUT_VERIFIED_CLAIM=true
# Apple Calendar CalDAV (optional)
APPLE_CALDAV_URL=https://caldav.icloud.com
APPLE_USERNAME=
APPLE_APP_SPECIFIC_PASSWORD=
# Sync interval in minutes for calendars and contacts (default: 15)
SYNC_INTERVAL_MINUTES=15
# ICS calendar subscriptions: allow http:// and private/local network feeds
# (e.g. Sonarr/Radarr/Home Assistant in the same LAN). Set true to lift the
# SSRF protection for ICS subscriptions — only in controlled environments.
# ICS_SUBSCRIPTION_ALLOW_PRIVATE_NETWORK=false
# Budget → Subscriptions (optional)
# Live currency conversion:
# FIXER_API_KEY=
# Automatic Backups
# BACKUP_ENABLED=true # Enable/disable automated backups (default: true)
# BACKUP_SCHEDULE=0 2 * * * # Cron schedule (default: 2 AM daily)
# BACKUP_KEEP=7 # Number of backups to keep (default: 7)
# TZ=Europe/Berlin # Timezone for scheduled backups (default: UTC, see above)
# WebDAV Backup Target (optional — uploads each backup to a WebDAV server)
# Supported: Nextcloud, ownCloud, Hetzner Storage Box, Infomaniak kDrive, etc.
# If set here, these values take precedence over the UI configuration in Settings → Backup.
# WEBDAV_BACKUP_ENABLED=true
# WEBDAV_BACKUP_URL=https://cloud.example.com/remote.php/dav/files/username/
# WEBDAV_BACKUP_USERNAME=username
# WEBDAV_BACKUP_PASSWORD=secret
# WEBDAV_BACKUP_PATH=/yuvomi/backups/
# WEBDAV_BACKUP_KEEP=10 # Remote backups to keep (default: 7)
# Local Folder Document Storage (optional — stores newly uploaded document files on a mounted host folder)
# When enabled, uploads are written to DOCUMENT_STORAGE_LOCAL_PATH/<key> instead of the database BLOB,
# and this backend takes precedence over WebDAV. Mount the folder into the container (see docker-compose.yml).
# Existing database/WebDAV documents remain readable; no automatic migration is performed.
# DOCUMENT_STORAGE_LOCAL_ENABLED=false
# DOCUMENT_STORAGE_LOCAL_PATH=/documents
# WebDAV Document Storage (optional — stores newly uploaded document files remotely)
# Non-empty values override the corresponding database settings. Existing WebDAV
# documents remain readable when new WebDAV uploads are disabled. Use this trusted
# deployment configuration for private/LAN WebDAV targets; UI-managed URLs must be public.
# DOCUMENT_STORAGE_WEBDAV_ENABLED=false
# DOCUMENT_STORAGE_WEBDAV_URL=https://cloud.example.com/remote.php/dav/files/username/
# DOCUMENT_STORAGE_WEBDAV_USERNAME=username
# DOCUMENT_STORAGE_WEBDAV_PASSWORD=secret
# DOCUMENT_STORAGE_WEBDAV_PATH=yuvomi-documents
# DOCUMENT_STORAGE_WEBDAV_ALLOW_PRIVATE_NETWORK=false # Set true to allow local/private network WebDAV targets (e.g. Nextcloud in same Docker network)
# Web Push (PWA notifications, optional)
# Delivers due reminders as system notifications even when the app is closed (requires HTTPS).
# VAPID keys are generated automatically on first use and stored in the database — leave these
# unset for a zero-config setup. Set them only to pin a fixed key pair across redeployments
# (generate with: npx web-push generate-vapid-keys).
# VAPID_PUBLIC_KEY=
# VAPID_PRIVATE_KEY=
# VAPID_SUBJECT=mailto:admin@example.com # Contact URI sent to push services (default: mailto:admin@localhost)
# Email / SMTP (optional)
# Configure an SMTP server to enable the "Forgot password" self-service flow.
# Can also be set in Settings → Administration → Email; non-empty values here override the DB.
# EMAIL_SMTP_HOST=smtp.example.com
# EMAIL_SMTP_PORT=587
# EMAIL_SMTP_SECURE=starttls # ssl | starttls | none
# EMAIL_SMTP_USER=
# EMAIL_SMTP_PASS=
# EMAIL_FROM_ADDRESS=yuvomi@example.com
# EMAIL_FROM_NAME=Yuvomi
# Absolute origin for password-reset links and calendar export-feed URLs. REQUIRED for
# reset emails: links are only sent when this is set (the request Host header is never
# trusted, to prevent reset poisoning). The export feed falls back to the request's
# protocol/host when unset.
# BASE_URL=https://yuvomi.example.com
# Security
RATE_LIMIT_WINDOW_MS=60000
RATE_LIMIT_MAX_ATTEMPTS=5
RATE_LIMIT_BLOCK_DURATION_MS=900000
# API documentation (/docs, /openapi.json) is admin-only and hidden entirely in
# production (NODE_ENV=production). Set to "true" to expose it to signed-in admins
# in production as well. Leave unset to keep it hidden.
# ENABLE_API_DOCS=true
# MCP endpoint (/mcp): the built-in Model Context Protocol bridge (call_api_operation)
# calls the REST API back over a loopback request. Override the base URL only for
# non-standard bind addresses; defaults to BASE_URL or http://127.0.0.1:<PORT>.
# MCP_INTERNAL_BASE_URL=http://127.0.0.1:3000
# Reverse proxy trust (controls which X-Forwarded-For / X-Real-IP values Express accepts)
# Default: 1 (trust one hop — correct for Caddy, nginx, Traefik in Docker)
# Set to a subnet when behind multiple proxy layers, e.g.:
# TRUST_PROXY=172.16.0.0/12,10.0.0.0/8
# Set to "loopback" for direct (no proxy) deployments.
# TRUST_PROXY=1