Automatically update Nextcloud automatically (Warning)

Dear All,

I have used ChatGPT and written code to automatically update Nextcloud as follows.

You can refer to and modify it according to your own situation.

Please note that you are responsible for any errors that may occur.

update_nextcloud_fn.php

the community strongly recommends to not using this script because its insecure and really dangerous. It could harm your server and lead to dataloss.
<?php
require 'PHPMailer/src/Exception.php';
require 'PHPMailer/src/PHPMailer.php';
require 'PHPMailer/src/SMTP.php';

use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;

function sendEmail($subject, $body, $to, $from) {
    $mail = new PHPMailer(true);
    try {
        // Server settings
        $mail->SMTPDebug = SMTP::DEBUG_OFF;
        $mail->isSMTP();
        $mail->Host = '';
        $mail->SMTPAuth = true;
        $mail->Username = '';
        $mail->Password = '';
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port = 587;

        // Recipients
        $mail->setFrom($from, '');
        $mail->addAddress($to);

        // Content
        $mail->isHTML(false);
        $mail->Subject = $subject;
        $mail->Body    = $body;

        // Email headers
        $mail->addCustomHeader('MIME-Version: 1.0');
        $mail->addCustomHeader('Content-Type: text/plain; charset=UTF-8');
        $mail->addCustomHeader('Content-Transfer-Encoding: 8bit');
       

        $mail->send();
        echo "Message sent successfully\n";
    } catch (Exception $e) {
        echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}\n";
    }
}

function getDomainFromConfigFile() {
    $configFilePath = '/var/www/nextcloud/config/config.php';
    if (file_exists($configFilePath)) {
        $config = include($configFilePath);
        if (isset($config['trusted_domains'][0])) {
            return $config['trusted_domains'][0];
        }
    }
    return null;
}

function getDomainFromNginxConfig() {
    $nginxConfigPath = '/etc/nginx/conf.d/nextcloud.conf';
    $domain = null;

    if (file_exists($nginxConfigPath)) {
        $configContent = file_get_contents($nginxConfigPath);
        $pattern = '/server_name\s+([\w.-]+);/';

        if (preg_match($pattern, $configContent, $matches)) {
            $domain = $matches[1];
        }
    }

    return $domain;
}

$bashScript = <<<BASH
#!/bin/bash

if [ ! -d "/var/www/old" ]; then
  mkdir /var/www/old
fi

# Download latest Nextcloud release
for i in {1..7}; do
  wget https://download.nextcloud.com/server/releases/latest.zip && break
  if [ \$i -eq 7 ]; then
    php -f /var/www/update_nextcloud_fn.php download_failed
    exit 1
  fi
  sleep 5
done

# Calculate the md5 checksum of both local and remote files
remote_md5=\$(md5sum latest.zip | awk '{print \$1}')
local_md5=\$(md5sum /var/www/old/latest.zip | awk '{print \$1}')

