Very Siberian's picture

Hi, everyone. I recently learned that the cron job that ships with TKL WordPress (and perhaps other appliances) was not working for my sites. I learned this because I kept getting error messages ("You have some tasks that are overdue, etc.") and automatic updates were not being installed. "Surely, this cannot be correct," I thought. "TKL disables wp_cron by default, which makes sense for many reasons, but they use a system cron instead." 

All of that is true, but I was wrong. This is the default cron job:

/usr/bin/curl -A 'Mozilla/5.0' 'http://127.0.0.1/wp-cron.php' >/dev/null 2>&1

I went into Webmin and ran it manually, but I received no output. "Eh, that's not good," I thought. I checked my other sites, and they had the same problem.

Fortunately, the following worked for me, which is why I'm sharing it here in case it helps anyone else. You can keep everything the same in terms of the cron frequency, but delete the default cron job and use WP-CLI instead:

/usr/local/bin/wp --path=/var/www/wordpress cron event run --due-now

The above returns output when I run it manually, and I can confirm that it works perfectly on my live sites. Not sure what the deal is with that default cron job, but if you have issues with it, feel free to try the above alternative.

Best regards,

Very Siberian (Rob)

Forum: 
Jeremy Davis's picture

Hi Rob, thanks for reporting your issue. It certainly doesn't sound like it's working exactly as it should be, but I have a couple of thoughts.

Firstly, the command is intended to have no output (hence the '>/dev/null 2>&1' - that redirects all output to /dev/null which is basically a blackhole), so getting no output should be expected. By default cron jobs are generally configured to not provide output. Cron itself should let you know if/when cron jobs are failing (i.e. non-zero exit code). Do you have system emails set up? If so, your server should have been emailing you about the failed jobs! So my guess is either you don't or if you do, you're relying on the default direct emails. That would likely mean that they are getting flagged as spam.

Whilst no output from the command is expected, your other info (e.g. WP reporting "You have some tasks that are overdue, etc.") does suggest that it's not working as it should.

FWIW, the cron job we provide by default is what WordPress docs recommend. So it should certainly be working. However, there are a few reasons why it might not and my guess is that you are redirecting all traffic to https (and the cron job isn't set up to follow redirects) or perhaps you are redirecting traffic to your domain (and AFAIK the cron job only works via localhost/127.0.0.1)? Perhaps that is something we're doing that I haven't considered?

It sounds like you've worked around the issue which is great, but if you're interested in trying to work out what the original issue is/was, then I suggest manually running the command via the terminal, but with all output (no output redirection). I.e.:

/usr/bin/curl -A 'Mozilla/5.0' 'http://127.0.0.1/wp-cron.php'

That should give some indication of what might be going wrong with the default cron job.

Regardless, looking at your suggested cron job, leveraging wp-cli is probably not a bad idea (even though the default one should work, using wp-cli should be more robust). Having said that though, it might actually be best to run as the webserver user though, rather than as root?

We provide a wp-cli wrapper script that will run 'wp' commands as the webserver. You should be able to find it at /usr/local/bin/turnkey-wp. You don't need to use the '--path' switch either (unless you're using a non-standard path). If the cron job doesn't make any filesystem changes, then it doesn't really matter. But if it can change the filesystem, then I definitely recommend running as the webserver (unless of course if you have things locked down and owned by root by default).

Very Siberian's picture

Thanks, Jeremy! I ran the modified command as you suggested, and here is the output.

Output from command /usr/bin/curl -A 'Mozilla/5.0' 'http://127.0.0.1/wp-cron.php' ..

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100   237  100   237    0     0  33857      0 --:--:-- --:--:-- --:--:-- 33857
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://127.0.0.1/wp-cron.php">here</a>.</p>
</body></html>

Hence, it appears that your hypothesis was correct about the https redirection being an issue. I re-ran the command by changing http: to https: with the following result.

Output from command /usr/bin/curl -A 'Mozilla/5.0' 'https://127.0.0.1/wp-cron.php' ..

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
curl: (60) SSL: no alternative certificate subject name matches target host name '127.0.0.1'
More details here: https://curl.se/docs/sslcerts.html

curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.

So it looks like it may be an issue of mismatch between the localhost address and what's in the SSL certificate. Any suggestions would be welcome, but in any case, the WP-CLI workaround has me covered for now.

Finally, I would note that I first duplicated the cron job you all provide by default and then replaced it with the WP-CLI command I provided in the OP, so it's running under www-data, not root.

Best regards,

Rob

 

Jeremy Davis's picture

Don't get me wrong, using wp-cli is fine! And I may well follow your lead and replace the default cron job with one that leverages wp-cli.

I wasn't necessarily suggesting that you should change it back to using curl, I was just interested to hear more about it and understand what might be going wrong.

If you do want to get it to work, you can use curl's '--insecure' switch (so it will ignore unmatched certs).

FWIW, the unmatched cert is expected when connecting to localhost (hence why using plain http is the default). Because you can't get a legitimate certificate for 'localhost'!

But as I say, please feel free to continue using the wp-cli cron job that you've implemented.

Also thanks for the clarification re the cron job. I was under the impression that by default it was running as root. Thanks for clarifying that!

Add new comment