CakePHP: Warum funktionieren Shells (bei gleichem Aufruf) nicht als Cronjob?

Shells lassen sich in CakePHP auch für den Aufruf aus Cronjobs verwenden. Dabei kann es jedoch vorkommen, dass der Aufruf einer Shell über das Terminal ohne Probleme funktioniert, aber im späteren Einsatz beim Aufruf über einen Cronjob nicht mehr so richtig will. Es hatte mich einiges an Zeit gekostet, herauszufinden warum dies passieren kann:

Mögliche Ursachen

Dass ein Cronjob nicht funktioniert, kann verschiedene Ursachen haben. Schaut man sich cake näher an, so liegen zunächst folgende Ursachen nahe:

  • cake nutzt einen falschen Pfad zu php (/usr/bin/php, /usr/...)
  • cake nutzt eine andere Version von php (bspw: CakePHP verwendet /usr/bin/php, cron verwendet: /usr/local/bin/php)

Der Grund für diese Ursachen sind meist unterschiedliche Umgebungsvariablen.

Nutzt man diese Variablen, um damit zusätzlich bestimmte Einstellungen in CakePHP vorzunehmen, so kann es schnell zu falschen Zuständen kommen, wenn die Inhalte dieser Variablen nicht definiert sind.

Warum unterschiedliche Umgebungsvariablen?

Wird eine Aktion durch einen Cronjob (wie in meinem Fall) nicht über einen GET-/POST-Request bzw. nicht in einer HTTP-Server-Umgebung aufgerufen, dann erhält man auch andere Umgebungsvariablen. Bei einem Nicht-HTTP-Request stehen einem beispielsweise nicht die HTTP-Variablen (z.B. HTTP_HOST, REQUEST_URI, …) zur Verfügung.

Lösungen

Nutzt man Umgebungsvariablen, um Einstellungen an der CakePHP-Umgebung vorzunehmen, dann sollte man auch den Fall berücksichtigen, dass diese Variablen nicht gesetzt sind.

Alternativ lässt sich eine Umgebungsvariable auch setzen. Verwendet man die im Cookbook (Running Shells as cronjobs) beschriebene Datei cakeshell, dann sollte diese um folgende Zeilen (möglichst vor den ersten Befehlen und mit der entsprechenden Variablen) erweitert werden:

HTTP_HOST=myserver.com
export HTTP_HOST

Umgehen kann man dies, wenn der Cronjob über eine URL definiert wird. Allerdings ist dann meist auch ein öffentlicher Zugriff möglich und damit die Aktion auch durch Suchmaschinen oder Benutzer aufrufbar.

Ein Beispiel für abweichende Umgebungsvariablen mit Folgen

Ein System wird auf zwei Domains verwendet, wobei eines das Testsystem und eines das öffentliche System ist. Beide nutzen die gleiche Datei Config/database.php, jedoch benötigen beide unterschiedliche Datenbankeinstellungen. Damit sich beim Abgleich beider Systeme nicht die Datenbankeinstellungen ändern, kann man über die Variable HTTP_HOST verschiedene Einstellungen (beispielsweise mit switch() { }) setzen lassen. Und hier wird es schwierig für Cronjobs: enthält die Umgebung des Cronjobs keine HTTP-Variablen, dann gibt es auch keine Datenbankverbindung.

Leave a Reply

Your email address will not be published. Required fields are marked *