Symfony2, Vagrant, and Chef

If you are like me, I hate having a lot of extra stuff on my laptop such as
mysql, apache/nginx, etc. All those extra services are such a pain in the ass to
maintain and other developers may have different versions of the same things.
This can lead to issues during development and has the potential to cause issues
with your application when in production that cannot be reproduced.

# Assumptions

It is assumed that you have the following installed and working.

– [Symfony](http://symfony.com/doc/master/book/installation.html)
– [Vagrant](https://docs.vagrantup.com/v2/installation/index.html)
– [Chef and Berkshelf](https://downloads.chef.io/chef-dk/)
– [vagrant-berkshelf](http://berkshelf.com/) (See “Vagrant with Berkshelf” Section)

# Creating a chef-repo and an app Cookbook

You can read more about this process here
[https://docs.chef.io/chef/essentials_repository.html](https://docs.chef.io/chef/essentials_repository.html)
since this is not the full process. You are just wanting to get from point A to
point B quickly.

{% highlight bash %}
$ cd /path/to/symfony2
$ mkdir -vp app/chef-repo/cookbooks
mkdir: created directory ‘app/chef-repo’
mkdir: created directory ‘app/chef-repo/cookbooks’
$ berks cookbook app app/chef-repo/cookbooks/app
create app/chef-repo/cookbooks/app/files/default
create app/chef-repo/cookbooks/app/templates/default
create app/chef-repo/cookbooks/app/attributes
create app/chef-repo/cookbooks/app/libraries
create app/chef-repo/cookbooks/app/providers
create app/chef-repo/cookbooks/app/recipes
create app/chef-repo/cookbooks/app/resources
create app/chef-repo/cookbooks/app/recipes/default.rb
create app/chef-repo/cookbooks/app/metadata.rb
create app/chef-repo/cookbooks/app/LICENSE
create app/chef-repo/cookbooks/app/README.md
create app/chef-repo/cookbooks/app/CHANGELOG.md
create app/chef-repo/cookbooks/app/Berksfile
create app/chef-repo/cookbooks/app/Thorfile
create app/chef-repo/cookbooks/app/chefignore
create app/chef-repo/cookbooks/app/.gitignore
create app/chef-repo/cookbooks/app/Gemfile
create .kitchen.yml
append Thorfile
create test/integration/default
append .gitignore
append .gitignore
append Gemfile
append Gemfile
You must run `bundle install’ to fetch any new gems.
create app/chef-repo/cookbooks/app/Vagrantfile
{% endhighlight %}

You can commit all of this into your repository. If you plan to expand on this
and use more cookbooks or upload them to a chef server, you will need to do some
more work. This will just get you started in the right direction.

The `app` cookbook is only used locally to help provision you vagrant
machine(s).

Next we will need to modify the cookbook we created so it provisions the vagrant
machine correctly.

# Add Required Cookbooks

You will need to append these cookbooks to the metadata.rb file.

{% highlight ruby %}
# ./app/chef-repo/cookbooks/app/metadata.rb
depends ‘apache2’, ‘~> 3.0.0’
depends ‘apt’, ‘~> 2.6.0’
depends ‘database’, ‘~> 2.3.0’
depends ‘php’, ‘~> 1.5.0’
depends ‘postgresql’, ‘~> 3.4.14’
{% endhighlight %}

NOTE: You can swap out the postgresql cookbook with mysql, the reason I use
postgresql is because I deploy symfony 2 apps to heroku.

You can find other cookbooks by checking out the [Chef
Supermarket](https://supermarket.getchef.com/)

# Create a Template for Apache Vhost

{% highlight ruby %}
# ./app/chef-repo/cookbooks/app/templates/default/default.conf.erb
# -*- mode: apache -*-
# vi: set ft=apache :

#ServerName domain.tld
#ServerAlias www.domain.tld

DocumentRoot /var/www/web

# enable the .htaccess rewrites
AllowOverride All
Order allow,deny
Allow from All


{% endhighlight %}

You can see more about this on symfony’s web site; [Configuring a Web
Server](http://symfony.com/doc/master/cookbook/configuration/web_server_configuration.html)

# Create Your attributes File

{% highlight ruby %}
# ./app/chef-repo/cookbooks/app/attributes/default.rb
default[‘app’][‘dbname’] = ‘symfony’
default[‘app’][‘dbuser’] = ‘postgres’
{% endhighlight %}

The attributes file allows you modify things a little easier when deploying the
project to production or if you need to change a few settings.

# Modify Your default Recipe

{% highlight ruby %}
# ./app/chef-repo/cookbooks/app/recipes/default.rb
%w{git vim ruby-dev php5-curl php5-pgsql php5-xdebug libpq-dev}.each do |pkg|
package pkg do
action :upgrade
notifies :run, ‘execute[apt-get-update-periodic]’
end
end

# Apache
web_app ‘symfony’ do
template ‘default.conf.erb’
notifies :restart, ‘service[apache2]’
end

# Postgress
postgresql_connection_info = {
:host => ‘127.0.0.1’,
:username => node[‘app’][‘dbuser’],
:password => node[‘postgresql’][‘password’][‘postgres’]
}
file “/home/vagrant/.pgpass” do
content “#{node[‘postgresql’][‘config’][‘listen_address’]}:#{node[‘postgresql’][‘config’][‘port’]}:#{node[‘app’][‘dbname’]}:#{node[‘app’][‘dbuser’]}:#{node[‘postgresql’][‘password’][‘postgres’]}”
owner “vagrant”
group “vagrant”
mode ‘0600’
action :create
end
postgresql_database node[‘app’][‘dbname’] do
connection postgresql_connection_info
end
{% endhighlight %}

# Creating Your Berksfile

{% highlight ruby %}
# ./Berksfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
source “https://supermarket.getchef.com”
cookbook “app”, path: “app/chef-repo/cookbooks/app”
{% endhighlight %}

# Creating Your Vagrantfile

{% highlight ruby %}
# ./Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.require_version “>= 1.7.1”
Vagrant.configure(2) do |config|
config.berkshelf.enabled = true
config.vm.box = “ubuntu/trusty64”
config.vm.network “forwarded_port”, guest: 80, host: 8080
config.vm.network “private_network”, ip: “192.168.33.10”
config.vm.synced_folder “.”, “/var/www”, type: “nfs”
config.vm.provider “virtualbox” do |vb|
# Customize the amount of memory on the VM:
vb.memory = “1024”
end
config.push.define “heroku” do |push|
push.app = “”
end
config.vm.provision “shell”, inline: “sudo apt-get update”
config.vm.provision “chef_solo” do |chef|
chef.run_list = [
‘recipe[apt]’,
‘recipe‘,
‘recipe[database::postgresql]’,
‘recipe[postgresql::server]’,
‘recipe[postgresql::client]’,
‘recipe[apache2]’,
‘recipe[apache2::mod_php5]’,
‘recipe[apache2::mod_env]’,
‘recipe[apache2::mod_alias]’,
‘recipe[app]’,
]
chef.json = {
php: {
directives: {
expose_php: ‘Off’,
max_input_time: ‘-1’,
memory_limit: ‘-1’,
error_reporting: ‘E_ALL’,
display_errors: ‘On’,
post_max_size: ‘128M’,
upload_max_filesize: ‘128M’
}
},
apache: {
mpm: ‘prefork’,
docroot_dir: ‘/var/www/web’
},
postgresql: {
enable_pgdg_apt: true,
config: {
listen_addresses: ‘*’
},
password: {
postgres: ‘postgres’
}
}
}
end
end
{% endhighlight %}

# End

You should now be able to run `vagrant up` and then visit http://localhost:8080
in your browser. This should allow all developers on your team to work within
the exact same stack and will allow you to easily modify configuration settings
to how you want.

This guide should be basic enough to get you up and running. You may need to
modify some of the files to your liking or to configure some extras.