Compare commits

..

16 Commits

Author SHA1 Message Date
3wordchant 65b1090e54 README update for imaginary 2026-04-15 15:10:57 -04:00
3wordchant d6a9db3162 Fix docker compose version 2026-04-15 15:10:30 -04:00
3wordchant c89109f7db Initial imagination 2026-04-15 15:10:29 -04:00
decentral1se 45d1985ddc Merge pull request 'add user_oidc' (#70) from oxaliq/nextcloud:user_oidc_setup into main
Reviewed-on: coop-cloud/nextcloud#70
2026-03-24 21:27:08 +00:00
decentral1se d49f3c4ef8 Merge pull request 'fix: mention that you need to install OnlyOffice first' (#74) from ineiti/nextcloud:readme_onlyoffice into main
Reviewed-on: coop-cloud/nextcloud#74
Reviewed-by: decentral1se <decentral1se@noreply.git.coopcloud.tech>
2026-03-18 08:26:19 +00:00
Linus Gasser a2395c6399 @decentral1se comment 2026-03-17 22:26:35 +01:00
Linus Gasser e4b3bc4f22 fix: mention that you need to install OnlyOffice first 2026-03-17 22:26:35 +01:00
moritz 21ea1daf83 chore: replace depricated traefik.docker.* with traefik.swarm.* 2026-03-17 17:25:38 +01:00
oxaliq ec5934e191 document user_oidc setup 2026-03-12 09:56:53 -04:00
oxaliq 4c3f6fa14d add command for initializing user_oidc 2026-03-11 15:55:53 -04:00
oxaliq eb3816b9c2 add env and secrets for user_oidc app 2026-03-11 15:55:26 -04:00
simon 8b7ed8142e chore: publish 13.0.1+32.0.3-fpm release 2026-01-14 12:22:05 +01:00
simon 87b064c773 chore: publish 13.0.0+32.0.3-fpm release 2026-01-13 16:34:02 +01:00
iexos d6a77fac4d remove default TIMEOUT (abra #596) 2025-12-30 14:00:00 +01:00
p4u1 f27ea1a2cc chore: publish 12.1.0+31.0.6-fpm release 2025-12-23 14:30:22 +01:00
Apfelwurm c952020194 Implement NC Talk High Performance Backend (#56)
This implements the high performance backend for Nextcloud Talk, which is nessecary if it needs to handle more people (video) calling.
More Details about it: https://nextcloud-talk.readthedocs.io/en/latest/quick-install/

The current implementation is sadly limited to be used once per host, so this might need some additional love in the future, if someone needs it more flexible.

The related traefik pr: coop-cloud/traefik#66

Reviewed-on: coop-cloud/nextcloud#56
Co-authored-by: Apfelwurm <Alexander@volzit.de>
Co-committed-by: Apfelwurm <Alexander@volzit.de>
2025-12-23 13:28:18 +00:00
10 changed files with 274 additions and 33 deletions
+20 -1
View File
@@ -1,5 +1,5 @@
TYPE=nextcloud
TIMEOUT=900
#TIMEOUT=900
ENABLE_AUTO_UPDATE=true
ENABLE_BACKUPS=true
@@ -15,6 +15,7 @@ COMPOSE_FILE="$COMPOSE_FILE:compose.mariadb.yml"
#MAX_DB_CONNECTIONS=500
ADMIN_USER=admin
TZ=Etc/UTC
SECRET_DB_ROOT_PASSWORD_VERSION=v1
SECRET_DB_PASSWORD_VERSION=v1
@@ -86,6 +87,24 @@ DEFAULT_QUOTA="10 GB"
#COMPOSE_FILE="$COMPOSE_FILE:compose.fulltextsearch.yml"
#SECRET_ELASTICSEARCH_PASSWORD_VERSION=v1
#COMPOSE_FILE="$COMPOSE_FILE:compose.talk.yml"
#TALK_DOMAIN=talk.example.com
#SECRET_TALK_INTERNAL_SECRET_VERSION=v1 # length=64 charset=default
#SECRET_TALK_TURN_SECRET_VERSION=v1 # length=64 charset=default
#SECRET_TALK_SIGNALING_SECRET_VERSION=v1 # length=64 charset=default
# COMPOSE_FILE="$COMPOSE_FILE:compose.user_oidc.yml"
# APPS="$APPS user_oidc"
# USER_OIDC_PROVIDER=
# USER_OIDC_ID=
# USER_OIDC_DISCOVERY_URI=
# USER_OIDC_END_SESSION_URI=
# USER_OIDC_LOGIN_ONLY=false
# SECRET_USER_OIDC_SECRET_VERSION=v1
# Image / PDF previews with Imaginary (see README)
#COMPOSE_FILE="$COMPOSE_FILE:compose.imaginary-preview.yml"
# HSTS Options
# Uncomment this line to enable HSTS: https://docs.nextcloud.com/server/30/admin_manual/installation/harden_server.html
#HSTS_ENABLED=1
+88 -5
View File
@@ -25,20 +25,28 @@ Fully automated luxury Nextcloud via docker-swarm.
### Onlyoffice Integration
First install onlyoffice following the instructions in the
[OnlyOffice Recipe](https://recipes.coopcloud.tech/onlyoffice), and enable
the JWT secret.
`abra app config <app-name>`
Configure the following envs:
Configure the following envs with the URL of the onlyoffice service:
```
COMPOSE_FILE="$COMPOSE_FILE:compose.apps.yml"
ONLYOFFICE_URL=https://onlyoffice.example.com
SECRET_ONLYOFFICE_JWT_VERSION=v1
```
`abra app secret insert <app-name> onlyoffice_jwt v1 <jwt_secret>`
`abra app cmd <app-name> app install_onlyoffice`
Then set the onlyoffice JWT secret from the onlyoffice installation:
* `abra app secret insert <app-name> onlyoffice_jwt v1 <jwt_secret>`
* `abra app cmd <app-name> app install_onlyoffice`
### BBB Integration
`abra app config <app-name>`
Configure the following envs:
```
COMPOSE_FILE="$COMPOSE_FILE:compose.apps.yml"
@@ -46,8 +54,44 @@ BBB_URL=https://talk.example.org/bigbluebutton/ # trailing slash!
SECRET_BBB_SECRET_VERSION=v1
```
`abra app secret insert <app-name> bbb_secret v1 <bbb_secret>`
`abra app cmd <app-name> app install_bbb`
* `abra app secret insert <app-name> bbb_secret v1 <bbb_secret>`
* `abra app cmd <app-name> app install_bbb`
### Nextcloud Talk High performance Backend
Note: at the moment you are limited to run one Nextcloud high performance backend per docker host with this setup.
`abra app config <app-name>`
Configure the following envs:
```
#COMPOSE_FILE="$COMPOSE_FILE:compose.talk.yml"
#TALK_DOMAIN=talk.example.com
#SECRET_TALK_INTERNAL_SECRET_VERSION=v1 # length=64 charset=default
#SECRET_TALK_TURN_SECRET_VERSION=v1 # length=64 charset=default
#SECRET_TALK_SIGNALING_SECRET_VERSION=v1 # length=64 charset=default
```
* `abra app secret insert <app-name> talk_internal_secret v1 <talk_internal_secret>`
* `abra app secret insert <app-name> talk_turn_secret v1 <talk_turn_secret>`
* `abra app secret insert <app-name> talk_signaling_secret v1 <talk_signaling_secret>`
* `abra app cmd <app-name> app install_talk`
Don't forget to enable the additional env's in your hosts traefik instance:
```
COMPOSE_FILE="$COMPOSE_FILE:compose.nextcloud-talk-hpb.yml"
NEXTCLOUD_TALK_HPB_ENABLED=1
```
Due to a bug in compose that deletes duplacted ports without checking for the protocol, traefik need to get the additional udp binding added after the deployment via ssh (this might take longer than expected!):
```
docker service update --publish-add published=3478,target=3478,protocol=udp traefik_XXX_XXX_app
```
To check if tcp and udp was binded, you can use:
```
docker service inspect traefik_XXX_XXX_app | grep 3478 -a2
```
### Authentik Integration
@@ -150,6 +194,31 @@ We've been able to get this setup by using the [social login](https://apps.nextc
If using Keycloak, you'll want to do [this trick](https://janikvonrotz.ch/2020/10/20/openid-connect-with-nextcloud-and-keycloak/) also.
## How do I enable OpenID Connect (OIDC) providers?
[user_oidc](https://github.com/nextcloud/user_oidc) is the recommended way to integrate Nextcloud with OIDC providers.
Run `abra app config <app-name>`
Set the following envs:
```env
COMPOSE_FILE="$COMPOSE_FILE:compose.user_oidc.yml"
APPS="$APPS user_oidc"
USER_OIDC_PROVIDER=example-provider # this has been tested with keycloak
USER_OIDC_ID=example-client-id # get this from your oidc provider
USER_OIDC_DISCOVERY_URI=example-oidc-provider.com/.well-known/openid-configuration # get this from your oidc provider
USER_OIDC_END_SESSION_URI=example-oidc-provider.com/protocol/openid-connect/logout # get this from your oidc provider
USER_OIDC_LOGIN_ONLY=false # set this to true to automatically redirect all logins to your oidc provider
SECRET_USER_OIDC_SECRET_VERSION=v1
```
Then insert the client secret from your OIDC provider:
```sh
abra app secret insert <app-name> user_oidc_secret v1 <client-secret from oidc provider>
```
After you deploy (or redeploy), run the following to set up the user_oidc Nextcloud app:
`abra app cmd <app-name> app set_user_oidc`
## How can I customise the CSS?
There is some basic stuff in the admin settings.
@@ -246,6 +315,20 @@ docker exec -u www-data $(docker ps -f name=foo_com_app -q) ./occ preview:pre-ge
This app will improve performance of image browsing at the cost of storage space.
## Better image previews with `imaginary`
1. Run `abra app config <domain>` and uncomment the line `#COMPOSE_FILE="$COMPOSE_FILE:compose.imaginary-preview.yml"`.
2. Re-deploy the app (`abra app deploy <domain> --force`)
3. Edit `/var/www/config/config.php` and add:
```
'enabledPreviewProviders' =>
array (
0 => 'OC\\Preview\\Imaginary',
),
'preview_imaginary_url' => 'http://imaginary:9000',
```
## Fulltextsearch using elasticsearch
1. Uncomment the following lines in your env file:
+27
View File
@@ -5,6 +5,7 @@ export NGINX_CONF_VERSION=v8
export MY_CNF_VERSION=v6
export ENTRYPOINT_VERSION=v3
export ENTRYPOINT_WHITEBOARD_VERSION=v1
export ENTRYPOINT_TALK_VERSION=v1
export CRONTAB_VERSION=v1
export PG_BACKUP_VERSION=v2
@@ -97,6 +98,15 @@ install_whiteboard() {
}
install_talk() {
install_apps spreed
run_occ "talk:signaling:add --verify 'wss://${TALK_DOMAIN}' '$(cat /run/secrets/talk_signaling_secret)'"
run_occ "talk:stun:add '${TALK_DOMAIN}:3478'"
run_occ "talk:stun:add '${TALK_DOMAIN}:443'"
run_occ "talk:turn:add --secret='$(cat /run/secrets/talk_turn_secret)' turn '${TALK_DOMAIN}:3478' udp,tcp"
}
install_fulltextsearch() {
install_apps fulltextsearch
install_apps fulltextsearch_elasticsearch
@@ -149,6 +159,23 @@ set_authentik() {
run_occ 'config:system:set lost_password_link --value=disabled'
}
set_user_oidc() {
install_apps user_oidc
USER_OIDC_SECRET=$(cat /run/secrets/user_oidc_secret)
run_occ "user_oidc:provider \
--clientid=${USER_OIDC_ID} \
--clientsecret=${USER_OIDC_SECRET} \
--discoveryuri=${USER_OIDC_DISCOVERY_URI} \
--endsessionendpointuri=${USER_OIDC_END_SESSION_URI} \
--postlogouturi=https://${DOMAIN} \
--scope='openid email profile' \
${USER_OIDC_PROVIDER}"
# disable non user_oidc login
if [[ ${USER_OIDC_LOGIN_ONLY:-false} = "true" ]]; then
run_occ "config:app:set --value=0 user_oidc allow_multiple_user_backends"
fi
}
disable_skeletondirectory() {
run_occ "config:system:set skeletondirectory --value ''"
}
+2 -2
View File
@@ -2,7 +2,7 @@ version: "3.8"
services:
elasticsearch:
image: "docker.elastic.co/elasticsearch/elasticsearch:8.19.6"
image: "docker.elastic.co/elasticsearch/elasticsearch:8.17.2"
environment:
- cluster.name=docker-cluster
- bootstrap.memory_lock=true
@@ -29,7 +29,7 @@ services:
mode: 0600
searchindexer:
image: nextcloud:32.0.1-fpm
image: nextcloud:32.0.3-fpm
volumes:
- nextcloud:/var/www/html/
- nextapps:/var/www/html/custom_apps:cached
+10
View File
@@ -0,0 +1,10 @@
---
version: '3.8'
services:
imaginary:
image: nextcloud/aio-imaginary:20250822_112758
environment:
- PORT=9000
command: -concurrency 50 -enable-url-source -log-level debug
networks:
- internal
+70
View File
@@ -0,0 +1,70 @@
version: "3.8"
services:
talk:
image: "nextcloud/aio-talk:20251128_084214"
environment:
- NC_DOMAIN=${DOMAIN}
- TALK_HOST=${TALK_DOMAIN}
- TZ
- TALK_PORT=3478
- INTERNAL_SECRET_FILE=/run/secrets/talk_internal_secret
- TURN_SECRET_FILE=/run/secrets/talk_turn_secret
- SIGNALING_SECRET_FILE=/run/secrets/talk_signaling_secret
deploy:
labels:
- traefik.enable=true
- traefik.swarm.network=proxy
- traefik.http.services.${STACK_NAME}_talk.loadbalancer.server.port=8081
- traefik.http.routers.${STACK_NAME}_talk.rule=Host(`${TALK_DOMAIN}`)
- traefik.http.routers.${STACK_NAME}_talk.entrypoints=web-secure
- traefik.http.routers.${STACK_NAME}_talk.tls.certresolver=${LETS_ENCRYPT_ENV}
- traefik.tcp.routers.${STACK_NAME}_nextcloud-talk-hpb.rule=HostSNI(`*`)
- traefik.tcp.routers.${STACK_NAME}_nextcloud-talk-hpb.entrypoints=nextcloud-talk-hpb
- traefik.tcp.routers.${STACK_NAME}_nextcloud-talk-hpb.service=${STACK_NAME}_nextcloud-talk-hpb-svc
- traefik.tcp.services.${STACK_NAME}_nextcloud-talk-hpb-svc.loadbalancer.server.port=3478
- traefik.udp.routers.${STACK_NAME}_nextcloud-talk-hpb-udp.entrypoints=nextcloud-talk-hpb-udp
- traefik.udp.routers.${STACK_NAME}_nextcloud-talk-hpb-udp.service=${STACK_NAME}_nextcloud-talk-hpb-udp-svc
- traefik.udp.services.${STACK_NAME}_nextcloud-talk-hpb-udp-svc.loadbalancer.server.port=3478
networks:
- proxy
configs:
- source: entrypoint_talk
target: /custom-entrypoint.sh
mode: 775
entrypoint: /custom-entrypoint.sh
secrets:
- source: talk_internal_secret
uid: "1000"
gid: "122"
mode: 0600
- source: talk_turn_secret
uid: "1000"
gid: "122"
mode: 0600
- source: talk_signaling_secret
uid: "1000"
gid: "122"
mode: 0600
app:
secrets:
- talk_turn_secret
- talk_signaling_secret
secrets:
talk_internal_secret:
external: true
name: ${STACK_NAME}_talk_internal_secret_${SECRET_TALK_INTERNAL_SECRET_VERSION}
talk_turn_secret:
external: true
name: ${STACK_NAME}_talk_turn_secret_${SECRET_TALK_TURN_SECRET_VERSION}
talk_signaling_secret:
external: true
name: ${STACK_NAME}_talk_signaling_secret_${SECRET_TALK_SIGNALING_SECRET_VERSION}
configs:
entrypoint_talk:
name: ${STACK_NAME}_entrypoint_talk_${ENTRYPOINT_TALK_VERSION}
file: entrypoint.talk.sh.tmpl
template_driver: golang
+10
View File
@@ -0,0 +1,10 @@
version: "3.8"
services:
app:
secrets:
- user_oidc_secret
secrets:
user_oidc_secret:
external: true
name: ${STACK_NAME}_user_oidc_secret_${SECRET_USER_OIDC_SECRET_VERSION}
+3 -3
View File
@@ -6,11 +6,11 @@ services:
- whiteboard_jwt
whiteboard:
image: ghcr.io/nextcloud-releases/whiteboard:v1.4.1
image: ghcr.io/nextcloud-releases/whiteboard:v1.5.0
deploy:
labels:
- traefik.enable=true
- traefik.docker.network=proxy
- traefik.swarm.network=proxy
- traefik.http.services.${STACK_NAME}_whiteboard.loadbalancer.server.port=3002
- traefik.http.routers.${STACK_NAME}_whiteboard.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS}) && PathPrefix(`/whiteboard`)
- traefik.http.routers.${STACK_NAME}_whiteboard.entrypoints=web-secure
@@ -41,4 +41,4 @@ configs:
entrypoint_whiteboard:
name: ${STACK_NAME}_entrypoint_whiteboard_${ENTRYPOINT_WHITEBOARD_VERSION}
file: entrypoint.whiteboard.sh.tmpl
template_driver: golang
template_driver: golang
+14 -22
View File
@@ -1,7 +1,7 @@
version: "3.8"
services:
web:
image: nginx:1.29.3
image: nginx:1.29.4
depends_on:
- app
configs:
@@ -17,7 +17,7 @@ services:
volumes:
- nextcloud:/var/www/html/
- nextapps:/var/www/html/custom_apps:cached
- /mnt/data-3t/nextdata:/var/www/html/data:cached
- nextdata:/var/www/html/data:cached
- nextconfig:/var/www/html/config:cached
- ${EXTRA_VOLUME}
networks:
@@ -29,35 +29,26 @@ services:
order: start-first
labels:
- "traefik.enable=true"
- "traefik.docker.network=proxy"
# shared service & middleware
- "traefik.swarm.network=proxy"
- "traefik.http.services.${STACK_NAME}.loadbalancer.server.port=80"
- "traefik.http.middlewares.${STACK_NAME}-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.${STACK_NAME}-redirect.redirectscheme.permanent=true"
# public domain (lets-encrypt cert)
- "traefik.http.routers.${STACK_NAME}.rule=Host(`${DOMAIN}`${EXTRA_DOMAINS})"
- "traefik.http.routers.${STACK_NAME}.tls.certresolver=${LETS_ENCRYPT_ENV}"
- "traefik.http.routers.${STACK_NAME}.entrypoints=web-secure"
- "traefik.http.routers.${STACK_NAME}.middlewares=${STACK_NAME}-redirect"
# local domain (self-signed cert)
- "traefik.http.routers.${STACK_NAME}-local.rule=Host(`${LOCAL_DOMAIN}`)"
- "traefik.http.routers.${STACK_NAME}-local.tls=true"
- "traefik.http.routers.${STACK_NAME}-local.entrypoints=web-secure"
- "traefik.http.routers.${STACK_NAME}-local.middlewares=${STACK_NAME}-redirect"
- "traefik.http.routers.${STACK_NAME}-local.service=${STACK_NAME}"
- "traefik.http.middlewares.${STACK_NAME}-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.${STACK_NAME}-redirect.redirectscheme.permanent=true"
- "caddy=${DOMAIN}"
- "caddy.reverse_proxy={{upstreams 80}}"
- "caddy.tls.on_demand="
healthcheck:
test: ["CMD-SHELL", 'curl -s -N curl -Ns localhost/status.php | grep "installed\":true"']
test: ["CMD-SHELL", "curl -fsS http://localhost/status.php | grep -q '\"installed\":true'"]
interval: 30s
timeout: 10s
retries: 10
start_period: 5m
app:
image: nextcloud:32.0.1-fpm
image: nextcloud:32.0.3-fpm
depends_on:
- db
configs:
@@ -94,7 +85,7 @@ services:
volumes:
- nextcloud:/var/www/html/
- nextapps:/var/www/html/custom_apps:cached
- /mnt/data-3t/nextdata:/var/www/html/data:cached
- nextdata:/var/www/html/data:cached
- nextconfig:/var/www/html/config:cached
- ${EXTRA_VOLUME}
networks:
@@ -104,8 +95,8 @@ services:
failure_action: rollback
order: start-first
labels:
- "coop-cloud.${STACK_NAME}.version=12.0.1+31.0.6-fpm"
- "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT:-120}"
- "coop-cloud.${STACK_NAME}.version=13.0.1+32.0.3-fpm"
- "coop-cloud.${STACK_NAME}.timeout=${TIMEOUT}"
- "backupbot.backup=${ENABLE_BACKUPS:-true}"
- "backupbot.backup.volumes.redis=false"
#- "backupbot.backup.volumes.nextcloud=false"
@@ -118,11 +109,11 @@ services:
start_period: 15m
cron:
image: nextcloud:32.0.1-fpm
image: nextcloud:32.0.3-fpm
volumes:
- nextcloud:/var/www/html/
- nextapps:/var/www/html/custom_apps:cached
- /mnt/data-3t/nextdata:/var/www/html/data:cached
- nextdata:/var/www/html/data:cached
- nextconfig:/var/www/html/config:cached
- ${EXTRA_VOLUME}
networks:
@@ -134,7 +125,7 @@ services:
cache:
image: redis:8.2.3-alpine
image: redis:8.4.0-alpine
networks:
- internal
volumes:
@@ -156,6 +147,7 @@ secrets:
volumes:
nextcloud:
nextapps:
nextdata:
nextconfig:
redis:
+30
View File
@@ -0,0 +1,30 @@
#!/bin/bash
set -eu
file_env() {
local var="$1"
local fileVar="${var}_FILE"
local def="${2:-}"
if [ "${!var:-}" ] && [ "${!fileVar:-}" ]; then
echo >&2 "error: both $var and $fileVar are set (but are exclusive)"
exit 1
fi
local val="$def"
if [ "${!var:-}" ]; then
val="${!var}"
elif [ "${!fileVar:-}" ]; then
val="$(< "${!fileVar}")"
fi
export "$var"="$val"
unset "$fileVar"
}
file_env "INTERNAL_SECRET"
file_env "TURN_SECRET"
file_env "SIGNALING_SECRET"
/start.sh supervisord -c /supervisord.conf