# Compare the md5 checksum
if [ "\$remote_md5" != "\$local_md5" ]; then
  # Rename the current version
  rm -rf /var/www/old_nextcloud
  mv /var/www/nextcloud /var/www/old_nextcloud

  # Unzip the latest version to the /var/www/ directory
  unzip latest.zip -d /var/www/

  # Remove the previous version
  rm /var/www/old/latest.zip

  # Store the new version
  mv latest.zip /var/www/old/

  # Remove the new version from the current directory
  rm latest.zip

  # Remove the new config files
  rm -rf /var/www/nextcloud/config/*

  # Copy the old config files
  cp -r /var/www/old_nextcloud/config/* /var/www/nextcloud/config/

  # Set the correct ownership and permissions
  restorecon -R '/var/www/nextcloud/'
  chown -R nginx:nginx /var/www/nextcloud/
  chown -R nginx:nginx /var/lib/php/{session,opcache}

  # Restart Nginx
  systemctl restart nginx

  # Upgrade Nextcloud
  sudo -u nginx php /var/www/nextcloud/occ upgrade

  # Send email notification if update is successful
  if [ \$? -eq 0 ]; then
    php -f /var/www/update_nextcloud_fn.php success
  fi
else
  echo "Nextcloud is already up to date"

  # Remove the downloaded file if it's not needed
  rm latest.zip

  # Set the correct ownership and permissions
  chown -R nginx:nginx /var/www/nextcloud/
  chown -R nginx:nginx /var/lib/php/{session,opcache}

  # Restart Nginx
  systemctl restart nginx
fi
BASH;

file_put_contents('update_nextcloud_2023.sh', $bashScript);
chmod('update_nextcloud_2023.sh', 0755);

if (isset($argv[1]) && $argv[1] === 'success') {
  $domain = getDomainFromConfigFile();
  if ($domain === null) {
    $domain = getDomainFromNginxConfig();
  }
  if ($domain === null) {
    echo "Could not find domain in Nextcloud or Nginx config files.\n";
    exit(1);
  }
  $subject = "Nextcloud has been updated";
  $body = "The Nextcloud update was successful on $domain.";
  $to = "";
  $from = "";
  sendEmail($subject, $body, $to, $from);
} elseif (isset($argv[1]) && $argv[1] === 'download_failed') {
  $subject = "Nextcloud update failed";
  $body = "Nextcloud update failed because the latest.zip file could not be downloaded after 7 attempts.";
  $to = "";
  $from = "";
  sendEmail($subject, $body, $to, $from);
}

Please configure crontab to run the update_nextcloud_2023.sh script daily.

Thank you sincerely,

The program has been working smoothly for me for several months now. However, anyone who is capable, please enhance it to make it even better.

Thank you sincerely,

Why on Earth would I want to do that?

If there’s an issue, if an app breaks, if the update fails in any way, I want to see it so I can fix it. I don’t want an update without my supervision.

If a transfer is in progress, or if a user is writing a note, the last thing they need is for Nextcloud to drop out to update. You’re just asking for trouble.

:face_with_raised_eyebrow:

You’re not filling me with confidence.

3 Likes

Thank you for your information.

I’m sharing the method that I am currently implementing. Who knows, someone might need it.

And of course, there will be people who do not need it.

That is normal.

I also make it clear that if someone finds the code inadequate, they can improve it.

I not only automatically update Nextcloud, but also everything like WordPress, Xenforo, Discourse, renew ssl etc. I have set them up for automatic updates.

The problem here isn’t so much that you want to do it automatically, but you’re making it cumbersome and extremely insecure. No database dump is created and no other backup either and that per cron. Your instance is not set into maintenance mode during the update. Steps are performed that are not needed at all! It looks like a typical chat-gpt mess.

Nextcloud comes with its own update script that you should use:

sudo chmod +x updater/updater.phar

updater/updater.phar --help
Description:
  Updates the code of an Nextcloud instance

Usage:
  update [options]

Options:
      --no-backup       Skip backup of current Nextcloud version
      --no-upgrade      Don't automatically run occ upgrade
  -h, --help            Display this help message
  -q, --quiet           Do not output any message
  -V, --version         Display this application version
      --ansi            Force ANSI output
      --no-ansi         Disable ANSI output
  -n, --no-interaction  Do not ask any interactive question
  -v|vv|vvv, --verbose  Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Help:
  This command fetches the latest code that is announced via the updater server and safely replaces the existing code with the new one.

This determines whether all requirements such as php version etc. are met and makes a backup in a secure way. You can do it without interaction (for your purpose) but i would never advice to do so.

You should do your updates on the console and create aliases for your automations, one for pre-update-steps (database dump and backup) and post-update-steps (fix all integrity tests, create missing indices, check if all services like notify_push etc. are up and runing)

Then you should never start using automations when you do not have created the revert script as well. So before I perform an update, I create the backup and with an other atomation I am able to revert everything to that snapshot-state, so that if something goes wrong, I am able to revert to my old state.

I am using my cloud server, because I want to get rid of oldschool mail. Why should I look in my mailserver for the results of an update?

As you hardly could oversee, I am not impressed by this script and I want to extremely discourage its use and will not give any support for those, who thought it might be a good idea to shoot in his own foot with it.

much luck!

6 Likes

I’m not so sure about that either, because I think it’s generally not a good idea to upgrade a production instance to a new major version on the first day after a release, and yes, you definitely shouldn’t do it without having a full backup.

4 Likes

Thank you for your feedback.

I hope that one day there will be a script or a secure and comprehensive method for automatically updating this from someone.

I just showed you, didn’t you see?
It already exists!

3 Likes

Thank you very much. So all I need to do is to run this command daily for it to automatically update, right?

sudo -u nginx php updater/updater.phar --quiet

Thank you for your assistance.

Thank you very much. I’ve updated.

your own words:

If you want to run this by an automation like cron, than you need the --no-interaction flag and not the --quiet flag, since you need the echoes for your logfile (or the mail you want to send) to know if it succeeded or not and if not, why.

Always wanting the latest version is a very bad strategy. Proper Windows mentality. In the server area, there are sometimes very specific versions that you want or need and therefore you should avoid automatic updates if possible.

Scripts for update yes, but never by daily cronjob.

much luck!

2 Likes

Thank you very much. I’m just trying to follow Nextcloud’s recommendations.

Privacy does not exist without security.

Our recommendation

We strongly recommend to keep a private cloud server constantly updated. Servers not running the latest security update in a supported release series are often vulnerable. You can find new versions here for Nextcloud and here for ownCloud. Nextcloud strives to make upgrading a safe, easy and painless procedure. As a result of these efforts, for users running PHP 7.x and a current version of Nextcloud, there is no need to re-enable apps upon upgrade and users get notified of new versions of apps as well. More improvements are coming! You can learn why and how to upgrade to the latest version of Nextcloud in our earlier blog.

We further recommend to read our Security Hardening Guide and follow the instructions there.

There is not mentioned, to run upgrades by cron without interaction!

You can perform a daily cronjob with this command:

occ update:check

and send the response-message to your mail or a pager of your choice (I use signal with signal-cli to get all important server messages on my mobile phone)

As soon as there is an update available, you are informed and can decide weather you want to apply it imediately or if you prefer to whait, until all your apps are supported or until a second bugfix release.

much luck!

3 Likes

Thank you very much.

Is there a way to send notifications via Telegram?

The system reports like this:

Then the updatenotification-App might be disabled on your instance. That is strange, because it is a shipped app, and it is enabled by default. So you must have disabled it somehow or it is broken because of your insecure update-procedure (if you have run it already).

   App-Id          updatenotification
   App-Name        Update notification
   Summary         Displays update notifications for Nextcloud and provides the SSO for the updater.
   Categories      monitoring
   App-Version     1.17.0
   Repository      https://github.com/nextcloud/server
   Issue-Tracker   https://github.com/nextcloud/server/issues
   NC min/max      27 / 27
                   Shipped (included), default enabled App
   Appstore-link   This app is currently not published in the Nextcloud app store.

Run

occ app:enable updatenotification

that should fix it.

Much luck

1 Like

Thank you very much. It worked like this:
Screenshot 2023-08-22 064409

@ernolf

(I use signal with signal-cli to get all important server messages on my mobile phone)

Could you please kindly guide me and everyone else on how to do this? Thank you sincerely.

I would like to refer to the link I gave here. There are all the necessary man-pages and even a WIKI with sample scripts.

Maybe I’ll do a how-to on occasion, but that’s not very Nextcloud related anymore.

Nextcloud has its own services that brings messages to your mobile phone about everything. Simply install the Nextcloud Android app and the “Nextcloud Services” app from the Droid Appstore. Then you can use the notification app (enabled by default) to send your server messages to the nextcloud notifications, which are then visible everywhere, in all clients.

Here is a thread where that is explained
and → this is a great example script ← from how it works. You can learn a lot from the latter.

Much luck!

1 Like