# ============================================================================= # Ulti Backend — Configuration # ============================================================================= # Secrets : definir UNE FOIS dans la section ci-dessous. # Le reste du fichier utilise {{NOM_VARIABLE}} — expansion au lancement # (docker compose, go run, migrate) via cmd/envexpand → .env.resolved # # Chaque brique peut etre en mode "local" (stack Docker) ou "external". # ============================================================================= # ----------------------------------------------------------------------------- # Secrets — source unique (rotation ici uniquement) # ----------------------------------------------------------------------------- POSTGRES_PASSWORD=changeme RUSTFS_ACCESS_KEY=ultiadmin RUSTFS_SECRET_KEY=changeme123 AUTHENTIK_SECRET_KEY=changeme-generate-a-long-random-string ULTID_OIDC_CLIENT_SECRET=changeme MAIL_CREDENTIAL_KEYS=v1:MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY= MAIL_ACTIVE_CREDENTIAL_KEY_ID=v1 MAIL_WEBHOOK_SHARED_SECRET=changeme-webhook-signing-secret NC_ADMIN_PASSWORD=changeme NC_OIDC_CLIENT_SECRET=changeme JITSI_APP_SECRET=changeme-jwt-secret JITSI_INTERNAL_AUTH_PASSWORD=changeme KEYDB_PASSWORD= MEILISEARCH_API_KEY=changeme TYPESENSE_API_KEY=changeme # ----------------------------------------------------------------------------- # General # ----------------------------------------------------------------------------- DOMAIN=localhost ULTID_PORT=8080 # ----------------------------------------------------------------------------- # PostgreSQL # Mode local : deploye dans la stack Docker (deploy/docker-compose.yml) # Mode externe : pointer vers une instance existante # ----------------------------------------------------------------------------- POSTGRES_USER=ulti POSTGRES_DB=ultidb POSTGRES_MULTIPLE_DATABASES=ultidb,authentik,nextcloud,immich # Connection utilisee par ultid (changer host pour instance externe) ULTID_DB_URL=postgres://{{POSTGRES_USER}}:{{POSTGRES_PASSWORD}}@postgres:5432/{{POSTGRES_DB}}?sslmode=disable # Exemple externe : # ULTID_DB_URL=postgres://user:{{POSTGRES_PASSWORD}}@db.example.com:5432/ultidb?sslmode=require # ----------------------------------------------------------------------------- # KeyDB (Redis-compatible) # Mode local : deploye dans la stack # Mode externe : pointer vers un Redis/KeyDB/Valkey existant # ----------------------------------------------------------------------------- ULTID_KEYDB_URL=keydb:6379 ULTID_KEYDB_PASSWORD={{KEYDB_PASSWORD}} ULTID_KEYDB_DB=0 # Exemple externe : ULTID_KEYDB_URL=redis.example.com:6379 KEYDB_HOST=keydb KEYDB_PORT=6379 # ----------------------------------------------------------------------------- # Object Storage (S3-compatible : RustFS, MinIO, AWS S3, Backblaze, etc.) # Mode local : RustFS deploye dans la stack # Mode externe : n'importe quel endpoint S3-compatible # ----------------------------------------------------------------------------- ULTID_RUSTFS_ENDPOINT=rustfs:9000 ULTID_RUSTFS_ACCESS_KEY={{RUSTFS_ACCESS_KEY}} ULTID_RUSTFS_SECRET_KEY={{RUSTFS_SECRET_KEY}} ULTID_RUSTFS_USE_SSL=false ULTID_RUSTFS_REGION=us-east-1 # Exemple AWS S3 : # ULTID_RUSTFS_ENDPOINT=s3.amazonaws.com # ULTID_RUSTFS_USE_SSL=true # ULTID_RUSTFS_REGION=eu-west-1 # ----------------------------------------------------------------------------- # Auth / OIDC (Authentik, Keycloak, ou tout provider OIDC) # Mode local : Authentik deploye dans la stack # Mode externe : n'importe quel provider OIDC existant # ----------------------------------------------------------------------------- ULTID_OIDC_ISSUER=http://authentik-server:9000/application/o/ulti/ ULTID_OIDC_CLIENT_ID=ulti-backend # ULTID_OIDC_CLIENT_SECRET — defini dans la section Secrets # Exemple Keycloak externe : # ULTID_OIDC_ISSUER=https://auth.example.com/realms/ulti # ULTID_OIDC_CLIENT_ID=ulti-backend # Config du container Authentik local (ignoree si provider externe) # AUTHENTIK_SECRET_KEY — defini dans la section Secrets AUTHENTIK_POSTGRESQL__HOST=postgres AUTHENTIK_POSTGRESQL__USER={{POSTGRES_USER}} AUTHENTIK_POSTGRESQL__PASSWORD={{POSTGRES_PASSWORD}} AUTHENTIK_POSTGRESQL__NAME=authentik AUTHENTIK_REDIS__HOST=keydb AUTHENTIK_WEB__PATH=/auth/ # ----------------------------------------------------------------------------- # Nextcloud (Drive / Calendar / Contacts) # Mode local : Nextcloud FPM deploye dans la stack # Mode externe : instance Nextcloud existante # ----------------------------------------------------------------------------- # URL interne (ultid → nginx Nextcloud, racine WebDAV) NEXTCLOUD_URL=http://nextcloud:80 # URL publique UI (edge nginx /cloud/) NC_PUBLIC_URL=http://{{DOMAIN}}/cloud NC_OVERWRITE_PROTOCOL=http NC_ADMIN_USER=admin # NC_ADMIN_PASSWORD — defini dans la section Secrets # Exemple externe : # NEXTCLOUD_URL=https://cloud.example.com # NC_ADMIN_USER=ulti-service # Desactiver (pas de Drive/Cal/Contacts) : NEXTCLOUD_ENABLED=false NEXTCLOUD_ENABLED=true # Ce flag pilote aussi le lancement Docker via ./deploy/compose-up.sh NC_OIDC_CLIENT_ID=ulti-nextcloud # NC_OIDC_CLIENT_SECRET — defini dans la section Secrets NC_OIDC_DISCOVERY_URL=http://authentik-server:9000/application/o/nextcloud/.well-known/openid-configuration NC_S3_BUCKET=nextcloud NC_S3_HOST=rustfs NC_S3_PORT=9000 NC_S3_KEY={{RUSTFS_ACCESS_KEY}} NC_S3_SECRET={{RUSTFS_SECRET_KEY}} NC_S3_SSL=false # ----------------------------------------------------------------------------- # Jitsi Meet (Visioconference) # Mode local : Jitsi deploye dans la stack # Mode externe : instance Jitsi existante avec JWT configure # ----------------------------------------------------------------------------- JITSI_ENABLED=true # Ce flag pilote aussi le lancement Docker via ./deploy/compose-up.sh JITSI_DOMAIN=meet.jitsi JITSI_APP_ID=ulti # JITSI_APP_SECRET — defini dans la section Secrets JITSI_PUBLIC_URL=https://{{DOMAIN}}/meet JICOFO_AUTH_PASSWORD={{JITSI_INTERNAL_AUTH_PASSWORD}} JVB_AUTH_PASSWORD={{JITSI_INTERNAL_AUTH_PASSWORD}} JVB_STUN_SERVERS=stun.l.google.com:19302 # ----------------------------------------------------------------------------- # Immich (Photos) # Mode local : Immich deploye dans la stack # Mode externe : instance Immich existante # ----------------------------------------------------------------------------- IMMICH_ENABLED=true # Ce flag pilote aussi le lancement Docker via ./deploy/compose-up.sh # Immich utilise son propre Postgres (pgvecto.rs) via immich-postgres IMMICH_API_URL=http://immich-server:2283/api # Quota photos partagé avec Ultidrive (0 = désactivé) ULTID_PHOTOS_MAX_UPLOAD_BYTES=0 ULTID_PHOTOS_QUOTA_RESERVED_BYTES=0 IMMICH_DB_NAME=immich IMMICH_UPLOAD_LOCATION=/upload IMMICH_ML_URL=http://immich-ml:3003 # ----------------------------------------------------------------------------- # Health checks / Observability # ----------------------------------------------------------------------------- # Endpoints vérifiés par /healthz (surchargables pour déploiements externes) HEALTH_NEXTCLOUD_URL={{NEXTCLOUD_URL}}/status.php HEALTH_IMMICH_URL={{IMMICH_API_URL}}/server-info/ping # Par défaut on retire /meet de JITSI_PUBLIC_URL pour viser /about/health HEALTH_JITSI_URL=https://{{DOMAIN}}/about/health HEALTH_HTTP_TIMEOUT=3s # Grafana local (monitoring) GRAFANA_ADMIN_USER=admin GRAFANA_ADMIN_PASSWORD=admin # ----------------------------------------------------------------------------- # Mail (Ultimail) — toujours gere par ultid # ----------------------------------------------------------------------------- MAIL_ATTACHMENTS_BUCKET=mail-attachments MAIL_SYNC_INTERVAL=2m MAIL_OUTBOX_INTERVAL=10s MAIL_OUTBOX_MAX_RETRIES=8 MAIL_SEND_RATE_PER_MINUTE=30 MAIL_SEND_BURST=10 MAIL_SMTP_CIRCUIT_FAILURES=5 MAIL_SMTP_CIRCUIT_COOLDOWN=5m # Credentials IMAP/SMTP chiffrés AES-GCM (format keyring: key_id:base64key,key_id2:base64key2) # Rotation: ajouter nouvelle clé dans MAIL_CREDENTIAL_KEYS puis basculer MAIL_ACTIVE_CREDENTIAL_KEY_ID. # Les anciennes clés restent présentes temporairement pour déchiffrement. # Runtime secrets possibles via *_FILE (ex: MAIL_CREDENTIAL_KEYS_FILE=/run/secrets/mail_keys) # Politique rotation secrets (RFC3339 + durée) SECRET_ROTATION_MAX_AGE=2160h ULTID_OIDC_CLIENT_SECRET_ROTATED_AT=2026-01-01T00:00:00Z MAIL_CREDENTIAL_KEY_ROTATED_AT=2026-01-01T00:00:00Z MAIL_WEBHOOK_SHARED_SECRET_ROTATED_AT=2026-01-01T00:00:00Z # ----------------------------------------------------------------------------- # Recherche # SEARCH_ENGINE: postgres (defaut) | meilisearch | typesense # ----------------------------------------------------------------------------- SEARCH_ENGINE=postgres # --- Meilisearch (SEARCH_ENGINE=meilisearch) --- # MEILISEARCH_URL=http://meilisearch:7700 # MEILISEARCH_API_KEY={{MEILISEARCH_API_KEY}} # MEILISEARCH_INDEX=ulti # --- Typesense (SEARCH_ENGINE=typesense) --- # TYPESENSE_URL=http://typesense:8108 # TYPESENSE_API_KEY={{TYPESENSE_API_KEY}} # TYPESENSE_COLLECTION=ulti