Skip to main content
Little disclaimer. Some information was copied from virtualize.link, because I find information provided by its author useful. Make sure to check the source or star the repo.
The following is a collection of ways to optimize Nextcloud’s performance and responsiveness.

Optimization steps

A step by step guide for setting up:
  • SWAG reverse proxy via cloudflare
  • Nextcloud
  • Redis
  • Mariadb
  • Collabora
  • Notify push
  • Talk high performance backend
  • Whiteboard
  • Imaginary
  • Draw.io
  • Maintenance
Replace all occurences of domain.com with your domain.

SWAG

  • Create a Cloudflare account and set it as the nameserver for your domain.
  • Create DNS records for domain.com and *.domain.com with your home’s WAN IP, disable the orange cloud.
  • Port forward 443 to your server on your home router.
  • Add SWAG to your docker compose and start it.
swag:
  image: lscr.io/linuxserver/swag:latest
  container_name: swag
  cap_add:
    - NET_ADMIN
  environment:
    - PUID=1000
    - PGID=1000
    - TZ=Etc/UTC
    - URL=domain.com
    - VALIDATION=dns
    - SUBDOMAINS=wildcard
    - DNSPLUGIN=cloudflare
    - PROPAGATION=60
    - SWAG_AUTORELOAD=true
  volumes:
    - /path/to/swag:/config
  ports:
    - 443:443
    - 80:80
  restart: unless-stopped
  • Generate a Cloudflare API token with DNS:Read, DNS:Edit permissions to domain.com and copy the token.
  • Edit /path/to/swag/dns-conf/cloudflare.ini, delete everything and paste the following with your token:
dns_cloudflare_api_token = token
  • Rename /path/to/swag/nginx/proxy-confs/nextcloud.subdomain.conf.sample to nextcloud.subdomain.conf.
  • Edit /path/to/swag/nginx/ssl.conf and uncomment HSTS and all the additional headers on the bottom.
  • Restart SWAG and make sure that domain.com shows the welcome page with a valid certificate.

Nextcloud

nextcloud:
  image: lscr.io/linuxserver/nextcloud:latest
  container_name: nextcloud
  environment:
    - PUID=1000
    - PGID=1000
    - TZ=Etc/UTC
  volumes:
    - /path/to/nextcloud/config:/config
    - /path/to/nextcloud/data:/data
  restart: unless-stopped
  depends_on:
    - mariadb
mariadb:
  image: lscr.io/linuxserver/mariadb:latest
  container_name: mariadb
  environment:
    - PUID=1000
    - PGID=1000
    - TZ=Etc/UTC
    - MYSQL_ROOT_PASSWORD=nextcloud_root_password
    - MYSQL_DATABASE=nextcloud_db
    - MYSQL_USER=nextcloud_user
    - MYSQL_PASSWORD=nextcloud_password
  volumes:
    - /path/to/mariadb:/config
  restart: unless-stopped
redis:
  image: redis:alpine
  container_name: redis
  restart: unless-stopped
  • Navigate to https://nextcloud.domain.com and fill out the details for Nextcloud and Mariadb. Nextcloud setup
  • Select recommended apps to install.
  • Run the following commands.
docker exec nextcloud occ app:disable richdocumentscode
docker exec nextcloud occ maintenance:repair --include-expensive
docker exec nextcloud occ db:add-missing-indices
docker exec -u abc nextcloud mkdir -p /config/log/nextcloud
docker exec nextcloud occ config:system:set overwrite.cli.url --value='https://nextcloud.domain.com'
docker exec nextcloud occ config:system:set memcache.local --value='\\OC\\Memcache\\APCu'
docker exec nextcloud occ config:system:set memcache.locking --value='\\OC\\Memcache\\Redis'
docker exec nextcloud occ config:system:set memcache.distributed --value='\\OC\\Memcache\\Redis'
docker exec nextcloud occ config:system:set logfile --value='/config/log/nextcloud/nextcloud.log'
docker exec nextcloud occ config:system:set trusted_proxies 0 --value='172.16.0.0/12'
docker exec nextcloud occ config:system:set trusted_proxies 1 --value='127.0.0.1'
docker exec nextcloud occ config:system:set trusted_proxies 2 --value='::1'
docker exec nextcloud occ config:system:set redis host --value='redis'
docker exec nextcloud occ config:system:set redis port --value=6379 --type=integer
docker exec nextcloud occ config:system:set loglevel --value=2 --type=integer
docker exec nextcloud occ config:system:set log_rotate_size --value=10485760 --type=integer
docker exec nextcloud occ config:system:set maintenance_window_start --value=1 --type=integer
docker exec nextcloud occ config:system:set filesystem_check_changes --value=1 --type=integer
docker exec nextcloud occ config:system:set filelocking.enabled --value=true --type=boolean
  • Add the following to /path/to/nextcloud/config/php/www2.conf.
pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18
  • Restart Nextcloud to apply the changes.

Collabora

  • Add Collabora to your docker compose and start it.
collabora:
  image: collabora/code
  container_name: collabora
  environment:
    - DONT_GEN_SSL_CERT=1
    - aliasgroup1=https://nextcloud.domain.com
    - dictionaries=en_US
    - server_name=nextcloud.domain.com
    - extra_params=--o:security.capabilities=false --o:ssl.enable=false --o:ssl.termination=true --o:logging.level=caution --o:net.post_allow.host[0]=.+ --o:home_mode.enable=true --o:mount_jail_tree=false --o:mount_namespaces=false  --o:remote_font_config.url=https://nextcloud.domain.com/apps/richdocuments/settings/fonts.json
  restart: unless-stopped
  cap_add:
    - SYS_CHROOT
    - MKNOD
  • Add the following locations to /path/to/swag/nginx/proxy-confs/nextcloud.subdomain.conf inside the server section.
