Skip to content

Goal: run recurring background work (Drupal cron, imports, cleanups) on a Cloud Platform environment, reliably and with output you can find later.

  • Drupal cron running on a schedule you chose, not on page-request luck.
  • Job output landing in a log file instead of silently filling the disk.
  • A Cloud Platform application, and either acli authenticated (CLI quickstart) or access to the Cloud Platform user interface
  • SSH access for testing commands before scheduling them
  1. Cloud Platform environments have a Scheduled Jobs feature: a command line plus a schedule, held per environment. Creating one is a single command:

    Terminal window
    acli api:environments:cron-create myapp.dev \
    '/var/www/html/${AH_SITE_NAME}/scripts/my-script.sh' \
    '25 7 * * *' 'Nightly cleanup'

    The three arguments after the environment are positional, in this order: the command to run, the cron frequency string, and the label the job is listed under. Single-quote the command so your own shell leaves ${AH_SITE_NAME} intact for the platform to expand at run time.

    The rest of the lifecycle is the same shape. acli api:environments:cron-job-list myapp.dev prints the environment’s jobs, each with the id that api:environments:cron-delete, api:environments:cron-enable, and api:environments:cron-disable take as their second argument. The environment’s Scheduled Jobs page in the Cloud UI has the same actions; see Using scheduled jobs on docs.acquia.com.

    Jobs are environment-specific by design; there is no “run on all environments” job. Once dev’s set is right, copy it rather than retyping it:

    Terminal window
    acli env:cron-copy myapp.dev myapp.prod

    That copies all of the source environment’s cron tasks to the destination, so tune dev to what production should run before you point it anywhere that matters.

    The platform’s constraints on the command line itself:

    • Maximum 255 characters. Anything longer goes into a shell script committed to your repository, and the job runs the script.
    • Use absolute paths everywhere; the job’s environment is minimal. The platform provides ${AH_SITE_NAME} to build them: /var/www/html/${AH_SITE_NAME}/docroot.
    • % is special in cron syntax; escape it as \%.

    For anything non-trivial, the script-in-repo pattern is the recommended one anyway: it’s version-controlled and its logging is controllable. Commit scripts/my-script.sh and schedule:

    /var/www/html/${AH_SITE_NAME}/scripts/my-script.sh
  2. Disable Drupal’s built-in automated cron

    Section titled “Disable Drupal’s built-in automated cron”

    Uninstall the Automated Cron module, or set Configuration > System > Cron > Run cron every to Never. Request-triggered cron runs on whatever traffic happens to arrive and ties up PHP processes mid-request; a scheduled job runs when you said it should.

  3. The command needs three things: the right docroot, the site URI, and a logging redirect:

    Terminal window
    drush --root=/var/www/html/${AH_SITE_NAME}/docroot --uri=https://www.example.com -d -v cron &>> /shared/logs/drush-cron.log
    • --uri matters: cron runs per site, and on a multisite codebase you schedule one job per site URI.
    • The &>> /shared/logs/... redirect is not optional politeness. Job output that isn’t redirected gets mailed to the application user on the box; unread mail accumulates until it fills the disk and takes the application down. Always redirect to a log file under /shared/logs.
    • /shared/logs files are not auto-rotated and must stay under 1 GB, so prune old logs periodically (that can be its own scheduled job).

    As written, the command is about 125 characters, comfortably inside the 255-character limit; committing it as a script (step 1) still pays, keeping it version-controlled with its logging adjustable in the script itself. Schedule the script:

    Terminal window
    acli api:environments:cron-create myapp.prod \
    '/var/www/html/${AH_SITE_NAME}/scripts/drush-cron.sh' \
    '25 7 * * *' 'Drupal cron'
  4. acli api:environments:cron-job-list myapp.prod confirms the job registered: each entry lists the stored command, the schedule split across minute, hour, day_month, month, and day_week, the label, and whether it is enabled. Scheduled-job STDOUT is captured in cronjob.log, downloadable from the environment’s Logs page; your own &>> redirect target has the rest. Before trusting a job to the scheduler, test the exact command over SSH first, from $HOME, so you’re testing in the same minimal environment the job gets.

The job didn’t run, or ran and failed

the triage steps are in diagnose a slow or erroring site.

The job dies partway through on memory

jobs created through the interface using Acquia’s cron wrapper run with your environment’s configured PHP memory limit (default 128 MB), while drush-triggered commands get the CLI limit of 512 MB. Running the work via drush instead of the wrapper is the platform’s own first suggestion.

The disk is filling up

look for un-redirected job output (mail spool) or unrotated logs in /shared/logs.

Was this page helpful?