diff --git a/public_html/appmonitor/classes/appmonitor-client.class.php b/public_html/appmonitor/classes/appmonitor-client.class.php
index bdf70db9f076e640763f452baccb98471a1ed0e1..66def5a5d02705512751a93982d325823d7a35f3 100755
--- a/public_html/appmonitor/classes/appmonitor-client.class.php
+++ b/public_html/appmonitor/classes/appmonitor-client.class.php
@@ -42,8 +42,10 @@ if (!class_exists('appmonitorcheck')) {
  * 2020-05-03  0.110  axel.hahn@iml.unibe.ch  update renderHtmloutput<br>
  * 2023-07-06  0.128  axel.hahn@unibe.ch      update httpcontent check<br>
  * 2024-07-19  0.137  axel.hahn@unibe.ch      php 8 only: use typed variables
+ * 2024-11-22  0.141  axel.hahn@unibe.ch      Set client version to server version after updating http, mysqli and app checks
+ * 2025-01-02  0.149  axel.hahn@unibe.ch      add getChecks method
  * --------------------------------------------------------------------------------<br>
- * @version 0.137
+ * @version 0.149
  * @author Axel Hahn
  * @link TODO
  * @license GPL
@@ -57,7 +59,7 @@ class appmonitor
      * Name and Version number
      * @var string
      */
-    protected string $_sVersion = 'php-client-v0.137';
+    protected string $_sVersion = 'php-client-v0.149';
 
     /**
      * config: default ttl for server before requesting the client check again
@@ -402,6 +404,15 @@ class appmonitor
         die('<h1>503 Service Unavailable</h1>' . $sMessage);
     }
 
+    /**
+     * Get array with executed checks
+     * @return array
+     */
+    public function getChecks(): array
+    {
+        return $this->_aChecks;
+    }
+
     /**
      * Get full array for response with metadata and checks
      * @return array
diff --git a/public_html/appmonitor/git_update_appmonitor.sh b/public_html/appmonitor/git_update_appmonitor.sh
index 117d5084dc6473c2199cb3c23dcb070ba8e6462a..0426661154b1f446ce991eb2b4ad1a33894067d5 100755
--- a/public_html/appmonitor/git_update_appmonitor.sh
+++ b/public_html/appmonitor/git_update_appmonitor.sh
@@ -29,6 +29,9 @@
 # 2022-05-03  0.3  <axel.hahn@iml.unibe.ch>  create general_include.php
 # 2024-07-25  0.4  <axel.hahn@iml.unibe.ch>  update quoting and comments
 # 2024-07-31  0.5  <axel.hahn@iml.unibe.ch>  Show more helpful information; wait on 1st install; added param -n
+# 2024-12-23  0.6  <axel.hahn@iml.unibe.ch>  remove which command. Maybe it is not installed on a shared hoster.
+# 2024-12-26  0.7  <axel.hahn@iml.unibe.ch>  rsync test with --version instead of -V (for compatibility with older versions)
+# 2025-01-06  0.8  <axel.hahn@iml.unibe.ch>  git test with --version instead of -v (for compatibility with older versions)
 # ======================================================================
 
 # ----------------------------------------------------------------------
@@ -38,7 +41,7 @@
 readonly git_repo_url="https://github.com/iml-it/appmonitor.git"
 readonly docs_url="https://os-docs.iml.unibe.ch/appmonitor/PHP_client/index.html"
 readonly line="______________________________________________________________________________"
-readonly version="0.5"
+readonly version="0.8"
 
 git_target=/tmp/git_data__appmonitor
 client_from="${git_target}/public_html/client"
@@ -168,8 +171,11 @@ ENDOFHELP
         fi
 esac
 
-which rsync >/dev/null || exit 1
-which git >/dev/null || exit 1
+# which rsync >/dev/null || exit 1
+# which git >/dev/null || exit 1
+
+rsync --version >/dev/null || exit 1
+git --version >/dev/null || exit 1
 
 test -f general_include.php && isUpdate=1
 
@@ -221,6 +227,7 @@ rsync -rav \
     --exclude "example.json" \
     --exclude "check-appmonitor-server.php" \
     --exclude "local.php" \
+    --exclude "git_update_appmonitor.sh" \
     $client_from/* "$client_to"
 echo
 
@@ -260,5 +267,6 @@ echo "Documentation: $docs_url"
 echo
 echo $line
 echo done.
+cp -rp "$client_from/git_update_appmonitor.sh" "$client_to"
 
 # ----------------------------------------------------------------------
diff --git a/public_html/appmonitor/plugins/apps/concrete5.php b/public_html/appmonitor/plugins/apps/concrete5.php
new file mode 100644
index 0000000000000000000000000000000000000000..fa846205e0702f73170f7b9a0281071bb2578141
--- /dev/null
+++ b/public_html/appmonitor/plugins/apps/concrete5.php
@@ -0,0 +1,165 @@
+<?php
+/* ______________________________________________________________________
+ * 
+ * A P P M O N I T O R  ::  CLIENT - CHECK
+ * ______________________________________________________________________
+ * 
+ * Check for a Concrete5 instance.
+ * CMS https://www.concrete5.org/
+ * 
+ * It checks 
+ * - the write access to the config file
+ * - the write access to the file storage
+ * - connect to mysql database (which is read from config)
+ * - ssl certificate (on https request only)
+ * 
+ * @author: Axel Hahn - https://www.axel-hahn.de/
+ * ----------------------------------------------------------------------
+ * 2018-06-30  v1.0   ah
+ * 2019-05-24  v1.01  ah                   detect include or standalone mode
+ * 2024-11-18  v1.02  <axel.hahn@unibe.ch> integrate in appmonitor repository
+ * 2024-11-22  v1.03  <axel.hahn@unibe.ch> send 400 instead of 503 on error
+ * 2024-12-21  v1.04  ah                   short array syntax; add php-modules and parent
+ * 2025-01-06  v1.05  ah                   add df
+ */
+
+// ----------------------------------------------------------------------
+// Init
+// ----------------------------------------------------------------------
+
+$aAppDefaults = [
+    "name" => "Concrete5 CMS",
+    "tags" => ["concrete5", "cms"],
+    "df" => [
+        "warning" => "100MB",
+        "critical" => "10MB"
+    ]
+];
+
+require 'inc_appcheck_start.php';
+
+// ----------------------------------------------------------------------
+// Read Concrete5 specific config items
+// ----------------------------------------------------------------------
+
+
+$sConfigfile = $sApproot . '/application/config/database.php';
+if (!file_exists($sConfigfile)) {
+    header('HTTP/1.0 400 Bad request');
+    die('ERROR: Config file was not found. Use ?rel=[subdir] to set the correct subdir to find /application/config/database.php.');
+}
+
+$aConfig = include($sConfigfile);
+$sActive = $aConfig['default-connection'];
+
+if (!isset($aConfig['connections'][$sActive])) {
+    header('HTTP/1.0 400 Bad request');
+    die('ERROR: Config file application/config/database.php was read - but database connection could not be detected from it in connections -> ' . $sActive . '.');
+}
+// print_r($aConfig['connections'][$sActive]); die();
+$aDb = $aConfig['connections'][$sActive];
+
+// ----------------------------------------------------------------------
+// checks
+// ----------------------------------------------------------------------
+
+// required php modules
+// see https://documentation.concretecms.org/developers/introduction/system-requirements
+$oMonitor->addCheck(
+    [
+        "name" => "PHP modules",
+        "description" => "Check needed PHP modules",
+        // "group" => "folder",
+        "check" => [
+            "function" => "Phpmodules",
+            "params" => [
+                "required" => [
+                    "PDO",
+                    "curl",
+                    "dom",
+                    "fileinfo",
+                    "gd",
+                    "iconv",
+                    "mbstring",
+                    "pdo_mysql",
+                    "xml",
+                    "zip"
+                ],
+                "optional" => [],
+            ],
+        ],
+    ]
+);
+
+$oMonitor->addCheck(
+    [
+        "name" => "config file",
+        "description" => "The config file must be readable and writable",
+        "check" => [
+            "function" => "File",
+            "params" => [
+                "filename" => $sConfigfile,
+                "file" => true,
+                "readable" => true,
+                "writable" => true,
+            ],
+        ],
+    ]
+);
+$oMonitor->addCheck(
+    [
+        "name" => "check file storage",
+        "description" => "The file storage must be writable",
+        "check" => [
+            "function" => "File",
+            "params" => [
+                "filename" => "$sApproot/application/files",
+                "dir" => true,
+                "writable" => true,
+            ],
+        ],
+    ]
+);
+
+$sPdoConnectString = "mysql:host=$aDb[server];port=3306;dbname=$aDb[database];";
+
+$oMonitor->addCheck(
+    [
+        "name" => "Mysql Master",
+        "description" => "Connect mysql server " . $aDb['server'] . " as user " . $aDb['username'] . " to scheme " . $aDb['database'],
+        "parent" => "config file",
+        "check" => [
+            "function" => "PdoConnect",
+            "params" => [
+                "connect" => $sPdoConnectString,
+                "user" => $aDb['username'],
+                "password" => $aDb['password'],
+            ],
+        ],
+    ]
+);
+
+if (isset($aAppDefaults['df'])) {
+    
+    $oMonitor->addCheck(
+        [
+            "name" => "check disk space",
+            "description" => "The file storage must have some space left - warn: " . $aAppDefaults["df"]['warning'] . "/ critical: " . $aAppDefaults["df"]['critical'],
+            "parent" => "check file storage",
+            "check" => [
+                "function" => "Diskfree",
+                "params" => [
+                    "directory" => "$sApproot/application",
+                    "warning"   => $aAppDefaults["df"]['warning'],
+                    "critical"  => $aAppDefaults["df"]['critical'],
+                ],
+            ],
+        ]
+    );
+}
+
+// ----------------------------------------------------------------------
+
+require 'inc_appcheck_end.php';
+
+// ----------------------------------------------------------------------
diff --git a/public_html/appmonitor/plugins/apps/dokuwiki.php b/public_html/appmonitor/plugins/apps/dokuwiki.php
new file mode 100644
index 0000000000000000000000000000000000000000..c03f3a122b354f9a5f54cb8f563f94eeda27e2ed
--- /dev/null
+++ b/public_html/appmonitor/plugins/apps/dokuwiki.php
@@ -0,0 +1,150 @@
+<?php
+/* ______________________________________________________________________
+ * 
+ * A P P M O N I T O R  ::  CLIENT - CHECK
+ * ______________________________________________________________________
+ * 
+ * Check for a Dokuwiki instance.
+ * https://www.dokuwiki.org/
+ * 
+ * @author: Axel Hahn - https://www.axel-hahn.de/
+ * ----------------------------------------------------------------------
+ * 2024-12-23  v1.00  ah                   initial version
+ * 2024-12-26  v1.01  ah                   fix directory checks
+ * 2025-01-06  v1.02  ah                   add df
+ */
+
+// ----------------------------------------------------------------------
+// Init
+// ----------------------------------------------------------------------
+
+$aAppDefaults = [
+    "name" => "Dokuwiki",
+    "tags" => ["dokuwiki", "wiki"],
+    "df" => [
+        "warning" => "100MB",
+        "critical" => "10MB"
+    ]
+];
+
+require 'inc_appcheck_start.php';
+
+// ----------------------------------------------------------------------
+// Read Concrete5 specific config items
+// ----------------------------------------------------------------------
+
+$sConfigfile = "$sApproot/conf/local.php";
+if (!file_exists($sConfigfile)) {
+    header('HTTP/1.0 400 Bad request');
+    die('ERROR: Config file was not found. Use ?rel=[subdir] to set the correct subdir to find /conf/local.php.');
+}
+
+// ----------------------------------------------------------------------
+// checks
+// ----------------------------------------------------------------------
+
+// required php modules
+// see https://www.dokuwiki.org/install:php
+$oMonitor->addCheck(
+    [
+        "name" => "PHP modules",
+        "description" => "Check needed PHP modules",
+        // "group" => "folder",
+        "check" => [
+            "function" => "Phpmodules",
+            "params" => [
+                "required" => [
+                    "json",
+                    "pcre",
+                    "session",
+                ],
+                "optional" => [
+                    "bz2",
+                    "gd",
+                    "intl",
+                    "mbstring",
+                    "openssl",
+                    "zlib"
+                ],
+            ],
+        ],
+    ]
+);
+
+$oMonitor->addCheck(
+    [
+        "name" => "config file",
+        "description" => "The config file must be readable and writable",
+        "check" => [
+            "function" => "File",
+            "params" => [
+                "filename" => $sConfigfile,
+                "file" => true,
+                "readable" => true,
+                "writable" => true,
+            ],
+        ],
+    ]
+);
+
+foreach (['lib/tpl/', 'lib/plugins/',] as $sDir) {
+    $oMonitor->addCheck(
+        [
+            "name" => "check read dir $sDir",
+            "description" => "The directory $sDir must be readable",
+            "group" => "folder",
+            "check" => [
+                "function" => "File",
+                "params" => [
+                    "filename" => "$sApproot/$sDir",
+                    "dir" => true,
+                    "readable" => true,
+                ],
+            ],
+        ]
+    );
+}
+
+
+foreach (['data/attic', 'data/cache', 'data/index', 'data/locks', 'data/log', 'data/media', 'data/meta', 'data/pages', 'data/tmp',] as $sDir) {
+    $oMonitor->addCheck(
+        [
+            "name" => "check writable dir $sDir",
+            "description" => "The directory $sDir must be readable and writable",
+            "group" => "folder",
+            "check" => [
+                "function" => "File",
+                "params" => [
+                    "filename" => "$sApproot/$sDir",
+                    "dir" => true,
+                    "readable" => true,
+                    "writable" => true,
+                ],
+            ],
+        ]
+    );
+}
+
+if (isset($aAppDefaults['df'])) {
+    
+    $oMonitor->addCheck(
+        [
+            "name" => "check disk space",
+            "description" => "The file storage must have some space left - warn: " . $aAppDefaults["df"]['warning'] . "/ critical: " . $aAppDefaults["df"]['critical'],
+            "check" => [
+                "function" => "Diskfree",
+                "params" => [
+                    "directory" => "$sApproot/data",
+                    "warning"   => $aAppDefaults["df"]['warning'],
+                    "critical"  => $aAppDefaults["df"]['critical'],
+                ],
+            ],
+        ]
+    );
+}
+
+// ----------------------------------------------------------------------
+
+require 'inc_appcheck_end.php';
+
+// ----------------------------------------------------------------------
diff --git a/public_html/appmonitor/plugins/apps/iml-appmonitor-server.php b/public_html/appmonitor/plugins/apps/iml-appmonitor-server.php
index 01797f877e280adcc54f4d99812c930f8c18c112..87473021d5cbe8b47d9ac9de7b512f732e593636 100755
--- a/public_html/appmonitor/plugins/apps/iml-appmonitor-server.php
+++ b/public_html/appmonitor/plugins/apps/iml-appmonitor-server.php
@@ -13,12 +13,28 @@
  * 2021-11-nn  removed all checks ... created as single files
  * 2022-03-28  move checks into plugins/apps/
  * 2024-07-23  php 8: short array syntax
+ * 2024-12-28  added check for custom config and url file (if they exist)
  */
 
 // ----------------------------------------------------------------------
 // files and dirs
 // ----------------------------------------------------------------------
 
+$oMonitor->addCheck(
+    [
+        "name" => "PHP modules",
+        "description" => "Check needed PHP modules",
+        // "group" => "folder",
+        "check" => [
+            "function" => "Phpmodules",
+            "params" => [
+                "required" => ["curl"],
+                "optional" => [],
+            ],
+        ],
+    ]
+);
+
 $oMonitor->addCheck(
     [
         "name" => "write to ./tmp/",
@@ -49,48 +65,74 @@ $oMonitor->addCheck(
         ],
     ]
 );
+
 $oMonitor->addCheck(
     [
         "name" => "check config file",
-        "description" => "The config file must be writable",
+        "description" => "The default config file must be readable",
         "parent" => "write to ./config/",
         // "group" => "file",
         "check" => [
             "function" => "File",
             "params" => [
-                "filename" => "$sApproot/server/config/appmonitor-server-config.json",
+                "filename" => "$sApproot/server/config/appmonitor-server-config-defaults.json",
                 "file" => true,
-                "writable" => true,
+                "readable" => true,
             ],
         ],
     ]
 );
 
-$oMonitor->addCheck(
-    [
-        "name" => "PHP modules",
-        "description" => "Check needed PHP modules",
-        // "group" => "folder",
-        "check" => [
-            "function" => "Phpmodules",
-            "params" => [
-                "required" => ["curl"],
-                "optional" => [],
+if (is_file("$sApproot/server/config/appmonitor-server-config.json")) {
+    $oMonitor->addCheck(
+        [
+            "name" => "check custom config file",
+            "description" => "The custom config file must be readable and writable",
+            "parent" => "write to ./config/",
+            // "group" => "file",
+            "check" => [
+                "function" => "File",
+                "params" => [
+                    "filename" => "$sApproot/server/config/appmonitor-server-config.json",
+                    "file" => true,
+                    "readable" => true,
+                    "writable" => true,
+                ],
             ],
-        ],
-    ]
-);
+        ]
+    );        
+}
+
+if (is_file("$sApproot/server/config/appmonitor-server-urls.json")) {
+    $oMonitor->addCheck(
+        [
+            "name" => "check url file",
+            "description" => "The url config file must be readable and writable",
+            "parent" => "write to ./config/",
+            // "group" => "file",
+            "check" => [
+                "function" => "File",
+                "params" => [
+                    "filename" => "$sApproot/server/config/appmonitor-server-urls.json",
+                    "file" => true,
+                    "readable" => true,
+                    "writable" => true,
+                ],
+            ],
+        ]
+    );        
+}
 
 // ----------------------------------------------------------------------
 // protect dirs against web access
 // specialty: if the test results in an error, the total result switches
 // to WARNING -> see worstresult value
 // ----------------------------------------------------------------------
-$sBaseUrl = 'http'.(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] ? 's' : '')
-        .'://'.$_SERVER['SERVER_NAME'].':'.$_SERVER['SERVER_PORT']
-        .dirname(dirname($_SERVER['REQUEST_URI']));
+$sBaseUrl = 'http' . (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] ? 's' : '')
+    . '://' . $_SERVER['SERVER_NAME'] . ':' . $_SERVER['SERVER_PORT']
+    . dirname(dirname($_SERVER['REQUEST_URI']));
 
