Hello everyone!

We have been investing plenty of personal time and energy for many years to share our knowledge with you all. However, we now need your help to keep this blog running. All you have to do is just click one of the adverts on the site, otherwise it will sadly be taken down due to hosting etc. costs. Thank you.

If your symfony application depends on cron jobs, you can edit crontab when deploying your application with capistrano. Follow example below to see how it can be done. In this example, we're going to create and run a symfony console command with cronjob every 1 minute. Command will just write logs into a log file.


Application


Crontab structure


Setup environment specific crontab files.


# Structure
app
config
crontab
production
staging

Cron jobs


# app/config/crontab/production
# Every minute
* * * * * cd /srv/www/football/current && php bin/console log:writer --message=Hello --iteration=2 --env=prod

# app/config/crontab/staging
# Every minute
* * * * * cd /srv/www/football/current && php bin/console log:writer --message=Hello --iteration=2 --env=stag

LogWriterCommand


namespace Football\FrontendBundle\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class LogWriterCommand extends Command
{
private $logPath;

public function __construct($logPath)
{
parent::__construct();

$this->logPath = $logPath;
}

protected function configure()
{
$this
->setName('log:writer')
->addOption('message', null, InputOption::VALUE_REQUIRED)
->addOption('iteration', null, InputOption::VALUE_REQUIRED);
}

protected function execute(InputInterface $input, OutputInterface $output)
{
for ($i = 1; $i <= $input->getOption('iteration'); $i++) {
file_put_contents(
$this->logPath,
sprintf('%d: %s', $i, $input->getOption('message')).PHP_EOL,
FILE_APPEND
);
}
}
}

services:
football_frontend.command.log_writer:
class: Football\FrontendBundle\Command\LogWriterCommand
tags:
- { name: console.command }
arguments:
- '%kernel.logs_dir%/%kernel.environment%.log'

Deployment


deploy.rb


# deploy/deploy.rb

set :cron_path, "#{fetch(:app_config_path)}/crontab/"+fetch(:stage).to_s
after "deploy:cleanup", "application:crontab:setup"

namespace :application do
namespace :crontab do
desc "Sets up crontab"
task :setup do
on roles (:app) do
puts "-" * 6
puts "Setting up crontab"
execute :crontab, "#{release_path}/#{fetch(:cron_path)}"
puts "-" * 6
end
end
end
end

Deploy


deploy:~# bundle exec cap staging deploy
...
------
Setting up crontab
00:09 application:crontab:setup
01 crontab /srv/www/football/releases/20170430201939/app/config/crontab/staging
✔ 01 deployer@192.168.99.40 0.012s
------
...

deploy:~# bundle exec cap production deploy
...
------
Setting up crontab
00:09 application:crontab:setup
01 crontab /srv/www/football/releases/20170430201939/app/config/crontab/staging
✔ 01 deployer@192.168.99.50 0.012s
------
...

Test


This is before you deploy your application.


staging:~#cat /srv/www/football/current/var/logs/stag.log
# Empty

staging:~# ls -l /var/spool/cron/crontabs/
total 0

This is after you deploying your application.


staging:~#cat /srv/www/football/current/var/logs/stag.log
1: Hello
2: Hello
1: Hello
2: Hello

staging:~# ls -l /var/spool/cron/crontabs/
-rw------- 1 deployer crontab 373 Apr 30 20:19 deployer

staging:~# crontab -e
# Every minute
* * * * * cd /srv/www/football/current && php bin/console log:writer --message=Hello --iteration=2 --env=stag