Using CRON with Ubuntu and NextCloud 25.0.1

[details=“Support intro”]

Sorry to hear you’re facing problems :slightly_frowning_face:

help.nextcloud.com is for home/non-enterprise users. If you’re running a business, paid support can be accessed via portal.nextcloud.com where we can ensure your business keeps running smoothly.

The installation of NextCloud 25.0.1 into Ubuntu 22.04 went without any issues. However, in trying to clean-up security and optimize setup I have an issue with “backgroud jobs”.

Error when running default AJAX background job: Some jobs have not been executed since 20 hours ago. Please consider switching to system cron.

So I tried selecting “Cron”, but, it does not run. After looking thru the documentation it seems to depend on if you have “/systemd” or “cli”, etc.

For me the system configuration suggested creating two files nextcloudcron.service and nextcloudcron.timer. The NC docs recommend replacing www-data with my admin user name. Regardless, I tried both ways and nothing changes.

I always get some variation with cron of: Last job execution ran 13 minutes ago. Something seems wrong.

Cron is installed but I’m not clear on using “www-data” or “admin”. The two files now are the SERVICE:
[Unit]
Description=Nextcloud cron.php job

[Service]
User=admin
ExecStart=/usr/bin/php -f /var/www/nc/cron.php
KillMode=process

AND the TIMER:

[Unit]
Description=Run Nextcloud cron.php every minutes

[Timer]
OnBootSec=2min
OnUnitActiveSec=1min
Unit=nextcloudcron.service

[Install]
WantedBy=timers.target

I did increase the php.ini memory to 512 and 64, turned on opcache and cli is enabled.

I’m so confused about how to use this cron solution. Can anyone point me in a direction to use cron on a ubuntu 22.04 install?

Nextcloud version: 25.0.1
Operating system and version: Ubuntu 22.04
Apache: 'Apache/2.4.52 (Ubuntu) PHP version:8.1.6`
MySQL: ‘10.6.11’

The issue you are facing:
Backgound jobs no running correctly.

Is this the first time you’ve seen this error? (Y/N):N

Steps to replicate it:

  1. Install NC 25.0.1
  2. Set “Cron” or “AJAX” as backgroud job manager
  3. Fails within 5 minutes

The output of your Nextcloud log in Admin > Logging:

cron.php file|config.php file|

CRON.PHP…

