Chef recipes for running Symfony apps on Opsworks
apache2::restart- Restart apache (important to clear the apc cache)
[:apache][:prefork][:maxrequestworkers]- Default is instance memory / 80Mb[:apache][:log_filter]- Array of{variable => regex}pairs to filter from logs, defaults:{'User-Agent' => 'ELB-HealthChecker'}{'User-Agent' => 'Amazon Route 53 Health Check Service'}{'Remote_Addr' => '127\.0\.0\.1'}
files:create- create files in the app directory from JSON (useful for key files etc)
go-composer- Install composer
logs::config- Create config file for CloudWatch logs (Must be done before the daemon is installed)logs::setup- Install CloudWatch daemonlogs::restart- Restart CloudWatch daemon
You will need to give your instances permission to access cloud watch logs, this IAM policy on your instance role should work
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:*"
],
"Resource": [
"arn:aws:logs:*:*:*"
]
}
]
}
[:logs][:apache]- enable sending apache logs to CloudWatch logs[:logs][:symfony]- enable sending symfony logs (prod and dev) to CloudWatch logs
metrics::setup- Setup the CloudWatch monitoring - will report disk usage stats
You will need to give your instances permission to access cloud watch, this IAM policy on your instance role should work
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Stmt1441183867000",
"Effect": "Allow",
"Action": [
"cloudwatch:PutMetricData"
],
"Resource": [
"*"
]
}
]
}
node::bower- Run bower install (bower should be installed using the package.json of the project)node::gulp- Runs gulp in the application dir (default task)node::npm- Runs npm install in the application dirnode::setup- Install nodejs/npm (With "legacy" support)
yarn::yarn- Runs yarn install in the application diryarn::setup- Install yarn
resque::config- Configure workers
supervisor::setup- Installs supervisorsupervisor::reload- Restart supervisor after a config change
symfony::assetic- assetic:dump --env=prodsymfony::cache- Clear the Symfony cachesymfony::composer- Run composer install in application dirsymfony::cron- Create cron jobs for the Symfony commands in JSONsymfony::daemon- Create supervisor daemons configs for the Symfony commands in JSONsymfony::ini- php.ini settingssymfony::logs- Link Symfony log files into the shared logs foldersymfony::migrate- Run doctrine migrationssymfony::parameters- Create the Symfony parameters files from JSONsymfony::permissions- Set permissions on logs and cache so that apache can write to themsymfony::setup- Install some common php packages
[:symfony][:ini]- PHP ini settings to add[:symfony][:console]- The location of the symfony console - change for Symfony 3+, default'app/console'[:symfony][:logs]- The location of the symfony logs dir - change for Symfony 3+, default'app/logs'[:symfony][:cache]- The location of the symfony cache dir - change for Symfony 3+, default'app/cache'[:symfony][:writable]- array of folders that should be writable by the web server - change for Symfony 3+, default['app/cache']{'User-Agent' => 'ELB-HealthChecker'}{'User-Agent' => 'Amazon Route 53 Health Check Service'}{'Remote_Addr' => '127\.0\.0\.1'}
slack::notify- Send a notification to the configured slack hook
[:slack][:hook]- The slack hook to send to[:slack][:channel]- Override the channel setting for the hook
telegraf::setup- Install telegraftelegraf::config- Configure telegraf
[:telegraf][:url]- The influxdb url to send metrics
The top key should match the application name in Opsworks
parameters- your Symfony parameters file - If a database is attached in Opsworks then the parametersdatabase_*will be set automatically.files- the name and content of any files you need to create, file names are relative to the project directory, or start with a /crons- the settings for cron jobs that you need to runcommand- the command and argumentssymfony- default true - means you are running a symfony command, it will be run inprodminute- cron format for the time to run at, default*hour- default*day- default*month- default*weekday- default*
daemons- the settings for daemons that you need to runcommand- the command and argumentssymfony- default true - means you are running a symfony command, it will be run inprodname- a name for your daemon to go in the confignumber- the number of processes to run, default1startretries- the number of times supervisor attemps to restart the process, default3
writable- array of directorys that should be writable by apacheresque- settings for resque - this section must exist for resque to be setup for this app. If this is set then parametersredis_host,redis_portandresque_queuewill be set in Symfonyworkers- number of worker, defaultnode['cpu']['total']queue- queue name, defaultdefault, multiple queues can be separated with a comma, and the order that they're supplied in is the order that they're checked in.bin- location of resque commands, defaultbin/resquescheduler- enable resque_scheduler, defaultfalsescheduler_bin- location of scheduler command, defaultbin/resque_schedulerredis.host- redis host name, defaultlocalhostredis.port- redis port, default6379app_include- defaults toapp/bootstrap.php.cacheto make sure annotations are loaded an improve load timeprefix- set the prefix for all redis keysinterval- how long, in seconds, to sleep between jobs, default5interval_scheduler- how long, in seconds, to sleep between checking for scheduled jobs, default5blocking- if true the worker uses BLPOP to wait for jobs, andintervalis the timeout, defaultfalse
aliases- a set of aliases that you want to setup in your virtual host
Sample:
{
"my_application": {
"parameters": {
"database_driver": "pdo_mysql",
"database_host": "db.app.com",
"database_name": "db_name",
"database_password": "db_pass",
"database_port": null,
"database_user": "db_user",
"custom_param": "my param",
"locale": "en",
"mailer_encryption": "tls",
"mailer_host": "email-smtp.eu-west-1.amazonaws.com",
"mailer_password": "smtp user secret",
"mailer_transport": "smtp",
"mailer_user": "smtp user key",
"router.request_context.host": "www.app.com",
"router.request_context.scheme": "https",
"secret": "Some symfony secret",
},
"files": {
"app/my secret file.pem": "-----BEGIN CERTIFICATE-----\nABCD...EF==\n-----END CERTIFICATE-----"
},
"crons": [
{
"name": "My regular command",
"command": "app:command",
"minute": "1"
}
],
"daemons": [
{
"command":"app:daemon-cmmand",
"name":"app-daemon"
}
],
"writable": [
"web/uploads"
],
"resque": {
"redis": {
"host": "localhost",
"port": 6379
},
"queue": "default",
"scheduler": true,
"prefix": "my_app"
},
"aliases": [{
"url_path": "/url",
"file_path": "/alternative/path"
}]
},
"thumbor": {
"key": "This-Is-A-Secret-Key",
"options": {
"ALLOW_UNSAFE_URL": false
}
},
"symfony": {
"ini": {
"upload_max_filesize": "2M"
}
},
"blackfire": {
"agent": {
"server_id": "your-server-id",
"server_token": "your-server-token"
}
},
"slack": {
"hook": "https://hooks.slack.com/..."
},
"telegraf": {
"url": "udp://influxdb:8089"
}
}
If built on the 'php app layer' settings:
go-composer symfony::setup node::setup logs::config logs::setup telegraf::setup metrics::setup blackfire
telegraf::config symfony::ini files::create symfony::parameters symfony::cache apache2::restart
symfony::logs logs::config logs::restart telegraf::config files::create symfony::parameters symfony::permissions node::npm node::bower node::gulp symfony::composer symfony::assetic symfony::migrate symfony::cache apache2::restart slack::deploy
If built on the 'custom layer' settings:
go-composer symfony::setup supervisor::setup logs::config logs::setup telegraf::setup metrics::setup blackfire
php::configure telegraf::config symfony::ini files::create symfony::parameters symfony::cache symfony::daemon resque::config supervisor::reload symfony::cron
deploy::php symfony::logs logs::config logs::restart telegraf::config files::create symfony::parameters symfony::permissions symfony::composer symfony::migrate symfony::cache symfony::daemon resque::config supervisor::reload symfony::cron slack::deploy
deploy::php-undeploy
If built on the 'custom layer' settings:
thumbor::default
So far I have tested a few receipes just using chef solo.
Create a solo.json with a run list and other data it requires
{
"run_list": [ "recipe[slack::deploy]" ],
"deploy": {
"x": {}
},
"slack": {
"hook": "https://hooks.slack.com/..."
}
}
run it
berks vendor cookbooks
chef-solo -c solo.rb -j solo.json