Wordpress Cron on Opsworks

Posted on Thu 27 August 2015 in aws

By default Wordpress uses it's own pseudo-cron which triggers with every request. Obviously this is wasteful since (a) the queue needs to be inspected with every GET and (b) jobs like publishing articles will interfere with serving content.

Some suggest calling the wp-cron.php GET request with curl in a cron like this

* * * * * curl http://www.mysite.com/wp-cron.php

but that's sub-optimal since it needlessly ties up a worker during the cron execution.

If you're using chef or Opsworks, here's a tidy way to install the system cron to execute without interfering with your webserver.

First, disable the Wordpress pseudo-cron by adding this to your wp-config.php.

$ grep CRON ./wp-config.php
define('DISABLE_WP_CRON', 'true');

Next, add this cron resource to your chef deploy/before_migrate.rb

# correct perms on app/storage
[release_path].each do |path|
    cron 'wp-cron' do
      # run every minute
      # prune & relay opsworks environment
      environment new_resource.environment.select {|key|
        ['APPLICATION_ENVIRONMENT','DB_HOST','DB_NAME','DB_USER', 'DB_PASSWORD'].include? key
      }
      action :create
      user 'www-data'
      command "php #{path}/wp-cron.php"
    end
end

Finally, shell into your instance to confirm that the cron was installed properly.

Notice the other nice part of this setup is that the cron is updated with each deployment--which means your cron will always be up-to-date.

$ sudo crontab -lu www-data
# Chef Name: wp-cron
APPLICATION_ENVIRONMENT=production
DB_HOST=XXXXX
DB_NAME=XXXXX
DB_USER=XXXXX
DB_PASSWORD=XXXXX
* * * * * php /srv/www/myapp/releases/20150827213430/wp-cron.php