-foreach(['server/config', 'server/tmp'] as $sMyDir){
+foreach (['server/config', 'server/tmp'] as $sMyDir) {
     $oMonitor->addCheck(
         [
             "name" => "http to $sMyDir",
@@ -111,15 +153,15 @@ foreach(['server/config', 'server/tmp'] as $sMyDir){
 // ----------------------------------------------------------------------
 // count of current projects
 // ----------------------------------------------------------------------
-require_once($sApproot.'/server/classes/appmonitor-server.class.php');
-$oServer=new appmonitorserver();
-$iCount=count($oServer->getAppIds());
+require_once($sApproot . '/server/classes/appmonitor-server.class.php');
+$oServer = new appmonitorserver();
+$iCount = count($oServer->getAppIds());
 $oMonitor->addCheck(
     [
         "name" => "appcounter",
         "description" => "Monitored apps",
         "group" => "monitor",
-        "parent" => "check config file",
+        "parent" => false,
         "check" => [
             "function" => "Simple",
             "params" => [
@@ -134,11 +176,11 @@ $oMonitor->addCheck(
 // ----------------------------------------------------------------------
 // check running service
 // ----------------------------------------------------------------------
-require_once($sApproot.'/server/classes/tinyservice.class.php');
+require_once($sApproot . '/server/classes/tinyservice.class.php');
 ob_start();
 $oService = new tinyservice("$sApproot/server/service.php", 15, "$sApproot/server/tmp");
-$sIsStopped=$oService->canStart();
-$out=ob_get_contents();
+$sIsStopped = $oService->canStart();
+$out = ob_get_contents();
 ob_clean();
 $oMonitor->addCheck(
     [
@@ -149,13 +191,13 @@ $oMonitor->addCheck(
             "function" => "Simple",
             "params" => [
                 "result" => ($sIsStopped ? RESULT_WARNING : RESULT_OK),
-                "value" => ($sIsStopped 
-                    ? "Info: Service is NOT running. Apps are checked interactively only (if the appmonitor web ui is running). | Output: $out" 
+                "value" => ($sIsStopped
+                    ? "Info: Service is NOT running. Apps are checked interactively only (if the appmonitor web ui is running). | Output: $out"
                     : "OK, service is running. | Output: $out"
                 )
             ],
         ],
-        "worstresult" => RESULT_OK        
+        "worstresult" => RESULT_OK
     ]
 );
 // ----------------------------------------------------------------------
diff --git a/public_html/appmonitor/plugins/apps/inc_appcheck_end.php b/public_html/appmonitor/plugins/apps/inc_appcheck_end.php
index 5f958628cffe7fb80936cf50bc333c5e032b39e6..e939ed6d5c31046af8b140082395c6aec270ad85 100644
--- a/public_html/appmonitor/plugins/apps/inc_appcheck_end.php
+++ b/public_html/appmonitor/plugins/apps/inc_appcheck_end.php
@@ -5,9 +5,29 @@
  * ______________________________________________________________________
  */
 
+include 'shared_check_ssl.php';
+
 // $bStandalone was set in inc_appcheck_start.php
 // send response if client was not initialized there
-if($bStandalone){
+if ($bStandalone) {
+
+    if(count($oMonitor->getChecks())==0){
+
+        $oMonitor->addCheck(
+            [
+                "name" => "Simple",
+                "description" => "Welcome to a simple app check. This is just a quick winner.",
+                "check" => [
+                    "function" => "Simple",
+                    "params" => [
+                        "result" => RESULT_OK,
+                        "value" => "Create a custom check and add all checks you need to test the ability to run the application",
+                    ],
+                ],
+            ]
+        );
+    }
+
     $oMonitor->setResult();
     $oMonitor->render();
 }
diff --git a/public_html/appmonitor/plugins/apps/inc_appcheck_start.php b/public_html/appmonitor/plugins/apps/inc_appcheck_start.php
index 93e17e635c07e66aa8b2680cfb39e8d5738e3472..3218fc99bd70bff01a289fbf65af2b793cdf1a45 100644
--- a/public_html/appmonitor/plugins/apps/inc_appcheck_start.php
+++ b/public_html/appmonitor/plugins/apps/inc_appcheck_start.php
@@ -9,32 +9,54 @@
 // CHECK IF THE APPROOT IS SET
 // ----------------------------------------------------------------------
 
-if (!$sApproot) {
-    header('HTTP/1.0 503 Service Unavailable');
-    echo "<h1>503 Service Unavailable</h1>";
-    echo 'ERROR:'.PHP_EOL;
-    echo '$sApproot was not set. Define it before including the application check.'.PHP_EOL;
-    echo 'Set the base folder of your application installation.'.PHP_EOL;
-    echo PHP_EOL;
-    echo 'Example:'.PHP_EOL;
-    echo '$sApproot = $_SERVER[\'DOCUMENT_ROOT\'];'.PHP_EOL;
-    echo '$sApproot = $_SERVER[\'DOCUMENT_ROOT\'].\'/myapp\';'.PHP_EOL;
-    die();
-}
-
 // initialize client and set very basic metadata ... if needed
-$bStandalone=!(class_exists('appmonitor') && isset($oMonitor));
-if($bStandalone){
-    require_once(__DIR__.'/../../classes/appmonitor-client.class.php');
+$bStandalone = !(class_exists('appmonitor') && isset($oMonitor));
+if ($bStandalone) {
+    require_once __DIR__ . '/../../classes/appmonitor-client.class.php';
     $oMonitor = new appmonitor();
-    $oMonitor->setWebsite('Wordpress Instance');
 
-    @include __DIR__.'/../../general_include.php';
-}
+    if (!isset($sApproot) || empty($sApproot)) {
+        $sApproot = $_SERVER['DOCUMENT_ROOT'];
+        if (isset($_GET['rel'])) {
+            $sApproot .= str_replace('..', '__', $_GET['rel']);
+            if (!is_dir($sApproot)) {
+                header('HTTP/1.0 400 Bad request');
+                die('ERROR: The given rel dir does not exist below webroot.');
+            }
+        }
+    }
 
-// ----------------------------------------------------------------------
-// FUNCTIONS
-// ----------------------------------------------------------------------
+    // --- set values coming from app plugins defaults & GET params 
+    // "name"
+    // "host"
+    // "tags"    
+    // "dfw", "dfc"    
+    $aAppDefaults['name'] = (isset($_GET['name']) && $_GET['name']) ? $_GET['name'] : $aAppDefaults['name'];
+    $aAppDefaults['host'] = $_GET['host']
+        ? explode(',', $_GET['host'])
+        : ($_SERVER['HTTP_HOST'] ?? '');
+    $aAppDefaults['tags'] = $_GET['tags'] ? explode(',', $_GET['tags']) : $aAppDefaults['tags'];
+
+    $aAppDefaults['df']['warning'] = (isset($_GET['dfw']) && $_GET['dfw']) ? $_GET['dfw'] : $aAppDefaults['df']['warning'] ?? false;
+    $aAppDefaults['df']['critical'] = (isset($_GET['dfc']) && $_GET['dfc']) ? $_GET['dfc'] : $aAppDefaults['df']['critical'] ?? false;
+    if($aAppDefaults['df']['warning'] == false && $aAppDefaults['df']['critical'] == false) {
+        unset($aAppDefaults['df']);
+    }
 
+    if ($aAppDefaults['name']) {
+        $oMonitor->setWebsite($aAppDefaults['name']);
+    }
+    if ($aAppDefaults['host']) {
+        $oMonitor->setHost($aAppDefaults['host']);
+    }
+    ;
+    if (isset($aAppDefaults['tags']) && is_array($aAppDefaults['tags']) && count($aAppDefaults['tags']) > 0) {
+        foreach ($aAppDefaults['tags'] as $sTag) {
+            $oMonitor->addTag($sTag);
+        }
+    }
+
+    @include __DIR__ . '/../../general_include.php';
+}
 
 // ----------------------------------------------------------------------
diff --git a/public_html/appmonitor/plugins/apps/matomo.php b/public_html/appmonitor/plugins/apps/matomo.php
new file mode 100644
index 0000000000000000000000000000000000000000..3be9f6e55adf6b9da63800a8ced5977ec5f98c69
--- /dev/null
+++ b/public_html/appmonitor/plugins/apps/matomo.php
@@ -0,0 +1,156 @@
+<?php
+/* ______________________________________________________________________
+ * 
+ * A P P M O N I T O R  ::  CLIENT - CHECK
+ * ______________________________________________________________________
+ * 
+ * Check for a Matomo instance.
+ * Open Analytics platform - https://matomo.org/
+ * 
+ * It checks 
+ * - the write access to the config file
+ * - connect to matomo database (which is read from config)
+ * - ssl certificate (on https request only)
+ * 
+ * @author: Axel Hahn - https://www.axel-hahn.de/
+ * ----------------------------------------------------------------------
+ * 2018-06-30  v1.0
+ * 2019-05-24  v1.01  detect include or standalone mode
+ * 2019-05-24  v1.02  detect include or standalone mode
+ * 2024-12-20  v1.03  <axel.hahn@unibe.ch> integrate in appmonitor repository
+ * 2024-12-21  v1.04  ah                   add php-modules and parent
+ * 2025-01-06  v1.05  ah                   add checks for writable dirs; add df
+ */
+
+// ----------------------------------------------------------------------
+// Init
+// ----------------------------------------------------------------------
+
+$aAppDefaults = [
+    "name" => "Matomo web statistics",
+    "tags" => ["matomo", "statistics"],
+    "df" => [
+        "warning" => "100MB",
+        "critical" => "10MB"
+    ]
+];
+
+require 'inc_appcheck_start.php';
+
+// ----------------------------------------------------------------------
+// Read Matomo specific config items
+// ----------------------------------------------------------------------
+
+$sConfigfile = $sApproot . '/config/config.ini.php';
+if (!file_exists($sConfigfile)) {
+    header('HTTP/1.0 400 Bad request');
+    die('ERROR: Config file was not found. Set a correct $sApproot pointing to Matomo install dir.');
+}
+$aConfig = parse_ini_file($sConfigfile, true);
+
+
+// ----------------------------------------------------------------------
+// checks
+// ----------------------------------------------------------------------
+
+// required php modules
+// see https://matomo.org/faq/on-premise/matomo-requirements/
+$oMonitor->addCheck(
+    [
+        "name" => "PHP modules",
+        "description" => "Check needed PHP modules",
+        // "group" => "folder",
+        "check" => [
+            "function" => "Phpmodules",
+            "params" => [
+                "required" => [
+                    "PDO",
+                    "curl",
+                    "gd",
+                    "mbstring",
+                    "pdo_mysql",
+                    "xml",
+                ],
+                "optional" => [],
+            ],
+        ],
+    ]
+);
+
+$oMonitor->addCheck(
+    [
+        "name" => "config file",
+        "description" => "The config file must be readable and writable",
+        "check" => [
+            "function" => "File",
+            "params" => [
+                "filename" => $sConfigfile,
+                "file" => true,
+                "writable" => true,
+            ],
+        ],
+    ]
+);
+
+$oMonitor->addCheck(
+    [
+        "name" => "Mysql Connect",
+        "description" => "Connect mysql server " . $aConfig['database']['host'] . " as user " . $aConfig['database']['username'] . " to scheme " . $aConfig['database']['dbname'],
+        "parent" => "config file",
+        "check" => [
+            "function" => "MysqlConnect",
+            "params" => [
+                "server" => $aConfig['database']['host'],
+                "user" => $aConfig['database']['username'],
+                "password" => $aConfig['database']['password'],
+                "db" => $aConfig['database']['dbname'],
+            ],
+        ],
+    ]
+);
+
+
+// directory list from system check
+foreach (['/tmp', '/tmp/assets', '/tmp/cache', '/tmp/climulti', '/tmp/latest', '/tmp/logs', '/tmp/sessions', '/tmp/tcpdf', '/tmp/templates_c'] as $sDir) {
+    $oMonitor->addCheck(
+        [
+            "name" => "check writable dir $sDir",
+            "description" => "The directory $sDir must be readable and writable",
+            "group" => "folder",
+            "check" => [
+                "function" => "File",
+                "params" => [
+                    "filename" => "$sApproot/$sDir",
+                    "dir" => true,
+                    "readable" => true,
+                    "writable" => true,
+                ],
+            ],
+        ]
+    );
+}
+
+
+if (isset($aAppDefaults['df'])) {
+    
+    $oMonitor->addCheck(
+        [
+            "name" => "check disk space",
+            "description" => "The file storage must have some space left - warn: " . $aAppDefaults["df"]['warning'] . "/ critical: " . $aAppDefaults["df"]['critical'],
+            "check" => [
+                "function" => "Diskfree",
+                "params" => [
+                    "directory" => $sApproot,
+                    "warning"   => $aAppDefaults["df"]['warning'],
+                    "critical"  => $aAppDefaults["df"]['critical'],
+                ],
+            ],
+        ]
+    );
+}
+
+// ----------------------------------------------------------------------
+
+require 'inc_appcheck_end.php';
+
+// ----------------------------------------------------------------------
\ No newline at end of file
diff --git a/public_html/appmonitor/plugins/apps/nextcloud.php b/public_html/appmonitor/plugins/apps/nextcloud.php
new file mode 100644
index 0000000000000000000000000000000000000000..231fbb0ad95a459a0001c96c8d730e8e6b79bc99
--- /dev/null
+++ b/public_html/appmonitor/plugins/apps/nextcloud.php
@@ -0,0 +1,235 @@
+<?php
+/* ______________________________________________________________________
+ * 
+ * A P P M O N I T O R  ::  CLIENT - CHECK
+ * ______________________________________________________________________
+ * 
+ * Check for a Nextcloud instance.
+ * 
+ * It checks 
+ * - the read + write access to the config file
+ * - connect to database (which is read from config)
+ * - the read + write access to data dir
+ * - free disk space on data dir
+ * - ssl certificate (on https request only)
+ * 
+ * @author: Axel Hahn - https://www.axel-hahn.de/
+ * ----------------------------------------------------------------------
+ * 2025-01-02  v1.0
+ */
+
+// ----------------------------------------------------------------------
+// Init
+// ----------------------------------------------------------------------
+
+$aAppDefaults = [
+    "name" => "Nextcloud",
+    "tags" => ["nextcloud", "share"],
+    "df" => [
+        "warning" => "1GB",
+        "critical" => "100MB"
+    ]
+];
+
+require 'inc_appcheck_start.php';
+
+// ----------------------------------------------------------------------
+// Read Nextcloud specific config items
+// ----------------------------------------------------------------------
+
+$sConfigfile = "$sApproot/config/config.php";
+if (!file_exists($sConfigfile)) {
+    header('HTTP/1.0 400 Bad request');
+    die('ERROR: Config file was not found. Use ?rel=/NAME or similiar to set a relative install dir.');
+}
+
+if (!include "$sConfigfile") {
+    header('HTTP/1.0 400 Bad request');
+    die('ERROR: Unable to read config file.');
+}
+
+// now $CONFIG is available ...
+/*
+Array
+(
+    [instanceid] => ocw...
+    [passwordsalt] => cNs...
+    [secret] => kFdQXw2w...
+    [trusted_domains] => Array
+        (
+            [0] => https://www.example.com
+        )
+
+    [datadirectory] => /home/httpd/cloud/data
+    [dbtype] => mysql
+    [version] => 30.0.4.1
+    [overwrite.cli.url] => https://www.example.com/cloud
+    [dbname] => nextcloud
+    [dbhost] => 127.0.0.1
+    [dbport] => 
+    [dbtableprefix] => oc_
+    [mysql.utf8mb4] => 1
+    [dbuser] => mydbuser
+    [dbpassword] => 516px9kcc...
+    [installed] => 1
+    [maintenance] => 
+    [theme] => 
+    [loglevel] => 2
+    [mail_smtpmode] => smtp
+    [mail_sendmailmode] => smtp
+)
+*/
+
+if (!isset($CONFIG) || !is_array($CONFIG)) {
+    header('HTTP/1.0 400 Bad request');
+    die('ERROR: Config file was found but has unexpected format.');
+} 
+
+
+// ----------------------------------------------------------------------
+// checks
+// ----------------------------------------------------------------------
+
+// required php modules
+// see https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html
+// doesn't show needed modules
+/*
+$oMonitor->addCheck(
+    [
+        "name" => "PHP modules",
+        "description" => "Check needed PHP modules",
+        // "group" => "folder",
+        "check" => [
+            "function" => "Phpmodules",
+            "params" => [
+                "required" => [
+                    "PDO",
+                    "curl",
+                    "gd",
+                    "mbstring",
+                    "pdo_mysql",
+                    "xml",
+                ],
+                "optional" => [],
+            ],
+        ],
+    ]
+);
+*/
+
+$oMonitor->addCheck(
+    [
+        "name" => "config file",
+        "description" => "The config file must be readable and writable",
+        "check" => [
+            "function" => "File",
+            "params" => [
+                "filename" => $sConfigfile,
+                "file" => true,
+                "readable" => true,
+                "writable" => true,
+            ],
+        ],
+    ]
+);
+$oMonitor->addCheck(
+    [
+        "name" => "Version",
+        "description" => "Nextcloud version",
+        "parent" => "config file",
+        "check" => [
+            "function" => "Simple",
+            "params" => [
+                "result" => RESULT_OK,
+                "value" => $CONFIG['version'] ?? "??",
+                "count" => $CONFIG['version'] ?? "??",
+                "visual" => "simple"
+            ],
+        ],
+    ]
+);
+$oMonitor->addCheck(
+    [
+        "name" => "maintenance",
+        "description" => "Is maintenance mode enabled?",
+        "parent" => "config file",
+        "check" => [
+            "function" => "Simple",
+            "params" => [
+                "result" => $CONFIG['maintenance'] ? RESULT_ERROR : RESULT_OK,
+                "value" => $CONFIG['maintenance'] ? "enabled - public access is denied" : "disabled (OK)",
+            ],
+        ],
+    ]
+);
+
+// ----------------------------------------------------------------------
+// database
+// ----------------------------------------------------------------------
+
+if($CONFIG['dbtype'] == "mysql"){
+    $oMonitor->addCheck(
+        [
+            "name" => "Mysql Connect",
+            // "description" => "Connect mysql server " . $aConfig['database']['host'] . " as user " . $aConfig['database']['username'] . " to scheme " . $aConfig['database']['dbname'],
+            "description" => "Connect mysql server",
+            "parent" => "config file",
+            "check" => [
+                "function" => "MysqlConnect",
+                "params" => [
+                    "server" => $CONFIG['dbhost'],
+                    "user" => $CONFIG['dbuser'],
+                    "password" => $CONFIG['dbpassword'],
+                    "db" => $CONFIG['dbname'],
+                    "port" => $CONFIG['dbport'],
+                ],
+            ],
+        ]
+    );
+}
+
+// ----------------------------------------------------------------------
+// data directory
+// ----------------------------------------------------------------------
+
+$oMonitor->addCheck(
+    [
+        "name" => "data dir",
+        "description" => "Data directory must be readable and writable",
+        "parent" => "config file",
+        "check" => [
+            "function" => "File",
+            "params" => [
+                "filename" => $CONFIG['datadirectory'],
+                "dir" => true,
+                "readable" => true,
+                "writable" => true,
+            ],
+        ],
+    ]
+);
+
+if (isset($aAppDefaults['df'])) {
+    
+    $oMonitor->addCheck(
+        [
+            "name" => "check disk space",
+            "description" => "The file storage must have some space left - warn: " . $aAppDefaults["df"]['warning'] . "/ critical: " . $aAppDefaults["df"]['critical'],
+            "parent" => "data dir",
+            "check" => [
+                "function" => "Diskfree",
+                "params" => [
+                    "directory" => $CONFIG['datadirectory'],
+                    "warning"   => $aAppDefaults["df"]['warning'],
+                    "critical"  => $aAppDefaults["df"]['critical'],
+                ],
+            ],
+        ]
+    );
+}
+
+// ----------------------------------------------------------------------
+
+require 'inc_appcheck_end.php';
+
+// ----------------------------------------------------------------------
diff --git a/public_html/appmonitor/plugins/apps/shared_check_ssl.php b/public_html/appmonitor/plugins/apps/shared_check_ssl.php
index c2f45b778e14194367197b336351205646034ce9..c80a3b8da347af8e1d5eefe20dc2d6017c30e91a 100644
--- a/public_html/appmonitor/plugins/apps/shared_check_ssl.php
+++ b/public_html/appmonitor/plugins/apps/shared_check_ssl.php
@@ -18,7 +18,7 @@
 // ----------------------------------------------------------------------
 // check certificate - only if https is used
 // ----------------------------------------------------------------------
-if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']){
+if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) {
     $oMonitor->addCheck(
         [
             "name" => "Certificate check",
diff --git a/public_html/appmonitor/plugins/apps/wordpress.php b/public_html/appmonitor/plugins/apps/wordpress.php
index 711a15fcc7bbc64f564f95cd07c6e7e9cba9a643..1ac052034d32a09d01b14fc6dae2e730f79c2160 100644
--- a/public_html/appmonitor/plugins/apps/wordpress.php
+++ b/public_html/appmonitor/plugins/apps/wordpress.php
@@ -20,8 +20,24 @@
  * 2019-05-24  v0.02  detect include or standalone mode
  * 2019-05-24  v0.03  detect include or standalone mode
  * 2024-07-31  v0.04  first version for wordpress check in plugins/apps/ 
+ * 2024-11-21  v0.05  use shared_check_sl 
+ * 2024-11-22  v0.07  <axel.hahn@unibe.ch> send 400 instead of 503 on error
+ * 2024-12-21  v0.08  ah                   add php-modules and parent
+ * 2025-01-06  v1.05  ah                   add df
  */
 
+// ----------------------------------------------------------------------
+// Init
+// ----------------------------------------------------------------------
+
+$aAppDefaults = [
+    "name" => "Wordpress",
+    "tags" => ["wordpress", "blog"],
+    "df" => [
+        "warning" => "100MB",
+        "critical" => "10MB"
+    ]
+];
 
 require 'inc_appcheck_start.php';
 
@@ -31,23 +47,62 @@ require 'inc_appcheck_start.php';
 
 $sConfigfile = $sApproot . '/wp-config.php';
 if (!file_exists($sConfigfile)) {
-    header('HTTP/1.0 503 Service Unavailable');
-    die('ERROR: Config file [wp-config.php] was not found. Set a correct $sApproot pointing to wordpress install dir.');
+    header('HTTP/1.0 400 Bad request');
+    die('ERROR: Config file [wp-config.php] was not found. Set a correct app root pointing to wordpress install dir.');
 }
 
 require($sConfigfile);
-$aDb=[
-  'server'   => DB_HOST,
-  'username' => DB_USER,
-  'password' => DB_PASSWORD,
-  'database' => DB_NAME,
-  // 'port'     => ??,
-]; 
+$aDb = [
+    'server' => DB_HOST,
+    'username' => DB_USER,
+    'password' => DB_PASSWORD,
+    'database' => DB_NAME,
+    // 'port'     => ??,
+];
 
 // ----------------------------------------------------------------------
 // checks
 // ----------------------------------------------------------------------
 
+// required php modules
+// see https://ertano.com/required-php-modules-for-wordpress/
+$oMonitor->addCheck(
+    [
+        "name" => "PHP modules",
+        "description" => "Check needed PHP modules",
+        // "group" => "folder",
+        "check" => [
+            "function" => "Phpmodules",
+            "params" => [
+                "required" => [
+                    // "cmath",
+                    "cli",
+                    "curl",
+                    "date",
+                    "dom",
+                    "fileinfo",
+                    "filter",
+                    "gd",
+                    "gettext",
+                    "hash",
+                    "iconv",
+                    "imagick",
+                    "json",
+                    // "libsodium",
+                    "mysql",
+                    "openssl",
+                    "pcre",
+                    // "opcache",
+                    // "readline",
+                    "xml",
+                    "zip"
+                ],
+                "optional" => [],
+            ],
+        ],
+    ]
+);
+
 $oMonitor->addCheck(
     [
         "name" => "config file",
@@ -72,30 +127,34 @@ $oMonitor->addCheck(
         "check" => [
             "function" => "MysqlConnect",
             "params" => [
-                "server"   => $aDb['server'],
-                "user"     => $aDb['username'],
+                "server" => $aDb['server'],
+                "user" => $aDb['username'],
                 "password" => $aDb['password'],
-                "db"       => $aDb['database'],
+                "db" => $aDb['database'],
                 // "port"     => $aDb['port'],
             ],
         ],
     ]
 );
 
-if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']){
+if (isset($aAppDefaults['df'])) {
+    
     $oMonitor->addCheck(
         [
-            "name" => "Certificate check",
-            "description" => "Check if SSL cert is valid and does not expire soon",
+            "name" => "check disk space",
+            "description" => "The file storage must have some space left - warn: " . $aAppDefaults["df"]['warning'] . "/ critical: " . $aAppDefaults["df"]['critical'],
             "check" => [
-                "function" => "Cert",
+                "function" => "Diskfree",
+                "params" => [
+                    "directory" => "$sApproot",
+                    "warning"   => $aAppDefaults["df"]['warning'],
+                    "critical"  => $aAppDefaults["df"]['critical'],
+                ],
             ],
         ]
     );
 }
 
-// ----------------------------------------------------------------------
-
 require 'inc_appcheck_end.php';
 
 // ----------------------------------------------------------------------
diff --git a/public_html/appmonitor/plugins/checks/diskfree.php b/public_html/appmonitor/plugins/checks/diskfree.php
index f1d942849f73698c98493c5131451baf5891516b..86e8efc8d4f74547b9e1647074167e59cb3af206 100755
--- a/public_html/appmonitor/plugins/checks/diskfree.php
+++ b/public_html/appmonitor/plugins/checks/diskfree.php
@@ -19,7 +19,7 @@
  * 
  * 2021-10-26  <axel.hahn@iml.unibe.ch>
  * 2024-07-23  <axel.hahn@unibe.ch>      php 8 only: use typed variables
- * 
+ * 2025-01-02  <www.axel-hahn.de>        update output
  */
 class checkDiskfree extends appmonitorcheck
 {
@@ -58,7 +58,7 @@ class checkDiskfree extends appmonitorcheck
         $iCritical = $this->_getSize($aParams["critical"]);
         $iSpaceLeft = disk_free_space($sDirectory);
 
-        $sMessage = '[' . $sDirectory . '] has ' . $this->_getHrSize($iSpaceLeft) . ' left.';
+        $sMessage = $this->_getHrSize($iSpaceLeft) . ' left in [' . $sDirectory . '].';
 
         if ($iWarn) {
             if ($iWarn <= $iCritical) {
@@ -68,7 +68,7 @@ class checkDiskfree extends appmonitorcheck
             if ($iWarn < $iSpaceLeft) {
                 return [
                     RESULT_OK,
-                    "$sMessage Warning level is not reached yet (still " . $this->_getHrSize($iSpaceLeft - $iWarn) . "over warning limit)."
+                    "$sMessage Warning level is not reached yet (still " . $this->_getHrSize($iSpaceLeft - $iWarn) . " over warning limit)."
                 ];
             }
             if ($iWarn > $iSpaceLeft && $iCritical < $iSpaceLeft) {
diff --git a/public_html/appmonitor/plugins/checks/httpcontent.php b/public_html/appmonitor/plugins/checks/httpcontent.php
index 8655a067077af819ffd52480a65d5c725d608de8..3d981c54e7a34dcf29f9473681d7e2a2be8e950c 100755
--- a/public_html/appmonitor/plugins/checks/httpcontent.php
+++ b/public_html/appmonitor/plugins/checks/httpcontent.php
@@ -21,7 +21,7 @@
  * 2022-12-21  <axel.hahn@unibe.ch>      add flag sslverify
  * 2023-07-06  <axel.hahn@unibe.ch>      add flag userpwd
  * 2024-07-23  <axel.hahn@unibe.ch>      php 8 only: use typed variables
- * 
+ * 2024-11-22  <axel.hahn@unibe.ch>      Return unknown if curl module is not active
  */
 class checkHttpContent extends appmonitorcheck
 {
@@ -67,8 +67,7 @@ class checkHttpContent extends appmonitorcheck
     {
         $this->_checkArrayKeys($aParams, "url");
         if (!function_exists("curl_init")) {
-            header('HTTP/1.0 503 Service Unavailable');
-            die("ERROR: PHP CURL module is not installed.");
+            return [RESULT_UNKNOWN, "UNKNOWN: Unable to perform mysqli test. The php-curl module is not active."];
         }
         $bShowContent = (isset($aParams["content"]) && $aParams["content"]) ? true : false;
         $ch = curl_init($aParams["url"]);
diff --git a/public_html/appmonitor/plugins/checks/mysqlconnect.php b/public_html/appmonitor/plugins/checks/mysqlconnect.php
index d259ec001b3e4c7bb6723352e78ba08ae8c96fb0..5fe8a611cccb570bdd57475a915b11a9f16c96eb 100755
--- a/public_html/appmonitor/plugins/checks/mysqlconnect.php
+++ b/public_html/appmonitor/plugins/checks/mysqlconnect.php
@@ -19,7 +19,7 @@
  * 
  * 2021-10-27  <axel.hahn@iml.unibe.ch>
  * 2024-07-23  <axel.hahn@unibe.ch>      php 8 only: use typed variables
- * 
+ * 2024-11-22  <axel.hahn@unibe.ch>      detect installed mysqli function
  */
 class checkMysqlConnect extends appmonitorcheck
 {
@@ -48,6 +48,9 @@ class checkMysqlConnect extends appmonitorcheck
     public function run(array $aParams): array
     {
         $this->_checkArrayKeys($aParams, "server,user,password,db");
+        if (!function_exists("mysqli_init")) {
+            return [RESULT_UNKNOWN, "UNKNOWN: Unable to perform mysqli test. The php-mysqli module is not active."];
+        }
         $mysqli = mysqli_init();
         if (!$mysqli) {
             return [RESULT_ERROR, 'ERROR: mysqli_init failed.'];