Setting up Files (High Performance Backend)

I had little trouble to setup notify_push in my docker-compose environment as I didn’t find clear instructions how the components are tied together so I decided to write all the steps together. This guide shows you how to setup High Performance Back-end for Nextcloud Files aka notify_push in Docker-compose environment with traefik proxy.

prerequisits

as prereqs you need running Nextcloud 21 with Redis (notify_push requires Redis) behind Traefik reverse proxy

environment

overview of the components. I decided to keep my individual container names in this article as it is crucial for the setup to use container names for some configs and I feel unique names easier to follow in opposite to generic hostnames like db or app. I didn’t understand this from the beginning and had hard time to find out the ways which components how depends on another one.

  • dev-nextcloud-app: NC application container
  • dev-nextcloud-redis: redis container
  • dev-nextcloud-notify_push: notify server
  • network traefik-proxy: external network used to expose services to traefik reverse proxy

install push app

docker exec --user www-data dev-nextcloud-app php occ app:install notify_push

Alternatively install the app “Client Push” with your browser.

create container for notify_push server

settings you need to adopt is

  • the image (adjust with you Nextcloud application container)
  • reverse proxy network ( traefik_proxy)
  • NEXTCLOUD_URL - use your Nextcloud container name with http:// prefix. Use the port you expose within application container. I didn’t manage notify_push to talk with public https:// address of Nextcloud (and from my point of view there is no advantage - direct communication through docker network is more direct and therefore faster)
  • ${NEXTCLOUD_FQDN} within the traefik rule - use your public FQDN in this place. Traefik uses this line to forward requests to https://${NEXTCLOUD_FQDN}/push to you notify_push server. Hint: you can expose this value through Docker .env file - so you can reuse it in all places you need this hostname
  • mount same config and apps (or custom_apps if separated) volumes you mount in your Nextcloud application container. config volume is needed to detect redis settings (host and password) custom_apps folder is where the server is installed and will be user to start the process (entrypoint:). No need to mount files

docker-compose.yaml:

services: 
  dev-nextcloud-notify_push:
    image: nextcloud:21.0 # use same image as you NC application
    container_name: dev-nextcloud-notify_push
    restart: unless-stopped
    networks:
      - traefik_proxy
      - default
    depends_on:
      - dev-nextcloud-db
      - dev-nextcloud-redis
      - dev-nextcloud-app
    volumes:
      - ./app:/var/www/html
      - ./config:/var/www/html/config:ro
    environment:
      - PORT=7867
      - NEXTCLOUD_URL=http://dev-nextcloud-app/  # NC app container name
    entrypoint: /var/www/html/custom_apps/notify_push/bin/x86_64/notify_push /var/www/html/config/config.php
    labels:
      - traefik.enable=true
      - traefik.protocol=http
      - traefik.docker.network=traefik_proxy
      - traefik.port=7867
      - traefik.http.services.dev-nextcloud_push.loadbalancer.server.port=7867
      - traefik.http.routers.dev-nextcloud_push.priority=2
      - traefik.http.routers.dev-nextcloud_push.middlewares=dev-nextcloud_strip_push
      - traefik.http.routers.dev-nextcloud_push.tls=true
      - traefik.http.routers.dev-nextcloud_push.entryPoints=web-secure
      - traefik.http.routers.dev-nextcloud_push.tls.certresolver=letsencrypt
      # necessary for the notify_push app to work:
      - traefik.http.routers.dev-nextcloud_push.rule=Host(`${NEXTCLOUD_FQDN}`) && PathPrefix(`/push`)
      - traefik.http.middlewares.dev-nextcloud_strip_push.stripprefix.prefixes=/push

one important hint:
you as both dev-nextcloud-app and dev-nextcloud-notify_push share the same domain it’s nessesary to add priorites to Traefik rules:

services: 
  dev-nextcloud-app:
  - traefik.http.routers.dev-nextcloud-app.priority=1
  dev-nextcloud-notify_push: 
  - traefik.http.routers.dev-nextcloud_push.priority=2

test notify_push container

start the new container with docker-compose up (-d if you prefer to check logs manually). If the dev-nextcloud-notify_push container doesn’t start and complains abont missing notify_push binary make sure you installed the the app first (docker exec or GUI)

verify your notify server is up and reachable from your client through Traefik (TLS works as well)

#display ip address of the user
https://${NEXTCLOUD_FQDN}/index.php/apps/notify_push/test/remote
#JSON with content "null"
https://${NEXTCLOUD_FQDN}/index.php/apps/notify_push/test/version
#some number (cookie id)
https://${NEXTCLOUD_FQDN}/index.php/apps/notify_push/test/cookie

configure push app

here you configure the Nextcloud application side to use the notify_push server component and provide the adress where this component lives. the address is https:// followed by the ${NEXTCLOUD_FQDN} followed by (/push)

docker exec --user www-data dev-nextcloud-app php occ notify_push:setup http://dev-nextcloud-notify_push
#if more logging ist needed
#docker exec --user www-data dev-nextcloud-app php occ notify_push:log 0

the output should be like this:

root@srv:~# docker exec --user www-data dev-nextcloud-app php occ notify_push:setup https://${NEXTCLOUD_FQDN}
✓ redis is configured
✓ push server is receiving redis messages
✓ push server can load mount info from database
✓ push server can connect to the Nextcloud server
✓ push server is a trusted proxy
✓ push server is running the same version as the app
  configuration saved

if there is a problem with trusted proxies

push server is not a trusted proxy, please add '172.19.0.2' to the list of trusted proxies or configure any existing reverse proxy to forward the 'x-forwarded-for' send by the push server.
  See https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/reverse_proxy_configuration.html#defining-trusted-proxies for how to set trusted proxies.
  The following trusted proxies are currently configured: "traefik, 172.16.0.0/12, 192.168.0.0/16, 10.0.0.0/8"
  The following x-forwarded-for header was received by Nextcloud: 1.2.3.4
    from the following remote: 172.19.0.2

make sure the IP address of dev-nextcloud-notify_push is configured within dev-nextcloud-app TRUSTED_PROXIES variable.

# docker name of the reverse proxy container (space separated list of fqdns/ips)
TRUSTED_PROXIES='traefik 172.16.0.0/12 192.168.0.0/16 10.0.0.0/8'

I recommend you to setup the whole 172.16.0.0/12 network (private network used by docker for internal networking) for trusted proxies - depending on your setup you may want to choose more secure configuration. Consult Admin manual > reverse proxy configurations for details

#show effective trusted_proxies from docker command line
docker exec --user www-data dev-nextcloud-app php occ config:system:get trusted_proxies
#should output something like this:
'traefik
172.16.0.0/12
192.168.0.0/16
10.0.0.0/8'

final steps

I found I need to restart my my docker application by

docker-compose down
docker-compose up -d

to make it work. Maybe disable and enable the app or restart browser session would do as well…

verification

notify_push results in changes reflected instant in the client. This is especially noticable in the Talk app - old behavior results in chat messages and incoming call are delayed by up to 15 sec (pull intervall) - once notify_push is running well and client recognize this (logout/login in browser, restart of desktop client) new messages and calls arrive immediately.

you can consult the log of dev-nextcloud-app as well

docker logs dev-nextcloud-app -n 100

without notify_push every client checks the server for updates every 15 sec… (PROPFIND request) after setup of notify_push you should not see such requests anymore (or at least much less frequent)

such PROPFIND request looks like this in client logs (similar in server logs)

[ info nextcloud.sync.accessmanager ]:	6 "PROPFIND" "https://${NEXTCLOUD_FQDN}/remote.php/dav/files/<username>/"

successful notify_push connection is visible in the client log:

2021-03-31 14:43:18:567 [ info nextcloud.sync.networkjob.jsonapi ]:	JsonApiJob of QUrl("https://${NEXTCLOUD_FQDN}/ocs/v1.php/cloud/capabilities?format=json") FINISHED WITH STATUS "OK"
2021-03-31 14:43:18:568 [ info nextcloud.sync.connectionvalidator ]:	Server capabilities QJsonObject( <<<lot of text>>> "notify_push":{"endpoints":{"pre_auth":"https://${NEXTCLOUD_FQDN}/apps/notify_push/pre_auth","websocket":"wss://${NEXTCLOUD_FQDN}/push/ws"} <<lot of text>>)
2021-03-31 14:43:18:569 [ info nextcloud.sync.account ]:	Try to setup push notifications
2021-03-31 14:43:18:569 [ info nextcloud.sync.pushnotifications ]:	Create websocket
2021-03-31 14:43:18:569 [ info nextcloud.sync.pushnotifications ]:	Open connection to websocket on: QUrl("wss://${NEXTCLOUD_FQDN}/push/ws")

if you see some issue verify the client can access the host displayed in this log line.

I hope you enjoy this guide and have much faster results then I had.

3 Likes