location ^~ /browser/ {
    include /config/nginx/proxy.conf;
    include /config/nginx/resolver.conf;
    set $upstream_app collabora;
    set $upstream_port 9980;
    set $upstream_proto http;
    proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
location ^~ /hosting/ {
    include /config/nginx/proxy.conf;
    include /config/nginx/resolver.conf;
    set $upstream_app collabora;
    set $upstream_port 9980;
    set $upstream_proto http;
    proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
location ^~ /cool/ {
    include /config/nginx/proxy.conf;
    include /config/nginx/resolver.conf;
    set $upstream_app collabora;
    set $upstream_port 9980;
    set $upstream_proto http;
    proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
  • Run the following commands.
docker exec nextcloud occ app:enable richdocuments
docker exec nextcloud occ config:app:set richdocuments wopi_url --value https://nextcloud.domain.com
docker exec nextcloud occ config:app:set richdocuments wopi_allowlist --value=0.0.0.0/0
docker exec nextcloud occ config:app:set richdocuments doc_format --value=ooxml
  • Disable Collabora’s dark mode under View > Dark Mode.

Notify Push

  • Add the following environment variable to Nextcloud’s docker compose and recreate it.
environment:
  - DOCKER_MODS=linuxserver/mods:nextcloud-notify-push

Talk high performance backend

  • Generate 3 secrets using the following command and paste them to the compose below.
openssl rand -hex 32
  • Add the high performance backend to your docker compose and start it.
talk:
  image: nextcloud/aio-talk:latest
  container_name: talk
  init: true
  ports:
    - 3478:3478/tcp
    - 3478:3478/udp
  environment:
    - NC_DOMAIN=nextcloud.domain.com
    - TALK_HOST=talk.domain.com
    - TZ=Etc/UTC
    - TALK_PORT=3478
    - TURN_SECRET=secret
    - SIGNALING_SECRET=secret
    - INTERNAL_SECRET=secret
  restart: unless-stopped
  • Paste the following to the bottom of /path/to/swag/nginx/proxy-confs/nextcloud.subdomain.conf.
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name talk.*;
    include /config/nginx/ssl.conf;
    client_max_body_size 0;

    location / {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app talk;
        set $upstream_port 8081;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
}
  • Run the following commands using the secrets generated earlier.
docker exec nextcloud occ talk:signaling:add --verify https://talk.domain.com SIGNALING_SECRET
docker exec nextcloud occ talk:stun:add talk.domain.com:3478
docker exec nextcloud occ talk:turn:add --secret TURN_SECRET turn talk.domain.com:3478 udp,tcp
  • Optionally port forward 3478 on your router to expose it.

Whiteboard

  • Generate a secret using the following command and paste it below.
openssl rand -hex 32
  • Add Whiteboard to your docker compose and start it.
whiteboard:
  image: ghcr.io/nextcloud-releases/whiteboard:release
  container_name: whiteboard
  environment:
    - NEXTCLOUD_URL=https://nextcloud.domain.com
    - STORAGE_STRATEGY=redis
    - REDIS_HOST=redis
    - JWT_SECRET_KEY=secret
  restart: unless-stopped
  • Paste the following to the bottom of /path/to/swag/nginx/proxy-confs/nextcloud.subdomain.conf.
server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name whiteboard.*;
    include /config/nginx/ssl.conf;
    client_max_body_size 0;

    location / {
        include /config/nginx/proxy.conf;
        include /config/nginx/resolver.conf;
        set $upstream_app whiteboard;
        set $upstream_port 3002;
        set $upstream_proto http;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
}
  • Run the following commands.
docker exec nextcloud occ app:enable whiteboard
docker exec nextcloud occ config:app:set whiteboard collabBackendUrl --value="https://whiteboard.domain.com"
docker exec nextcloud occ config:app:set whiteboard jwt_secret_key --value="secret"

Imaginary

  • Add Imaginary to your docker compose and start it.
imaginary:
  image: nextcloud/aio-imaginary:latest
  container_name: imaginary
  restart: unless-stopped
  • Run the following commands.
docker exec nextcloud occ config:system:set enable_previews --value=true --type=boolean
docker exec nextcloud occ config:system:set enabledPreviewProviders 0 --value='OC\\Preview\\Imaginary'
docker exec nextcloud occ config:system:set enabledPreviewProviders 1 --value='OC\\Preview\\Movie'
docker exec nextcloud occ config:system:set enabledPreviewProviders 2 --value='OC\\Preview\\MP4'
docker exec nextcloud occ config:system:set preview_imaginary_url --value='http://imaginary:9000'

Diagrams

  • Add draw.io to your docker compose and start it.
drawio:
  image: jgraph/drawio:alpine
  container_name: drawio
  restart: unless-stopped
  • Add the following locations to /path/to/swag/nginx/proxy-confs/nextcloud.subdomain.conf inside the server section.
location ^~ /draw/ {
    include /config/nginx/proxy.conf;
    include /config/nginx/resolver.conf;
    set $upstream_app drawio;
    set $upstream_port 8080;
    set $upstream_proto http;
    proxy_pass $upstream_proto://$upstream_app:$upstream_port;
}
  • Run the following commands.
docker exec nextcloud occ app:enable drawio
docker exec nextcloud occ config:app:set drawio DrawioUrl --value="https://nextcloud.domain.com/draw"

Maintenance

  • Manually pull new images and recreate the containers every few weeks.
  • Check docker logs mariadb for upgrade instructions.
  • Run the following commands.
docker exec nextcloud occ maintenance:repair --include-expensive
docker exec nextcloud occ db:add-missing-indices
docker exec nextcloud occ app:update --all