1

I've built a command in Symfony 4 which works fine when run from CLI but doesn't execute when run by cron. The console command is being run and no errors are thrown.

I've even thrown one in execute and it does not fail/error out:

public function execute(InputInterface $input, OutputInterface $output): void
{
    throw new \Exception('I am doing something');
}

My full command looks like this and is autowired:

<?php declare(strict_types = 1);

namespace CRMInterface\Command\Customer;

use CRMInterface\Service\Customer\CustomerSyncService;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class CustomerSyncCommand extends Command
{
    const COMMAND_NAME = 'crm:sync:customer';

    /**
     * @var CustomerSyncService
     */
    private $syncService;

    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * @param CustomerSyncService $syncService
     * @param LoggerInterface $logger
     */
    public function __construct(CustomerSyncService $syncService, LoggerInterface $logger)
    {
        parent::__construct(self::COMMAND_NAME);
        $this->syncService = $syncService;
        $this->logger = $logger;
    }

    protected function configure()
    {
        $this
            ->setName(self::COMMAND_NAME)
            ->setDescription('Processes outstanding portal sync tasks');
    }

    /**
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return void
     */
    public function execute(InputInterface $input, OutputInterface $output): void
    {
        $this->logger->info('Syncing customers...');
        try {
            $this->syncService->sync();
            $this->logger->info('Customer sync complete.');
        } catch (\Exception $e) {
            $this->logger->error('Customer sync failed: ' . $e->getMessage());
        }
    }
}

My cron job is as follows:

*/3 * * * * www-data cd /var/www/html && /usr/local/bin/php bin/console crm:sync:customer --env=prod

This set up works in a Symfony 3 app and a Symfony 2.8 app I have running but not with 4 and it's driving me batty.

My bin/console is as follows - I've taken out the stuff to do with APP_ENV because it was superfluous in my case and was failing due to the lack of env vars in cron.

#!/usr/bin/env php
<?php

use CRMInterface\Kernel;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Debug\Debug;

set_time_limit(0);

require __DIR__.'/../vendor/autoload.php';

if (!class_exists(Application::class)) {
    throw new \RuntimeException('You need to add "symfony/framework-bundle" as a Composer dependency.');
}

$input = new ArgvInput();
$env = $input->getParameterOption(['--env', '-e'], $_ENV['APP_ENV'] ?? 'dev');
$debug = ($_ENV['APP_DEBUG'] ?? ('prod' !== $env)) && !$input->hasParameterOption(['--no-debug', '']);

if ($debug) {
    umask(0000);

    if (class_exists(Debug::class)) {
        Debug::enable();
    }
}

$kernel = new Kernel($env, $debug);
$application = new Application($kernel);
$application->run($input);

Can anyone point me in the right direction as to why the command is running but not getting down to execute?

It's almost as if it's just running bin/console without the command... could it be something to do with lazy loading?

5
  • Does it run when you call bin/console crm:sync:customer --env=prod manually? Commented Oct 24, 2018 at 14:06
  • @Tomasz - yes - runs perfectly Commented Oct 24, 2018 at 14:08
  • You can grep syslog for cron errors, but I see that in the line of crontab you have (...) www-data cd && (...) I believe it's failing there because of undefined command Commented Oct 24, 2018 at 14:09
  • I would try to run cron task with: */3 * * * * /usr/local/bin/php /var/www/html/bin/console crm:sync:customer --env=prod Commented Oct 24, 2018 at 14:11
  • @Tomasz I set up syslog, but it just shows that it ran - no errors found. I also know that it's hitting the bin/console file ok as it's coming up in the monitoring. When I add a statement in that file to throw an exception if the command name is crm:sync:customer then that exception is thrown... Commented Oct 24, 2018 at 14:14

2 Answers 2

4

For those having similar issues with commands not making execution with no errors, check that cron has access to all the environment variables your application uses.

In this case, there was an exception that was thrown, but caught by the Symfony Application class. Environment variable not found: "ELASTICSEARCH_INDEX".. Unfortunately, it just continued on as if it had run. (May create an issue over at the repo).

For Docker on an Ubuntu based apache container, the solution was fairly simple - add a line in the entrypoint script to write the environment variables into the /etc/environment file:

FROM php:7.2
EXPOSE 80 443
CMD ["sh", "./.docker/run.sh"]

run.sh:

#!/usr/bin/env bash

printenv | grep -v "no_proxy" >> /etc/environment \
    && /etc/init.d/cron start \
    && apache2-foreground
Sign up to request clarification or add additional context in comments.

1 Comment

I cannot for the life of me reproduce it in a fresh project in order to create an issue about it so this seems quite edgy.
0

Similar to the previous answer, but make sure you add the cron job to the proper user.

Example: crontab -u www-data -e Edit the cron jobs by updating or adding

*/3 * * * * /usr/local/bin/php /var/www/html/bin/console crm:sync:customer --env=prod

You can add some testing on the command such as the following

0 * * * * if [ -f /var/www/html/bin/console ]; then /var/www/html/bin/console crm:sync:customer --env=prod >> /var/log/symfony/crm.log; else echo 'console not found'

/var/log/symfony/crm.log; fi >/dev/null 2>&1

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.