Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Full-Stack CakePHP Deployment

Full-Stack CakePHP Deployment

Deploying CakePHP applications using Capistrano and Chef. Covering both server - MySQL/nginx/php - and application deployment, as well as existing tools and usage examples.

Jose Diaz-Gonzalez

September 03, 2011
Tweet

More Decks by Jose Diaz-Gonzalez

Other Decks in Technology

Transcript

  1. ~WHOAMI • Jose Diaz-Gonzalez • Resident IRC Troll (savant) •

    Rants at http://josediazgonzalez.com • Harasses as @savant • Codes as josegonzalez on github • EMPLOYED at @seatgeek I’m also hot like sriracha sauce ➘ me ➘ not me
  2. WHO IS THIS TALK FOR? • Devs/Sysadmins not afraid of

    Ruby • Developers who don’t have time to waste with sysops • Sysadmins who are looking to automate more of their workflow Also anyone who couldn’t get into Mark’s talk
  3. WHY AM I SPEAKING ABOUT THIS? • I’m no Sysadmin;

    Sysadmining on half of the projects I’m on • Devs do servers wrong; Perhaps I do too • PHPNut Parole Policy (PPP) My Crime: The Patriot Ale House
  4. WHAT THE HELL IS THIS • Being lazy • Deploying

    a SERVAR • CHARGING LAYSHURS • What about the app? ¡¡¡SHOOP DA WOOP!!!
  5. • Geared towards automated deployments of workstations, not servers •

    Convergence implies we may never be within compliance • Community maintained packages? #  Every  policy  must  have  a  bundlesequence body  common  control { bundlesequence    =>  {  "test"  }; inputs  =>  {  "cfengine_stdlib.cf"  }; } bundle  agent  test { files: #  This  is  a  throw-­‐away  comment,  below  is  a  full-­‐bodied  promise  "/tmp/testfile"                                            #  promiser      comment  =>  "This  is  for  keeps...",  #  Live  comment        create  =>  "true",                                  #  Constraint  1          perms  =>  m("612");                              #  Constraint  2,  rw-­‐-­‐-­‐x-­‐ w-­‐ } I love it when an automation tool makes a promise
  6. MODULES AND CLASSES http://forge.puppetlabs.com/ #  ntp-­‐class1.pp class  ntp  {  

     case  $operatingsystem  {        centos,  redhat:  {              $service_name  =  'ntpd'            $conf_file        =  'ntp.conf.el'        }        debian,  ubuntu:  {              $service_name  =  'ntp'            $conf_file        =  'ntp.conf.debian'        }    }        package  {  'ntp':        ensure  =>  installed,    }        service  {  'ntp':        name            =>  $service_name,        ensure        =>  running,        enable        =>  true,        subscribe  =>  File['ntp.conf'],    }        file  {  'ntp.conf':        path        =>  '/etc/ntp.conf',        ensure    =>  file,        require  =>  Package['ntp'],        source    =>  "/root/learning-­‐manifests/${conf_file}",    } } Free beer to the first person to raise their hand
  7. WHY CHEF? • Uses a Ruby DSL; Doesn’t re-invent the

    wheel • Officially-sanctioned Cookbooks • Community-supported Cookbooks • All the cool rails developers are using it • Awesome logo • Screams when things are broken • Extensive Documentation And the obvious Chef/CakePHP pun
  8. HOW IS DEPLOYMENT FORMED? • Each server can have one

    or more cookbooks • Cookbooks are like plugins (nginx, apache, memcache) that can depend upon/require one another • Cookbooks have recipes, libraries, templates, definitions, files • Recipes are sets of instructions I vote we rename “plugins” to “recipes”
  9. git  "#{node[:server][:production][:dir]}/#{hostname}/#{base}/public"  do    repository  info[:repository]    user  "deploy"  

     group  "deploy" end ➘ ➘ resource name of resource options WHAT’S IN A RESOURCE CALL? http://wiki.opscode.com/display/chef/Resources ➘ special node var ➘
  10. ROLL YOUR OWN RESOURCES? Yo dawg, I hurd u liek

    yo yos so I gave yo dawg a yo yo so yo dawg can yo yo while yo dawg yo yos yo dawg yo
  11. #  Definition define  :nginx_up,  :enable  =>  true  do    template

     params[:name]  do        source  "html.erb"        owner  "deploy"        group  "deploy"        mode  0644        variables(params[:variables])    end    nginx_site  params[:hostname]  do        action  :enable    end end #  Usage nginx_up  "#{node[:nginx][:dir]}/sites-­‐available/#{hostname}.#{base}"  do    hostname  "#{info[:hostname]}.#{info[:base]}"    variables(info[:variables]) end “Fake” resources, for more info see http://wiki.opscode.com/display/chef/Providers Resources on the Cheap ➘ Just chain resources ➘ Fire at will
  12. node[:static_applications].each  do  |hostname,  sites|    sites.each  do  |base,  info|  

         directory  "#{node[:server][:production][:dir]}/#{hostname}/#{base}"  do                owner  "deploy"                group  "deploy"                mode  "0755"                recursive  true        end        git  "#{node[:server][:production][:dir]}/#{hostname}/#{base}/public"  do            repository  info[:repository]            user  "deploy"            group  "deploy"        end        nginx_up  "#{node[:nginx][:dir]}/sites-­‐available/#{hostname}.#{base}"  do            hostname  "#{hostname}.#{base}"            variables(info[:variables])        end    end end ALL TOGETHER NOW Simplified version of something in production use
  13. server  {    listen            

     80;    server_name    <%=  @subdomain  %><%=  @hostname  %>  www.<%=  @subdomain  %><%=  @hostname  %>;    root                  <%=  @root  %>;    index                index.html  index.htm;    error_page      500  501  502  503  504    /error_500.html;    charset            utf-­‐8;    access_log      <%=  @node[:nginx][:log_dir]  %>/<%=  @subdomain  %><%=  @hostname  %>-­‐access.log;    error_log        <%=  @node[:nginx][:log_dir]  %>/<%=  @subdomain  %><%=  @hostname  %>-­‐error.log;    #  remove  www  from  the  url    if  ($host  ~*  www\.(.*))  {        set  $host_without_www  $1;        rewrite  ^(.*)$  http://$host_without_www$1  permanent;    } } ^ FROM THIS ^ here it comes...
  14. server  {    listen            

     80;    server_name    areyousmokingcrack.com  www.areyousmokingcrack.com;    root                  /apps/production/areyousmokingcrack.com/default;    index                index.html  index.htm;    error_page      500  501  502  503  504    /error_500.html;    charset            utf-­‐8;    access_log      /var/log/nginx/areyousmokingcrack.com-­‐access.log;    error_log        /var/log/nginx/areyousmokingcrack.com-­‐error.log;    #  remove  www  from  the  url    if  ($host  ~*  www\.(.*))  {        set  $host_without_www  $1;        rewrite  ^(.*)$  http://$host_without_www$1  permanent;    } } ^ TO THIS ^ this site actually exists
  15. SERVER DNA • An instance is defined as a JSON

    DNA file • dna.json reference both recipes and configurations • Modifying DNA should reconfigure server • DNA can be versioned with the app You too can be a Geneticist
  16. BACK TO CAKE? • Define one set of cookbooks, use

    everywhere • Share, collaborate, grow optimized server cookbooks • Define servers in terms of DNA files: lb.json, db.json, web.json, etc. • Automate server deployment: • server new 127.0.0.1 lb.json • CakePHP http://bit.ly/cakechef Contributions welcome, documentation being fleshed out
  17. BASH • Usable everywhere • Easy to read/write • Everything

    is custom; Don’t be your own giant Have fun handling multiple server types
  18. ANT I’ll cut you So I put some RDFA in

    your XML so you can SPARQL while you parse
  19. CAPISTRANO • MOAR Ruby • Similar in concept to Chef

    - has deployment strategies • Separates related tasks into namespaces (deploy, migration, etc.) • Easy to extend and manipulate • Docs are a bit hazy at the moment • Geared towards SCM users http://capistranorb.com
  20. INSTALL • Install Ruby/RubyGems • gem install capistrano • cd

    path/to/local/app/repository • capify . the other 8 steps of the process involve alcohol
  21. CAPIFY? • “capify .” creates a Capfile and a config/deploy.rb

    file • deploy.rb is by convention; we can move the contents to the Capfile if it bothers you • Capfile is necessary and proper; loads capistrano plugins
  22. set  :application,  "set  your  application  name  here" set  :repository,  

     "set  your  repository  location  here" set  :scm,  :subversion #  Or:  `accurev`,  `bzr`,  `cvs`,  `darcs`,  `git`,  `mercurial`,  `perforce`,  `subversion`  or  `none` role  :web,  “your  web-­‐server  here”                                                    #  Your  HTTP  server,  Apache/etc role  :app,  “your  app-­‐server  here”                                                    #  This  may  be  the  same  as  your  `Web`  server role  :db,    “your  primary  db-­‐server  here”,  :primary  =>  true  #  This  is  where  Rails  migrations  will  run role  :db,    “your  slave  db-­‐server  here” ➘ ➘ ➘ ➘ <3 Perforce CakePHP is cool too Cause we’re all on failover servers, right? milliondollarapp.com deploy.rb
  23. CUSTOMIZABLE • Set your own SCM, deploy paths, even callbacks

    • Define custom namespaces and tasks • Override core functionality
  24. ENVIRONMENT HANDLING ##  Available  Environments task  :production  do    server

                               $config[“servers”][“prod”][“server”],  :web,  :god    set  :application,      $config[“servers”][“prod”][“application”]    set  :deploy_to,          $config[“servers”][“prod”][“deploy_to”]    set  :branch,                :master end task  :staging  do    role  :web,                    $config[“servers”][“dev”][“server”]    set  :application,      $config[“servers”][“dev”][“application”]    set  :deploy_to,          $config[“servers”][“dev”][“deploy_to”]    set  :branch,                ENV[‘branch’]  if  ENV.has_key?(‘branch’)  &&  ENV[‘branch’]  =~  /[\w_-­‐]+/i end
  25. CUSTOM TASKS ##  Tasks  involving  assets namespace  :asset  do  

     desc  "Clears  assets"    task  :clear  do        run  "cd  #{app_dir}  &&  ../cake/console/cake  -­‐app  #{app_dir}  asset_compress  clear"    end    desc  "Builds  all  assets"    task  :build  do        run  "cd  #{app_dir}  &&  ../cake/console/cake  -­‐app  #{app_dir}  asset_compress  build"    end    desc  "Builds  ini  assets"    task  :build_ini  do        run  "cd  #{app_dir}  &&  ../cake/console/cake  -­‐app  #{app_dir}  asset_compress  build_ini"    end    desc  "Rebuilds  assets"    task  :rebuild  do        run  "cd  #{app_dir}  &&  ../cake/console/cake  -­‐app  #{app_dir}  asset_compress  clear"        run  "cd  #{app_dir}  &&  ../cake/console/cake  -­‐app  #{app_dir}  asset_compress  build"    end end
  26. CAVEATS • Path to Cake Core may be incorrect -

    use -app flag • Takes some initial setup • Behaves funky with multiple concurrent deploys • Potentially slow with large deploys • Will murder your datacenter if deploying to hundreds of servers
  27. LINKS • CFEngine: • Puppet: http://puppetlabs.com • Chef: http://opscode.com/chef •

    CakePHP Chef Cookbooks: http://bit.ly/cakechef • Capistrano: http://capistranorb.com