diff --git a/README.md b/README.md
index 7ac0d1d53839274e49a3eff6bfcc5598593ea59d..4e3eab87df84e2e5a4f18bc7179f9835f4a929ae 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,9 @@ possible to specify which applications from the app store are available for
 installation. It is also possible to enable them by default. Apps that are not
 enabled by default can be enabled through the Apps screen in Nextcloud.
 
+Apps that are installed this way are automatically updated to their newest
+version every time Nextcloud is updated.
+
 To install apps, edit the values.yaml file:
 
 ```yaml
@@ -67,6 +70,27 @@ apps:
     enabled: false     # Disables sociallogin by default
 ```
 
+Additionally, we have added an option to install Apps immediately from GitHub
+releases. The benefit of this, compared to installing them with `occ`, is that
+we can pin the versions to specific GitHub releases.  To install an app from
+GitHub releases:
+
+```yaml
+apps:
+  - name: onlyoffice
+    # The name of the repository. This is the name for a repository located at
+    # https://github.com/ONLYOFFICE/onlyoffice-nextcloud:
+    github_repository: ONLYOFFICE/onlyoffice-nextcloud
+    # The version to install or upgrade the app to
+    version: 7.5.4
+    # The name of the "asset" to download from this release. This name can be
+    # found on https://github.com/ONLYOFFICE/onlyoffice-nextcloud/releases
+    release_filename: onlyoffice.tar.gz
+    # Enable the app after installing it
+    enabled: true
+```
+
+
 ## Values
 
 The included `values.yaml` file configures Nextcloud to use a Mariadb database,
diff --git a/renovate.json b/renovate.json
index f58279359441fcd09e57384d487a88b096e2d397..f5a7464785396920c19b2e10ffa93d05857cbc52 100644
--- a/renovate.json
+++ b/renovate.json
@@ -2,5 +2,16 @@
     "$schema": "https://docs.renovatebot.com/renovate-schema.json",
     "extends": [
         "local>stackspin/renovate-config"
+    ],
+    "regexManagers": [
+        {
+            "fileMatch": [
+                "(^|/)values\\.yaml*$"
+            ],
+            "matchStrings": [
+                "github_repository: (?<depName>.*)\n*version: (?<currentValue>.*)"
+            ],
+            "datasourceTemplate": "github-releases"
+        }
     ]
 }
diff --git a/templates/nextcloud-onlyoffice-config.yaml b/templates/nextcloud-onlyoffice-config.yaml
index 88a6a3d78aae0db3f0d4a3d7ebaf3fa057c8a74f..90037544dcc1318bb0a5315c920c6c1838b2fba3 100644
--- a/templates/nextcloud-onlyoffice-config.yaml
+++ b/templates/nextcloud-onlyoffice-config.yaml
@@ -49,25 +49,62 @@ data:
     # Enable app store so we can run `install` and `enable` commands
     php $occ config:system:set appstoreenabled --type boolean --value true
 
-    # Update all apps to their latest version, so they are compatible
-    # with the new NC version.
-    # Unfortunatly the occ app:install cmd doesn't allow to pin apps to
-    # a certain version.
-    php $occ app:update --all --no-interaction
 
     # Install all apps declared in the `apps` helm values array
     {{- range .Values.apps }}