<?php /** * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Artem Sidorenko * @author Christopher Schäpers * @author Christoph Wurst * @author Daniel Kesselberg * @author hoellen * @author J0WI * @author Jakob Sack * @author Joas Schilling * @author Jörn Friedrich Dreyer * @author Ko- * @author Michael Kuhn * @author Morris Jobke * @author Oliver Kohl D.Sc. * @author Robin Appelman * @author Roeland Jago Douma * @author Steffen Lindner * @author Thomas Müller * @author Vincent Petry * @author Stephen Michel * * @license AGPL-3.0 * * This code is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License, version 3, * along with this program. If not, see * */ require_once __DIR__ . '/lib/versioncheck.php'; try { require_once __DIR__ . '/lib/base.php'; if (\OCP\Util::needUpgrade()) { \OC::$server->getLogger()->debug('Update required, skipping cron', ['app' => 'cron']); exit; } if ((bool) \OC::$server->getSystemConfig()->getValue('maintenance', false)) { \OC::$server->getLogger()->debug('We are in maintenance mode, skipping cron', ['app' => 'cron']); exit; } // load all apps to get all api routes properly setup OC_App::loadApps(); \OC::$server->getSession()->close(); // initialize a dummy memory session $session = new \OC\Session\Memory(''); $cryptoWrapper = \OC::$server->getSessionCryptoWrapper(); $session = $cryptoWrapper->wrapSession($session); \OC::$server->setSession($session); $logger = \OC::$server->getLogger(); $config = \OC::$server->getConfig(); $tempManager = \OC::$server->getTempManager(); // Don't do anything if Nextcloud has not been installed if (!$config->getSystemValue('installed', false)) { exit(0); } $tempManager->cleanOld(); // Exit if background jobs are disabled! $appMode = $config->getAppValue('core', 'backgroundjobs_mode', 'ajax'); if ($appMode === 'none') { if (OC::$CLI) { echo 'Background Jobs are disabled!' . PHP_EOL; } else { OC_JSON::error(['data' => ['message' => 'Background jobs disabled!']]); } exit(1); } if (OC::$CLI) { // set to run indefinitely if needed if (strpos(@ini_get('disable_functions'), 'set_time_limit') === false) { @set_time_limit(0); } // the cron job must be executed with the right user if (!function_exists('posix_getuid')) { echo "The posix extensions are required - see https://www.php.net/manual/en/book.posix.php" . PHP_EOL; exit(1); } $user = posix_getuid(); $configUser = fileowner(OC::$configDir . 'config.php'); if ($user !== $configUser) { echo "Console has to be executed with the user that owns the file config/config.php" . PHP_EOL; echo "Current user id: " . $user . PHP_EOL; echo "Owner id of config.php: " . $configUser . PHP_EOL; exit(1); } // We call Nextcloud from the CLI (aka cron) if ($appMode !== 'cron') { $config->setAppValue('core', 'backgroundjobs_mode', 'cron'); } // Low-load hours $onlyTimeSensitive = false; $startHour = $config->getSystemValueInt('maintenance_window_start', 100); if ($startHour <= 23) { $date = new \DateTime('now', new \DateTimeZone('UTC')); $currentHour = (int) $date->format('G'); $endHour = $startHour + 4; if ($startHour <= 20) { // Start time: 01:00 // End time: 05:00 // Only run sensitive tasks when it's before the start or after the end $onlyTimeSensitive = $currentHour < $startHour || $currentHour > $endHour; } else { // Start time: 23:00 // End time: 03:00 $endHour -= 24; // Correct the end time from 27:00 to 03:00 // Only run sensitive tasks when it's after the end and before the start $onlyTimeSensitive = $currentHour > $endHour && $currentHour < $startHour; } } // Work $jobList = \OC::$server->getJobList(); // We only ask for jobs for 14 minutes, because after 5 minutes the next // system cron task should spawn and we want to have at most three // cron jobs running in parallel. $endTime = time() + 14 * 60; $executedJobs = []; while ($job = $jobList->getNext($onlyTimeSensitive)) { if (isset($executedJobs[$job->getId()])) { $jobList->unlockJob($job); break; } $logger->debug('CLI cron call has selected job with ID ' . strval($job->getId()), ['app' => 'cron']); $job->execute($jobList, $logger); // clean up after unclean jobs \OC_Util::tearDownFS(); $tempManager->clean(); $jobList->setLastJob($job); $executedJobs[$job->getId()] = true; unset($job); if (time() > $endTime) { break; } } } else { // We call cron.php from some website if ($appMode === 'cron') { // Cron is cron :-P OC_JSON::error(['data' => ['message' => 'Backgroundjobs are using system cron!']]); } else { // Work and success :-) $jobList = \OC::$server->getJobList(); $job = $jobList->getNext(); if ($job != null) { $logger->debug('WebCron call has selected job with ID ' . strval($job->getId()), ['app' => 'cron']); $job->execute($jobList, $logger); $jobList->setLastJob($job); } OC_JSON::success(); } } // Log the successful cron execution $config->setAppValue('core', 'lastcron', time()); exit(); } catch (Exception $ex) { \OC::$server->getLogger()->logException($ex, ['app' => 'cron']); echo $ex . PHP_EOL; exit(1); } catch (Error $ex) { \OC::$server->getLogger()->logException($ex, ['app' => 'cron']); echo $ex . PHP_EOL; exit(1); } ************************************************************************ Config.php... <?php $CONFIG = array ( 'instanceid' => 'xxx', 'passwordsalt' => 'xxx', 'secret' => 'xxx', 'trusted_domains' => array ( 0 => 'www.sheoki.com', ), 'datadirectory' => '/var/www/html/nc/data', 'dbtype' => 'mysql', 'version' => '25.0.1.1', 'overwrite.cli.url' => 'https://www.sheoki.com/nc', 'dbname' => 'nc', 'dbhost' => 'localhost:3306', 'dbport' => '', 'dbtableprefix' => 'oc_', 'mysql.utf8mb4' => true, 'dbuser' => 'nc22ad', 'dbpassword' => 'xxx', 'installed' => true, 'mail_smtpmode' => 'smtp', 'mail_smtpsecure' => 'tls', 'mail_sendmailmode' => 'smtp', 'mail_from_address' => 'info', 'mail_domain' => 'sheoki.com', 'mail_smtpauthtype' => 'LOGIN', 'mail_smtpauth' => 1, 'mail_smtphost' => 'smtp.ionos.com', 'mail_smtpport' => '587', 'mail_smtpname' => 'info@sheoki.com', 'mail_smtppassword' => 'xxx', 'default_phone_region' => 'US', 'app_install_overwrite' => array ( 0 => 'apporder', ), 'maintenance' => false, );

You need to put an entry in www-data’s crontab (or the main crontab running as www-data) to run cron.php with the php binary every 5 minutes.

If it’s executing correctly, the setting will change from AJAX to Cron automatically.

Did you read the documentation and have you tried the configuration examples it provides? On Ubuntu, they should actually work pretty much exactly as they are. Your SystemD config, however, deviates in several points from the documentation:

  • Wrong user, unless your installation / webserver is actually owned by the user “admin”,
  • OnBootSec=2min, OnUnitActiveSec=1min, instead of 5min as in the documentation.

Try to get it running with the default values before you start tuning it. Or just use cron as @KarlF12 suggested.

sudo -u www-data crontab -e

*/5 * * * * php8.1 -f /var/www/nextcloud/cron.php

Or full path your php executeable, and full path to the cron.php file in your nextcloud folder. Thats it.

Both methods (Cron and SystemD), are described in detail in the documentation and they do work on Ubuntu, if you are configuring them exactly as they are described in the documentation. (the path to the cron.php in the Nextcloud installation folder obviously needs to be adjusted)

If the examples in the docs do not work, the user has either changed something on the system, like running the webserver with a different user, installed multiple PHP versions etc…

However, All we know is that @donshepard has configured the systemd service differently from what is described in the documentation. Running it with the Nextcloud “admin” user is obviously not going to work, and also, running it every minute is probably too often, which could lead to issues.

Thanks for the quick feedback. I really want to get this fixed. I will give this a go but let me understand …

OK, so to be clear you’re suggesting to not use the complicated alternative approach with nextcloudcron.service and nextcloudcron.timer files in the /etc/systemd/system/ folder.

I delete those two files and ignore the NC documentation about “/systemd/system” option:

### systemd

If systemd is installed on the system, a systemd timer could be an alternative to a cronjob.

This approach requires two files: nextcloudcron.service and nextcloudcron.timer. Create these two files in /etc/systemd/system/.


Simply edit the cron table file with something like… [my NC is located at "/var/www/html/nc]:
*/5 * * * * php8.1 -f /var/www/html/nc/cron.php

image


NEXT: Don’t even select cron in the NC dministrative panel and cron will correct the NextCloud administration from AJAX to CRON!? Sweet!

Any thing else like restart the server or do a dance of hope and joy?

1 Like

restart shouldn’t be necessary, a dance of hope and joy won’t hurt probably. :wink:

Btw, I tried the SystemD variant and it works too. But I had to issue one more command, that isn’t mentioned in the documentation:

systemctl daemon-reload

Change CRON setting in administrator settings.
cron

Hmmm… NC is still running but not a positive change? Is my php8.1 not working correctly?

OK. So I added “*/5 * * * * php8.1 -f /var/www/html/nc/cron.php” to my cron table. Saved and exit. I opened again to confirm it is saved:
image

I did not change the NC Administrative setting for “Background”… left as default “AJAX”.

Waited for 10 minutes… no change. So I rebooted my server… no change. Waited… no change.

After a few more minutes I get “Last job ran 14 minutes ago. Something went wrong”:

I have not used cron before so it must be my ignorance. How do I confirm the cron job in the table is running correctly.

To review I’m using Ubuntu 22.04 on a VPS with IONOS provider. My NC is 25.0.1; php is 8.1.6; MySQL is 10.6.11. My server user is “root”. My NC user administration account is “admin”.

I’m missing something with “www-data”? Do I need to add “www-data” as a user in NC? Do I need to modify the “cron.php” file in NC?

My NC directory looks like this:
CRON.PHP Location:
image

My logs look like this:

session_start(): Ignoring session_start() because a session is already active at /var/www/html/nc/lib/private/Session/Internal.php#219

To which crontab? What was the exact command you were using, in order to open the crontab?
What’s the output of:

crontab -u www-data -l

www-data is the user the webserver (Apache or NGINX) is running as.

No

No, Don’t do that in any case!

OK. So my ignorance. So sorry. I have not used cron. Need to add a cron user specific to the job.

I used “crontab -e”. Clearly wrong.

So crontab is unique to a user!!! I did not understand and I appreciate your patience. So I need to make a user called “www-data” for cron. I’ll try to find the syntax… does this work on Ubuntu 22.04? I use nano. Is this another table or do u simple create the table with crontab command?

So to set the job I want for NextCloud with www-data I open with something like “crontab -u www-data -e”? [syntax?]. Then add the cron request “*/5 * * * * php8.1 -f /var/www/html/nc/cron.php”. Save. Now the cron module know which user and can find the cron.php from the location in the crontab for that user?

My setup is Apache2.

The return of “crontab -u www-data -1” is negative… no crontab for “www-data”:

Yes. Configure a cron as www-data to execute cron.php as you posted.

Yes you needs to configure Nextcloud in administrator settings to use system cron. However that is about it.

I also found this… should I make this “cron.allow.file” or does the syntax “crontab -u www-data -e” work just as well?

1 Like

IT WORKS!!!

1 Like

Assume! You guys are great. Power to NextCloud. I have other questions of the memcache but I’ll ask separately.

Now I do my dance of joy!

Fantastic support!!!


So the NextCloud background Cron job solution for me, in case anyone else is not proficient with LINUX, was to assign cron command to a specific user (www-data) by creation of a crontab command.

NextCloud is recommending CRON or AJAX. To implement for my Apache2 instance of NextCloud ( /var/www/html/nc ) was to get into my root using SolarPuTTY.

NEXT: create the cron job for user “www-data” [crontab -u www-data -e]
NEXT: add cron syntax to run every 5 minutes per cron.php at "/var/html/nc/cron.php " [*/5 * * * * php8.1 -f /var/www/nextcloud/cron.php]; Save, Exit
NEXT: goto NextCloud Administrative/Basic settings and select “Cron (recommended)”

No reboot or restart required.

The solution was stated at the first response by Kerasit:

2 Likes

This worked for me. I tried 2 clean Nextcloud installation and couldn’t get it to work with cron. Thank you so much.

Edit: I had to add the php version in the append this line to work properly. Just in case anyone is having some issues, try also this.