Nextcloud
Partage de fichiers et collaboration auto-hébergés — le hub auquel d’autres templates se connectent.
- Projet original : https://nextcloud.com
- Remplace : Google Drive, Dropbox, OneDrive Entreprise
- Connexion (SSO) : Câblé automatiquement — la convergence de votre opérateur exécute un hook CLI idempotent qui enregistre Keycloak dans l’app à chaque passage. Aucune étape post-déploiement côté client.
Étapes de configuration
Section intitulée « Étapes de configuration »- Ouvrez l’onglet Environment et remplissez
S3_BUCKET,S3_REGION,S3_HOST,S3_ACCESS_KEY,S3_SECRET_KEYavec les coordonnées de votre seau S3. (Le reste est pré-rempli —NEXTCLOUD_HOSTNAME, identifiants admin/DB, variables d’intégration OIDC.) - Cliquez Deploy. Patientez ~2 min pour le premier démarrage.
- Câblez le SSO : ouvrez
actions.<votre-domaine>puis cliquez Câbler l’OIDC pour Nextcloud. Le bouton enregistre Keycloak comme fournisseur OIDC à l’intérieur de Nextcloud (idempotent — peut être recliqué sans risque après un redéploiement ou une rotation de secret). - Connectez-vous sur votre domaine Nextcloud avec Se connecter avec keycloak (utilise votre identité gérée par l’opérateur), ou repli sur
NEXTCLOUD_ADMIN_USER/NEXTCLOUD_ADMIN_PASSWORDde l’onglet Environment.
Connexion avec Keycloak — câblée par le bouton OliveTin
Section intitulée « Connexion avec Keycloak — câblée par le bouton OliveTin »Après le premier déploiement de Nextcloud, vous cliquez
Câbler l’OIDC pour Nextcloud sur
actions.<votre-domaine>. Le bouton active l’application
user_oidc de Nextcloud et enregistre un fournisseur
keycloak avec les valeurs OIDC de l’onglet Environment. La
page de connexion Nextcloud affiche alors Se connecter
avec keycloak à votre prochaine visite. La connexion admin
locale (NEXTCLOUD_ADMIN_USER / NEXTCLOUD_ADMIN_PASSWORD)
continue de fonctionner en parallèle comme issue de secours.
Recliquez le bouton chaque fois que la configuration OIDC dérive (après une rotation de secret, un redéploiement destructif, etc.). Il est idempotent — relancer ne fait que rafraîchir l’enregistrement du fournisseur.
Le partage de fichiers par lien courriel fonctionne toujours
Section intitulée « Le partage de fichiers par lien courriel fonctionne toujours »L’authentification Keycloak gouverne la connexion des
utilisateurs à Nextcloud. Elle ne restreint pas les
liens de partage publics anonymes — les URL
/s/<jeton> que votre équipe génère depuis Nextcloud
restent accessibles aux destinataires qui n’ont pas de
compte Keycloak.
Le flux courant fonctionne donc tel quel :
- Un membre de votre équipe (utilisateur connecté) crée un lien de partage dans Nextcloud, avec un mot de passe et une date d’expiration s’il le souhaite.
- Nextcloud envoie le lien par courriel au destinataire.
- Le destinataire clique le lien. Cloudflare Tunnel achemine la requête directement à Nextcloud ; Nextcloud sert la page de partage publique (ou l’invite de mot de passe, si vous en avez défini un). Pas de redirection Keycloak, pas de connexion requise.
Cela fonctionne parce que Nextcloud est atteint via son
propre code d’authentification, pas via un proxy
forward-auth. Le module user_oidc ne gère que le flux de
connexion pour les membres de votre équipe ; les points
d’accès des partages publics restent anonymes par
conception.
Si vous souhaitez verrouiller complètement les partages publics, le bon contrôle est à l’intérieur de Nextcloud (Paramètres -> Partage -> “Autoriser le partage par lien public”), pas au niveau réseau.
Variables d’environnement
Section intitulée « Variables d’environnement »Ces valeurs se trouvent dans l’onglet Environment du compose Dokploy. Les secrets aléatoires sont générés automatiquement au premier semi du template — vous n’avez pas à les générer vous-même.
| Variable | Valeur par défaut |
|---|---|
NEXTCLOUD_HOSTNAME | nextcloud.yourdomain.com |
NEXTCLOUD_ADMIN_USER | admin |
NEXTCLOUD_ADMIN_PASSWORD | valeur aléatoire auto-générée |
DB_PASSWORD | valeur aléatoire auto-générée |
NEXTCLOUD_LOGLEVEL | 1 |
NEXTCLOUD_VERSIONS_RETENTION | auto, 7 |
NEXTCLOUD_TRASH_RETENTION | auto, 30 |
S3_BUCKET | (à définir avant déploiement) |
S3_REGION | bhs |
S3_HOST | s3.bhs.io.cloud.ovh.net |
S3_ACCESS_KEY | (à définir avant déploiement) |
S3_SECRET_KEY | (à définir avant déploiement) |
OIDC_CLIENT_ID | nextcloud |
OIDC_CLIENT_SECRET | <your-nextcloud_oidc_client_secret> |
OIDC_DISCOVERY_URL | https://auth.yourdomain.com/realms/catena/.well-known/openid-configuration |
OIDC_ISSUER_URL | https://auth.yourdomain.com/realms/catena |
OIDC_REDIRECT_URL | https://nextcloud.yourdomain.com/apps/user_oidc/code |
SIGNALING_HOSTNAME | signaling.yourdomain.com |
SIGNALING_SECRET | <your-nextcloud_talk_signaling_secret> |
TALK_INTERNAL_SECRET | <your-nextcloud_talk_internal_secret> |
TURN_HOSTNAME | turn.yourdomain.com |
TURN_STATIC_AUTH_SECRET | <your-turn_static_auth_secret> |
- Service et port :
app:80 - Nom d’hôte :
nextcloud.yourdomain.com
Le nom d’hôte est attaché automatiquement au semi du template ; modifiez-le dans l’onglet Domains avant de cliquer Deploy si vous souhaitez autre chose.
Fichier compose
Section intitulée « Fichier compose »Pour référence — c’est ce que le template déploie. Ne collez ceci nulle part. Le compose est semé dans Dokploy automatiquement ; les ajustements côté client se font dans les onglets Environment et Domains (décrits plus haut), jamais dans le compose lui-même.
# Nextcloud -- S3 primary storage + Keycloak SSO.## All values come from the Environment tab: hostname, S3 credentials,# admin password, DB password, OIDC coordinates (auto-injected). The# compose itself is not edited per deploy.
services: app: image: nextcloud:33.0.3-apache restart: unless-stopped # Two-stage delivery for the loglevel override: # # 1. The entrypoint wrapper writes a `before-starting` hook # script into the container's writable layer (image-baked # path /docker-entrypoint-hooks.d/before-starting/). # 2. Wrapper exec's the upstream /entrypoint.sh apache2-foreground. # 3. Upstream entrypoint populates /var/www/html/config (rsync # from /usr/src/nextcloud/config/), runs occ install / occ # upgrade, then iterates `before-starting/*.sh` -- our hook # runs as www-data and drops zz-loglevel.config.php into the # already-populated config dir. # # Why this dance instead of writing the .config.php from the # wrapper directly? Upstream's populate.sh skips rsync'ing # /var/www/html/config when the dir is already non-empty # (`directory_empty` check). A wrapper that writes our file in # /var/www/html/config BEFORE the upstream runs makes the dir # non-empty -> populate skips -> autoconfig.php / redis.config.php # / s3.config.php / etc. never land in the volume -> Apache 503s. # Running our writer in a before-starting HOOK sidesteps that # check entirely. # # Why not the compose-v2 `configs:` block? Through Dokploy the # inline content-delivery pipeline produced a script that exited 2 # with no script-side stderr on every start. Materializing the # hook ourselves via the wrapper bypasses that delivery path. # # `$$X` -> `$X` after compose interpolation. The outer # `<<'HOOK'` is single-quoted so the wrapper writes the hook # body verbatim; the INNER `<<PHP` is unquoted so the runtime # shell expands `${NEXTCLOUD_LOGLEVEL}` and friends from the # container env. `\$$CONFIG` escapes the `$` through both # rounds so the literal `$CONFIG` (PHP variable) lands in the # rendered .config.php. entrypoint: - /bin/sh - -ec - | cat > /docker-entrypoint-hooks.d/before-starting/zz-catena.sh <<'HOOK' #!/bin/sh # Catena-managed config overlay. Re-rendered on every container # start from the env vars below. Lets the operator change # client-policy knobs (log level, version retention) via the # Dokploy Environment tab without dropping into occ. set -e : "$${NEXTCLOUD_LOGLEVEL:=1}" : "$${NEXTCLOUD_VERSIONS_RETENTION:=auto, 7}" : "$${NEXTCLOUD_TRASH_RETENTION:=auto, 30}" cat > /var/www/html/config/zz-catena.config.php <<PHP <?php \$$CONFIG = [ 'loglevel' => $${NEXTCLOUD_LOGLEVEL}, 'versions_retention_obligation' => '$${NEXTCLOUD_VERSIONS_RETENTION}', 'trashbin_retention_obligation' => '$${NEXTCLOUD_TRASH_RETENTION}', ]; PHP # Server-side encryption (SSE), master-key mode. Encrypts file # content before it is handed to the S3 object-store driver, so # the storage provider only ever sees ciphertext at rest. # Master-key mode encrypts against a single, operator-recoverable # key (held in DB + the config `secret`) -- NOT per-user keys, # which would put files out of reach of an operator restore. # Idempotent: this hook runs on every container start, but # master-key SELECTION runs only once -- on the fresh install, # before any file is encrypted. Switching modes on already- # encrypted data is destructive, hence the useMasterKey guard. # `encryption:enable-master-key` prompts y/n and treats # --no-interaction as "no", so the confirmation is fed on stdin. php occ app:enable encryption # Force-set the useMasterKey config flag BEFORE any path that # might trigger the encryption module's per-user-mode bootstrap. # Bench diag (run 2026-05-31T14-26-35-ad7b nc_s3_hot_recovery) # caught the failure mode this guards against: master_<id>.{pub, # priv}Key files DID land in S3, but useMasterKey stayed empty # in oc_appconfig. Nextcloud's KeyManager::getPrivateKey then # took the per-user branch (because isMasterKeyEnabled returns # false when useMasterKey != "1") and threw PrivateKeyMissing- # Exception for admin -- the admin user has no per-user key # because we never went through that setup. occ encryption: # enable-master-key shorts out with "Master key already enabled" # if the FILES exist, regardless of the config flag, so the # original guard could not self-heal. Setting the flag # idempotently FIRST flips KeyManager into master-key mode for # every subsequent occ + Apache request. php occ config:app:set encryption useMasterKey --value=1 if [ "$$(php occ config:app:get encryption useMasterKey 2>/dev/null)" != "1" ]; then printf 'y\n' | php occ encryption:enable-master-key fi php occ encryption:enable # --- Catena SSE diagnostic sentinel ------------------------------ # Captures the bytes that would diverge under the three Bad- # Signature theories (secret rotation, hook ordering, S3 master- # key corruption) so the bench / operator can compare runtime # state against install-time state when WebDAV PUT 503s with # "Encryption not ready". Hashes never leak the secret in # clear -- only sha256 prints land in the sentinel. The file # sits under the local nc-data volume (NOT objectstore), so it # survives container recreate but goes away with the VM disk. # Rewritten on every container boot so a redeploy that bumps # the secret would show in a fresh capture. diag_inst="$$(php occ config:system:get instanceid 2>/dev/null | tr -d '\n')" diag_secret="$$(php occ config:system:get secret 2>/dev/null)" diag_salt="$$(php occ config:system:get passwordsalt 2>/dev/null)" diag_secret_h="$$(printf '%s' "$$diag_secret" | sha256sum | cut -d' ' -f1)" diag_salt_h="$$(printf '%s' "$$diag_salt" | sha256sum | cut -d' ' -f1)" diag_useMK="$$(php occ config:app:get encryption useMasterKey 2>/dev/null | tr -d '\n')" diag_encE="$$(php occ config:app:get core encryption_enabled 2>/dev/null | tr -d '\n')" diag_defM="$$(php occ config:app:get core default_encryption_module 2>/dev/null | tr -d '\n')" diag_apps_enc="$$(php occ app:list 2>/dev/null | awk '/^- encryption:/{getline; print $$2}' | tr -d '\n')" diag_now="$$(date -u +%Y-%m-%dT%H:%M:%SZ)" mkdir -p /var/www/html/data cat > /var/www/html/data/.catena-encryption-setup.json <<EOF_DIAG { "captured_at": "$$diag_now", "container_hostname": "$$(hostname)", "instanceid": "$$diag_inst", "secret_sha256": "$$diag_secret_h", "passwordsalt_sha256": "$$diag_salt_h", "encryption_app_useMasterKey": "$$diag_useMK", "core_encryption_enabled": "$$diag_encE", "core_default_encryption_module": "$$diag_defM", "encryption_app_version": "$$diag_apps_enc" } EOF_DIAG HOOK chmod 0755 /docker-entrypoint-hooks.d/before-starting/zz-catena.sh # Remove the predecessor hook if present from a prior catalog # version so the same key is not declared twice. rm -f /docker-entrypoint-hooks.d/before-starting/zz-loglevel.sh \ /var/www/html/config/zz-loglevel.config.php exec /entrypoint.sh "$$@" - -- command: ["apache2-foreground"] environment: NEXTCLOUD_TRUSTED_DOMAINS: ${NEXTCLOUD_HOSTNAME} NEXTCLOUD_ADMIN_USER: ${NEXTCLOUD_ADMIN_USER} NEXTCLOUD_ADMIN_PASSWORD: ${NEXTCLOUD_ADMIN_PASSWORD}
# Catena-managed config knobs. The zz-catena.sh hook reads these # at container start and writes /var/www/html/config/zz-catena # .config.php. Change the value here (Dokploy Environment tab) # + redeploy and the next container start picks it up. # # NEXTCLOUD_LOGLEVEL: 0=debug, 1=info, 2=warn, 3=error, 4=fatal. # Default 1 matches the historical zz-loglevel.sh hook. # # NEXTCLOUD_VERSIONS_RETENTION: passed verbatim into the # `versions_retention_obligation` config key. Format is # `<min>, <max>` in days OR the keyword `auto, <N>` where N is # the operator-controlled max-age cap. Default `auto, 7` keeps # ~50-70% less storage than the upstream default 30-day cap; # raise to `auto, 14` or `auto, 30` for clients who routinely # need deeper undo. Direct lever on hot+cold bucket storage cost. # # NEXTCLOUD_TRASH_RETENTION: passed verbatim into the # `trashbin_retention_obligation` config key (same `auto, <N>` # format). This is the mass-DELETE safety net: a runaway desktop # sync that deletes a tree propagates the deletes server-side, but # the files land in each user's trash and are recoverable for at # least N days regardless of free space. Default `auto, 30` keeps a # 30-day undo window for accidental/ransomware bulk deletion; lower # it only for storage-constrained clients who accept a shorter # recovery window. (versions_retention covers OVERWRITES; this # covers DELETES -- both are needed.) NEXTCLOUD_LOGLEVEL: ${NEXTCLOUD_LOGLEVEL:-1} NEXTCLOUD_VERSIONS_RETENTION: ${NEXTCLOUD_VERSIONS_RETENTION:-auto, 7} NEXTCLOUD_TRASH_RETENTION: ${NEXTCLOUD_TRASH_RETENTION:-auto, 30}
# TLS is terminated upstream (Cloudflare Tunnel -> Traefik). Force # Nextcloud to render https:// links + trust the reverse-proxy # Forwarded headers so user_oidc's HTTPS precondition check passes. OVERWRITEPROTOCOL: https OVERWRITEHOST: ${NEXTCLOUD_HOSTNAME} OVERWRITECLIURL: https://${NEXTCLOUD_HOSTNAME} TRUSTED_PROXIES: 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
POSTGRES_HOST: db POSTGRES_DB: nextcloud POSTGRES_USER: nextcloud POSTGRES_PASSWORD: ${DB_PASSWORD} REDIS_HOST: redis
OBJECTSTORE_S3_BUCKET: ${S3_BUCKET} OBJECTSTORE_S3_REGION: ${S3_REGION} OBJECTSTORE_S3_HOST: ${S3_HOST} OBJECTSTORE_S3_PORT: "443" OBJECTSTORE_S3_SSL: "true" OBJECTSTORE_S3_USEPATH_STYLE: "true" OBJECTSTORE_S3_AUTOCREATE: "false" OBJECTSTORE_S3_KEY: ${S3_ACCESS_KEY} OBJECTSTORE_S3_SECRET: ${S3_SECRET_KEY}
NEXTCLOUD_OIDC_CLIENT_ID: ${OIDC_CLIENT_ID} NEXTCLOUD_OIDC_CLIENT_SECRET: ${OIDC_CLIENT_SECRET} NEXTCLOUD_OIDC_ISSUER_URL: ${OIDC_ISSUER_URL} NEXTCLOUD_OIDC_REDIRECT_URL: ${OIDC_REDIRECT_URL}
# Talk + HPB wire script (catena-wire-nextcloud-talk-hpb) reads # these from the running container at click time and feeds them # to `occ talk:turn:add` / `occ talk:signaling:add`. They live # alongside the OIDC + S3 envs because both go through the same # docker-exec pattern. Empty / unset is fine -- the wire script # auto-detects HPB-disabled state via an http probe to # signaling:8081 first and exits 0 when the service is absent. SIGNALING_HOSTNAME: ${SIGNALING_HOSTNAME} SIGNALING_SECRET: ${SIGNALING_SECRET} TURN_HOSTNAME: ${TURN_HOSTNAME} TURN_STATIC_AUTH_SECRET: ${TURN_STATIC_AUTH_SECRET} volumes: - nc-config:/var/www/html/config - nc-apps:/var/www/html/custom_apps # Even with S3 primary storage, /var/www/html/data still holds # appdata_<instance>/ residue, nextcloud.log, audit.log, .ocdata, # sqlite caches for some apps -- everything Nextcloud writes # outside the objectstore driver. Explicit named volume so the # path lives at /mnt/data/docker/volumes/<compose>_nc-data/_data # (predictable, visible in `docker volume ls`, captured by # restic's docker/volumes/ rule). Without this mount, Docker # creates an anonymous volume from the image's VOLUME directive # -- still backed up but with an opaque sha256 name. - nc-data:/var/www/html/data labels: - "vps.auth.mode=public" - "vps.auth.oidc=true" - "vps.auth.groups=staff" - "vps.auth.oidc.redirect_uris=https://${NEXTCLOUD_HOSTNAME}/apps/user_oidc/code" - "vps.auth.oidc.scopes=openid email profile groups" - "vps.auto-update=patch" networks: dokploy-network: aliases: - nextcloud default: {} # Gate Nextcloud's first-boot install on postgres being ready to # accept connections. See the db service's healthcheck block for # the failure mode this prevents. depends_on: db: condition: service_healthy redis: condition: service_started
db: image: postgres:16.13-alpine restart: unless-stopped environment: POSTGRES_DB: nextcloud POSTGRES_USER: nextcloud POSTGRES_PASSWORD: ${DB_PASSWORD} volumes: - db-data:/var/lib/postgresql/data # pg_isready health-check is what `app` and `cron` gate on via # `depends_on: { db: { condition: service_healthy } }`. Without # it, both services launch in parallel with the db, the upstream # nextcloud entrypoint runs `occ maintenance:install` before # postgres has accepted its first connection, install retries 10x # 10s, exhausts the budget, container exits rc=1, Dokploy auto- # restarts. The restart finds /var/www/html/version.php already # written by the previous populate.sh run -> entrypoint takes the # UPGRADE path -> no-op -> NC stuck reporting installed=false. healthcheck: test: ["CMD-SHELL", "pg_isready -U nextcloud -d nextcloud"] interval: 5s timeout: 3s retries: 30 start_period: 10s labels: - "vps.auto-update=patch" networks: - default
redis: image: redis:7.4.9-alpine restart: unless-stopped labels: - "vps.auto-update=patch" networks: - default
cron: image: nextcloud:33.0.3-apache restart: unless-stopped entrypoint: /cron.sh environment: POSTGRES_HOST: db POSTGRES_DB: nextcloud POSTGRES_USER: nextcloud POSTGRES_PASSWORD: ${DB_PASSWORD} REDIS_HOST: redis OBJECTSTORE_S3_BUCKET: ${S3_BUCKET} OBJECTSTORE_S3_REGION: ${S3_REGION} OBJECTSTORE_S3_HOST: ${S3_HOST} OBJECTSTORE_S3_PORT: "443" OBJECTSTORE_S3_SSL: "true" OBJECTSTORE_S3_USEPATH_STYLE: "true" OBJECTSTORE_S3_KEY: ${S3_ACCESS_KEY} OBJECTSTORE_S3_SECRET: ${S3_SECRET_KEY} volumes: - nc-config:/var/www/html/config - nc-apps:/var/www/html/custom_apps # Cron and app must share the data volume -- background jobs # (file scanning, preview generation, etc.) write to the same # /var/www/html/data tree the app reads from. - nc-data:/var/www/html/data # No command override on cron: it runs /cron.sh as its entrypoint, # which is a thin runner for occ background-jobs. The app service # writes zz-loglevel.config.php into the shared nc-config volume # on its own startup; cron picks it up via the shared mount. networks: - default # Cron is also a Nextcloud entrypoint variant (runs /cron.sh) so # it gates on postgres readiness for the same reason `app` does. depends_on: db: condition: service_healthy redis: condition: service_started
# === HPB BEGIN -- Talk High-Performance Backend ========================== # Comment out this single service to disable Talk + HPB. The wire # script catena-wire-nextcloud-talk-hpb already handles the # "HPB not deployed -> exit 0" path so leaving it commented does # NOT break the rest of the stack -- Talk falls back to built-in # P2P mode (works up to ~5 participants). # # Image is the Nextcloud team's official All-In-One HPB bundle: # signaling + janus + nats + an internal eturnal TURN, all under # supervisord in one container. We deliberately KEEP the standalone # roles/coturn (TURN/STUN at turn.<base>:5349) because Rocket.Chat's # bundled Jitsi (rocketchat-oidc template) shares the same coturn # via JVB_TURN_*. Two design choices follow from that: # # 1. Janus inside aio-talk is configured (via TURN_DOMAIN + # TALK_PORT) to use the EXTERNAL standalone coturn for its # own ICE relay. Janus's start.sh inside aio-talk mints # ephemeral HMAC-SHA1 creds against TURN_SECRET (which we # set to vault_turn_static_auth_secret -- the same secret # coturn validates with). Clients dialing Talk get TURN # coordinates pointing at the same coturn (set by the # catena-wire-nextcloud-talk-hpb wire script via # `occ talk:turn:add`), so all media converges through one # shared TURN provider. # 2. aio-talk's bundled eturnal still binds TALK_PORT inside # the container netns -- start.sh has no skip flag for it. # That binding is harmless: TALK_PORT=5349 lives only in the # container's private netns; nothing on the host competes. # The bundled eturnal stays unused. # # Public exposure: only the signaling HTTP endpoint (port 8081 # inside the container) needs to be reachable. The catalog entry # in dokploy_template_catalog.yml declares signaling.<base>:8081 # as an extra_domain so Dokploy auto-injects the Traefik labels. # # Tag: pinned to a dated upstream build. Bump by listing # `ghcr.io/nextcloud-releases/aio-talk` tags and picking the # most recent stable one (the upstream tag scheme is YYYYMMDD_HHMMSS). talk-hpb: image: ghcr.io/nextcloud-releases/aio-talk:20260409_094910 init: true restart: unless-stopped environment: # NEXTCLOUD_HOSTNAME owns the public Nextcloud URL; aio-talk # advertises this to clients as the parent app's identity. NC_DOMAIN: ${NEXTCLOUD_HOSTNAME} # Public hostname clients dial for the WSS signaling channel. # Routed through Cloudflare Tunnel + Traefik to this container's # port 8081. TALK_HOST: ${SIGNALING_HOSTNAME} # TURN coordinates Janus uses for its own ICE candidates. # Pointed at the standalone coturn (turn.<base>:5349) so # restrictive-network clients reach Janus through the same # shared TURN that the wire script advertises to Talk. TURN_DOMAIN: ${TURN_HOSTNAME} TALK_PORT: "5349" TURN_SECRET: ${TURN_STATIC_AUTH_SECRET} # Bearer secret between the signaling service and the Talk # backend. The wire script (catena-wire-nextcloud-talk-hpb) # passes this same value to `occ talk:signaling:add`, so the # two endpoints share the secret. SIGNALING_SECRET: ${SIGNALING_SECRET} # Internal secret between the signaling frontend and its # backend store. Never leaves the container; aio-talk requires # it set at startup but clients never see it. INTERNAL_SECRET: ${TALK_INTERNAL_SECRET} # Quiet the supervisord log to warn-level by default; bump to # debug temporarily when troubleshooting. AIO_LOG_LEVEL: warn # Optional bitrate ceilings. aio-talk defaults to 1 Mbps audio + # 2 Mbps screen-share when these are unset; ship the defaults # explicitly so a UI edit lands in the catalog managed-keys. TALK_MAX_STREAM_BITRATE: "1048576" TALK_MAX_SCREEN_BITRATE: "2097152" labels: # Public via Traefik (the Domain entry in catalog adds the # router/service labels at deploy time). Bearer-secret authed # by aio-talk's signaling layer; no oauth2-proxy gate. - "vps.auth.mode=public" - "vps.auto-update=patch" networks: dokploy-network: aliases: # Wire script's auto-detect probe hits http://signaling:8081 # from inside the Nextcloud container; keep this alias so # the existing probe URL continues to resolve. - signaling default: {} # === HPB END =============================================================
volumes: nc-config: nc-apps: nc-data: db-data:
networks: dokploy-network: external: true