-    # -- Begin {{ .name }}
-    # Only install {{ .name }} if it's not installed already
+    {{- if and .github_repository .version }}
+    # Apps with a pinned version number are downloaded from GitHub so we can
+    # update the pin with Renovatebot
+
+    # Get currently installed app version without using jq. Empty string if
+    # nothing is installed
+    # This counts on pipefail being off!
+    current_version=$(php occ app:list --output json | grep -o '"{{ .name }}":"[0-9]\+.[0-9]\+.[0-9]\+"' | grep -o '[0-9]\+.[0-9]\+.[0-9]\+' | cat)
+
+    if [ "$current_version" != "{{ .version }}" ]
+    then
+      echo "Upgrading app {{ .github_repository }} from '$current_version' to '{{ .version }}'"
+      # Where to install the app
+      target_directory="/var/www/html/custom_apps/{{ .name }}"
+      tmpdir=$(mktemp --directory)
+      cd $tmpdir
+      # We need to edit $ to be able to use `tpl` inside a `range`,
+      # see https://github.com/helm/helm/issues/5979#issuecomment-518231758
+      # allows us to use version variable in the release_filename
+      {{- $_ := set $ "version" .version}}
+      curl "https://github.com/{{ .github_repository }}/releases/download/v{{ .version }}/{{ tpl .release_filename $ }}" -Lo {{ .name }}.tar.gz
+      tar -xf {{ .name }}.tar.gz
+      # Remove old version of the app
+      if [[ -d $target_directory ]] 
+      then
+        rm -r $target_directory
+      fi
+      # Move app directory into target directory
+      mv {{ .name }} $target_directory
+      cd -
+      rm -r $tmpdir
+    else
+      echo "App {{ .name }} is up-to-date"
+    fi
+    {{- else }}
+    # Unpinned app
     if ! php $occ app:list | grep -q {{ .name }}; then
         php $occ app:install {{ .name }} --keep-disabled --no-interaction
+    else
+        # Update the app to its latest version
+        php $occ app:update --all --no-interaction
     fi
+    {{ end }}
     {{- if .enabled }}
     # Enable {{ .name }} app
     php $occ app:enable {{ .name }}
     {{ end }} # -- end {{ .name }}
     {{ end }} # end range {{ .Values.apps }}
 
+    # Some of the manually installed apps might need to run upgrade scripts, run
+    # them now
+    php $occ upgrade
+
     # Config settings from the configmap above
     php $occ config:import /var/local/onlyoffice-config.json
     php $occ config:app:set sociallogin custom_providers --value='{"custom_oidc": [{{ .Values.sociallogin.custom_oidc | toJson }}]}'
diff --git a/values-local.yaml.example b/values-local.yaml.example
index 070062e667ecb7464a8ea4683edf1fd4b2e04733..7b02ddb2e2653cc268e14a8d856d52782f8f1b93 100644
--- a/values-local.yaml.example
+++ b/values-local.yaml.example
@@ -66,6 +66,14 @@ rabbitmq:
 #     enabled: false
 #   - name: onlyoffice
 #     enabled: true
+#   - name: polls
+#     # Install an app from a github repository. This has the advantage that you
+#     # can pin the version number, so it does not get auto-updated to breaking
+#     # versions
+#     github_repository: nextcloud/polls
+#     version: 3.8.1
+#     release_filename: polls-.8.1.tar.gz
+#     enabled: true
 
 # sociallogin enables login via oAuth/Open-ID Connect
 # sociallogin:
diff --git a/values.yaml b/values.yaml
index 6a0dc0b2ebfab221cc8df9e88a9ff0ab31bfddd1..2aff044d77d8bc94f708e3e6e48b4d3a543ba10e 100644
--- a/values.yaml
+++ b/values.yaml
@@ -30,11 +30,21 @@ nextcloud:
     failureThreshold: 60
 
 apps:
-  # OIDC consumer
   - name: sociallogin
-    enabled: true
-  # List of applications that are installed *and enabled*
+    # apps[0].enabled needs to be set to true if you want to enable login via an external
+    # oauth server. In that case you need to configure all the values in `sociallogin`
+    enabled: false
+    # Line order is important here for renovatebot! first github_repository,
+    # then version
+    github_repository: zorn-v/nextcloud-social-login
+    version: 4.17.1
+    release_filename: release.tar.gz
   - name: onlyoffice
+    # Line order is important here for renovatebot! first github_repository,
+    # then version
+    github_repository: ONLYOFFICE/onlyoffice-nextcloud
+    version: 7.5.4
+    release_filename: onlyoffice.tar.gz
     enabled: true
 
 setupApps: