-
-
Notifications
You must be signed in to change notification settings - Fork 145
Expand file tree
/
Copy path.env.example
More file actions
297 lines (266 loc) · 16.8 KB
/
Copy path.env.example
File metadata and controls
297 lines (266 loc) · 16.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
# 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)
# Address the app listens on (default: all interfaces). Leave unset in a container:
# the published port reaches the app only when it listens on all interfaces. Set to
# 127.0.0.1 when Node runs directly on the host behind a reverse proxy on that host.
# IP addresses only: a host name (localhost included) is refused, and so is an IPv6
# address with a zone ID (fe80::1%eth0).
# Not the same as OIKOS_HTTP_BIND below, which is where the container engine
# publishes the port.
# BIND_ADDRESS=127.0.0.1
# 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). Affects log timestamps
# # and the automated-backup schedule, and is the DEFAULT for
# # the household zone. Since v2.34.0 the household zone is a
# # setting of its own (Settings > Personal > Appearance >
# # Region), and that setting wins where both are present -
# # TZ lives in the compose file, which you cannot reach on
# # Umbrel, TrueNAS or Unraid. Whichever applies is the zone
# # used wherever a time has no zone of its own: the calendar
# # day server jobs call "today", events pushed to Google or
# # Outlook, the due times of CalDAV reminders synced into
# # Tasks, and the times in the exported calendar feed -
# # subscribers read those in this zone, so a wrong zone
# # shifts every appointment.
# 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
# MODULES_DIR=./modules # Host folder for third-party drop-in modules (see MODULES.md)
# These are HOST paths, used by docker-compose.yml / podman-compose.yml to build the
# volume mapping. Inside the container the app always uses /data, /backups and
# /app/modules (the compose files and the Quadlet set DB_PATH, BACKUP_DIR and
# MODULES_DIR accordingly), so a host path here only moves the mount source. Do not
# pass this file to a bare `docker run --env-file`: nothing pins those names there,
# and BACKUP_DIR=./backups would 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
# The placeholder below is not a secret: it is printed in this repository, so
# anyone who can reach your instance could forge a session cookie and sign in as
# any user. The app refuses to start until you replace it. Generate a value with
# `openssl rand -base64 48`. Changing it later only signs everyone out once.
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
# AES-256 encryption at rest. Leave empty for an unencrypted database (development).
# Once set, the key cannot be changed without re-encrypting, and a wrong key aborts
# the start. An existing unencrypted database is encrypted once on the next start;
# the untouched original is kept as <DB_PATH>.plaintext-backup — delete it after you
# have verified that the app starts and your data is complete.
# Both installers keep an existing key when you re-run them, so a second setup pass
# cannot lock you out of a database that is already encrypted.
# The placeholder below is not a key: it is printed in the repository, so a database
# encrypted against it is not protected. A fresh installation refuses to start until
# you either put a real value here or clear the line to run unencrypted.
DB_ENCRYPTION_KEY=REPLACE_WITH_A_STRONG_ENCRYPTION_KEY
# Emergency switch, normally unset. Migrations only run forward, so a database that a
# newer Yuvomi has opened carries migrations an older version does not know, and that
# older version refuses to start on it: what it wrote in the meantime could be lost on
# the next update. The way back is the backup taken before the update. Set to 1 to
# start anyway, at your own risk; a warning is logged on every start while it is set.
# DB_ALLOW_NEWER_SCHEMA=
# 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=
# OPENWEATHER_CITY=Berlin
# OPENWEATHER_UNITS=metric
# OPENWEATHER_LANG=en
# Google Calendar (optional)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=https://your-domain.com/api/v1/calendar/google/callback
# Outlook Calendar Push via Microsoft Graph (optional) — one-way Yuvomi → Outlook
# for personal Microsoft accounts (outlook.com / M365 Family). Requires a free
# Entra ID app registration ("Personal Microsoft accounts only"), see
# docs/installation.md. All three values must be set to enable the provider.
MS_CLIENT_ID=
MS_CLIENT_SECRET=
MS_REDIRECT_URI=https://your-domain.com/api/v1/calendar/outlook/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 — all four values must be set to enable OIDC)
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: link existing accounts by email when the IdP omits the email_verified
# claim entirely. Only set this for an IdP fully under your control that never
# issues unverified addresses (e.g. older Authentik without an explicit
# email_verified property mapping).
# OIDC_TRUST_EMAIL_WITHOUT_VERIFIED_CLAIM=true
# Set to false so an SSO sign-in never creates a new account. Existing accounts
# are still recognised and still get linked on first SSO sign-in, so the admin
# creates the account and the user signs in with SSO - only provisioning for
# unknown identities is dropped. Use this when the IdP serves more people than
# this household. Default: true (any identity your IdP accepts gets an account).
# OIDC_ALLOW_SIGNUP=false
# Set to false to make SSO the only way in: the login form disappears, password
# login is refused, and password reset is switched off with it. Existing
# password hashes stay untouched, so setting this back to true restores the
# form unchanged - clearing a password is a per-account decision in
# Settings -> Family. Takes effect only once all four OIDC values above are set
# AND at least one administrator account is linked to the provider; until then it is ignored
# and the server says so on startup, because otherwise nobody could sign in at
# all - a fresh install creates its first admin through /setup with a password.
# Recovery when the IdP is unreachable: remove this line and restart.
# Default: true.
# AUTH_ALLOW_PASSWORD_LOGIN=false
# 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
# Notification channels (Webhook, Gotify, ntfy): the same SSRF protection as
# ICS feeds - a channel URL must resolve to a public address. Set true for a
# Gotify or ntfy container in the same Docker network or a Home Assistant
# webhook in the LAN. Only in controlled environments.
# NOTIFICATION_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)
# BACKUP_UPLOAD_LIMIT=100mb # Max size of a backup file uploaded for restore via the admin UI (Express body-limit syntax)
# 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)
# Maximum size of a single upload, in megabytes (documents, calendar attachments,
# housekeeping receipts). Default 5, supported range 1-100. This is a limit on the
# process, not on disk: the request body is buffered in memory before any route
# sees it, so a very large value can take the container down on a small machine.
# MAX_UPLOAD_MB=5
# 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 # Path inside the container
# DOCUMENT_STORAGE_LOCAL_DIR=./documents # Host folder mounted onto that path (compose only).
# The two are the ends of one mount: LOCAL_DIR on the host, LOCAL_PATH inside
# the container. The Compose files derive both ends from here, so changing
# LOCAL_PATH moves the mount with it. Deployments that pin the target to a
# literal /documents instead would send uploads into the container layer, gone
# on the next `pull && up -d` while the database keeps referencing them.
# 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)
# Recipe provider mirrors (Mealie, Tandoor): allow private/local network targets
# (e.g. self-hosted in the same Docker network). Set true to lift the SSRF
# protection for recipe provider sync - only in controlled environments.
# RECIPE_PROVIDER_ALLOW_PRIVATE_NETWORK=false # Set true to allow local/private network Mealie/Tandoor targets (e.g. self-hosted in the same Docker network)
# Waste collection URL sources (#1063): allow private/local network feeds
# (e.g. a municipal waste calendar mirrored by a self-hosted service in the
# same Docker network). Set true to lift the SSRF protection - only in
# controlled environments. Without it, every http:// URL is rejected and an
# https:// URL that resolves to a private address is blocked at connect time.
# WASTE_SOURCE_ALLOW_PRIVATE_NETWORK=false
# Document management systems (Paperless-ngx, Papra): allow private/local
# network targets. NOTE the inverted default - unlike the three flags above,
# this one defaults to TRUE. A DMS is self-hosted by definition and in practice
# sits on the same LAN or Docker network as Yuvomi, so blocking private targets
# by default would break virtually every existing setup. Set it to false to
# enforce the same SSRF protection the other integrations have.
# DMS_ALLOW_PRIVATE_NETWORK=true # Set false to block local/private network Paperless/Papra targets
# 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. Must be routable:
# Apple rejects a localhost/.local subject with 403 and
# push then fails on iOS only. Defaults to the SMTP sender
# address, else BASE_URL, else a placeholder.
# Email / SMTP (optional)
# Configure an SMTP server to enable the "Forgot password" self-service flow, email as a
# household notification channel (alongside Gotify/ntfy/webhooks), and sending a shopping
# list to a member. All three share this one configuration - no per-channel credentials.
# Set BASE_URL too if reminder mails should carry a link back into the app.
# 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, mailed invitation links and calendar
# export-feed URLs. REQUIRED for reset and invitation emails: links are only sent when
# this is set (the request Host header is never trusted, to prevent reset poisoning).
# An invitation link copied from the admin page works without this - the browser builds
# that one from its own origin; only mailing it needs the value. 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
# 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. Defaults to BASE_URL, otherwise
# http://<BIND_ADDRESS>:<PORT> (127.0.0.1 while BIND_ADDRESS is unset). Override the
# base URL only when neither reaches the app.
# 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
# Optional Immich photo screensaver. IMMICH_URL may be the server root or end in /api.
# The API key needs asset.read and asset.view permissions. Album ID is optional.
IMMICH_URL=
IMMICH_API_KEY=
IMMICH_SCREENSAVER_ALBUM_ID=