WordPress Scheduled Events: wp-cron, wp-env, and password protected sites.
I prefer developing WordPress plugins using wp-env. It’s a great way to almost instantly set up a working WordPress environment using Docker. Check out my wp-env config file.
While developing a recent plugin I ran into the issue with wp-cron not firing at the scheduled time… and down the rabbit hole I went yesterday. Not too deep, but it still left me frustrated with one eye twitching.
Bottom line is that wp-env runs inside of a docker container, duh! Docker forwards the ports to make it accessible from outside of the container. Without the port forwarding, it would be difficult to access anything inside of the container from my regular developer space.
As we know, WordPress has settings for the local url of the site, so it can generate the links found throughout the site pointing my browser to the right ports on Docker.
However, wp-cron tries to use the same address as well, but from inside the container!! So while localhost:8888 works for my browser, it doesn’t work from inside of the container. So the wp-cron fails to fire.
This is how we get around this problem: we either use an external forwarding service like ngroks.com or we update our hosts file on our computer to point to the correct location. Yikes. Is there an easier way that we can simply include in our .wp-env.json? I haven’t found that yet. Here’s where I found the current solutions: https://github.com/WordPress/gutenberg/issues/20569
Now, there’s also the problem of using a password protected site to test the plugin. Which is what I ran into next. It’s like that. I run into one problem, and it stalks me. I need to get this figured out!
Again, since wp-cron uses a loopback to fire the functions… it fails when it hits the password protected url! Of course, this one has a much easier solution, a plugin: WP Cron HTTP Auth. Just install that on the site, enter the web page’s login credentials, and BOOM, wp-cron should fire correctly.
But what do you mean correctly? Ah, wp-cron is described in the WP Developer Handbook as firing events only when the site is visited. So if you’re like me, and you use cache plugins, Varnish, and a CDN… your visitors might not be loading the site in a way that triggers wp-cron!
If the timing is mission critical, DO NOT RELY ON WP-CRON ALONE! What you need to do is set up a scheduled task on the server. The page in the developer handbook describes how to do it for Linux, Mac, and Windows servers. The gist of it is that you want to hit /wp-cron.php on an appropriate schedule that meets your need. Every 15 minutes works for my purposes, but you might want something more frequent.