2. Best Practices...
• Defining environments (Dev, Stage, Prod, etc)
• Smooth and Automated deployments
• Distributions and How to use them
• Useful development tools
Mike Potter
Software Architect @ Phase2
Email: mpotter@phase2technology.com
Drupal.org: mpotter
Friday, August 1, 14
3. Principles & Goals
• Create an easy-to-understand and simple codebase
• Know exactly what code is present in each environment
• Isolate developers to avoid stepping on toes
• Track contributed code and patches
• Automate putting desired code into an environment
• Automate putting desired configuration into an environment
• Test upcoming release code against latest production data/config
Friday, August 1, 14
5. Environments - DEVelopment
• One for each Individual developer
(whether Local, VMs, or via VHosts)
• Use git-flow branching strategy
• Put Everything into Code!
• Isolate Developers
Development
Integration
Staging / QA
Production
Friday, August 1, 14
6. Environments - INTegration
• “Integrates” all DEV environments
• Runs on “develop” branch
• First round of testing
• Automated or Manual rebuilding
Development
Integration
Staging / QA
Production
Friday, August 1, 14
7. Environments - QA (Staging)
• Contains Production Content
• Runs on “release” branches or tags
• Final testing ground
• Used to test hotfixes
• Essentially a copy of Production for the next release
Development
Integration
Staging / QA
Production
Friday, August 1, 14
8. Environments - PRODuction
• “Database of Record” for Content
• Runs on tagged “master” branch
• Should NEVER manually touch Production
• Use Hotfix process on QA for emergencies
Development
Integration
Staging / QA
Production
Friday, August 1, 14
10. Drupal
DB
Images, FilesPHP Code
Development
Integration / Staging
Production
GIT Repo
Code
Code
Images, Files
Images, Files
DB
Content
DB
Content
Configuration
Code
git commit
git push
git pull
Features
rsync
@prod >> @stage
rsync
@stage >> @dev
sql dump
sql restore
sql restore
branch: develop
branch: release
git pull
branch: master DB of Record
Code Files
Database
Content
• CODE is for Developers
• CONTENT is for Production
Friday, August 1, 14
11. Git Flow
• Each major feature has a branch
• Current release is “master”
• Next release is “develop”
• http://github.com/nvie/gitflow
provides easy git commands
• git flow feature start <name>
git flow feature publish <name>
http://nvie.com/posts/a-successful-git-branching-model/
Friday, August 1, 14
12. Everything in Code
• Use Features module to export configuration
http://drupal.org/project/features
• Keep it modular! (don’t put everything into one feature)
• Use Features Override module to export site-specific changes
(when using a base distribution)
• Use update-hooks for anything else
(custom hook_update functions in code)
Friday, August 1, 14
13. Features Strategies
• In general, more, smaller Features is better
• Group by functionality, such as configuration related to a
specific content type
• Keep stuff that is often changed (permissions) separate
from configuration that doesn’t change (fields)
Friday, August 1, 14
14. Good Feature
gallery (content type)
main_image (field)
gallery_thumbnail (image style)
gallery_view (view)
Bad Feature
gallery_view (view)
content_view (view)
event_view (view)
news_view (view)
user_view (view)
Friday, August 1, 14
15. Use Update Hooks
• Enable/disable modules
• Update database
• Revert features
(if not using drush fra)
Friday, August 1, 14
16. Automated Deployment
• Use drush command line tool
• Pull code (git fetch, git checkout branch/tag)
• Rsync files @prod >> @stage (*)
• Run updates (drush updb)
• Revert all features (drush fra -y)
• Clear cache (drush cc all)
• (*) See also the Stage File Proxy module
Friday, August 1, 14
17. Tools for Continuous Integration
• Open Source : Jenkins, CruiseControl
• Commercial : Bamboo (Atlassian)
• Create jobs to execute automated scripts
• Run job automatically when code changes
Friday, August 1, 14
19. Distributions & Profiles
• A Distribution is:
A full copy of Drupal core along with additional modules, themes, and
installation profiles
• A Profile is:
A set of installation instructions
https://www.drupal.org/node/1022020
• Drupal searches in /sites before /profiles
Friday, August 1, 14
20. Why use Profiles?
• Easily separate common code from site-specific code
• Documents exact module dependencies and patches
(stops you from hacking core)
• Easier to control module updates
• Can build upon other profiles (*)
• Can be more of a “drush make” wrapper rather than
something actually “installed”
Friday, August 1, 14
21. Module search order
• Drupal searches for modules in this order:
/sites/sitename/modules (for multisites)
/sites/default/modules
/sites/all/modules
/profiles/ProfileName/modules
/profiles/BaseProfileName/modules (if using a base profile)
/modules
• Modules from your Profile are kept separate from
site-specific module overrides
Friday, August 1, 14
22. Building your own Install Profile
• ProfileName.info
Defines the dependencies (other modules)
• ProfileName.profile
Can add steps to the installer, or just have an empty
ProfileName_install() hook function
• ProfileName.make
Defines the specific versions and patches for modules
Friday, August 1, 14
23. ProfileName.info file
• Same as Module.info files
• Determines what modules are
enabled when profile installed
• Can contain:
base[] = BaseProfileName
to build on another profile
when using this patch:
http://drupal.org/files/1356276-make-D7-21.patch
name = Profile Name
description = Description of what the profile does.
core = 7.x
dependencies[] = block
dependencies[] = color
dependencies[] = comment
dependencies[] = contextual
dependencies[] = dashboard
dependencies[] = help
dependencies[] = image
dependencies[] = list
dependencies[] = menu
dependencies[] = number
dependencies[] = options
dependencies[] = path
dependencies[] = taxonomy
dependencies[] = dblog
dependencies[] = search
dependencies[] = shortcut
dependencies[] = toolbar
dependencies[] = overlay
dependencies[] = field_ui
dependencies[] = file
dependencies[] = rdf
Friday, August 1, 14
24. ProfileName.profile File
• Can add steps to installer
• Return empty array for default
<?php
/**
* Implements hook_install_tasks().
*/
function PROFILENAME_tasks($install_state) {
$tasks = array();
return $tasks;
}
?>
Friday, August 1, 14
25. Profile Make files
• Controls what modules are downloaded when built
• Three make files:
drupal-org-core.make (contains Drupal Core)
drupal-org.make (contains everything else)
build-profile.make (references the other two)
• Allows you to build a Distribution from your Profile
using “drush make”
Friday, August 1, 14
29. Building using Drush Make
• Pull your latest profile into temp directory
• Run drush:
drush make
--prepare-install
--contrib-destination=profiles/ProfileName
ProfileLocation/build-profile.make
DestinationDir
• Example:
git clone git@myProfileRepository.git
drush make --prepare-install --contrib-destination=profiles/myprofile
myProfileRepository/build-myprofile.make /var/www/mysite
• Will download modules, patch, etc
(ProfileLocation)
Friday, August 1, 14
30. Merge the distribution
• Use rsync to merge your profile
distribution with what
“drush make” installed
rsync -r
ProfileLocation/
DestinationDir/profiles/profileName/
• Then just go to
http://mysite/install.php to install
Profile
Drush Make
Full Drupal Site
Friday, August 1, 14
31. Automated Building
• You only need to run install.php ONCE to set up your initial site
• For future changes (e.g. via Jenkins),
• This will delete DestDir (drupal root) and recreate your entire site!
cd ProfileLocation
git checkout develop
git pull origin develop
mv DestDir/sites /tmp/sites
drush make --contrib-destination=profiles/myprofile build-profile.make DestDir
rsync -r ProfileLocation/ DestDir/profiles/myprofile
mv /tmp/sites DestDir/sites
cd DestDir
drush updb
drush fra -y
drush cc all
Friday, August 1, 14
32. “Fake” profiles
• Install Drupal normally
• Use “drush make” to create files in profiles/profileName
• Tell Drupal you installed with a profile:
drush vset install_profile profileName
• Now Drupal will look in profiles/profileName for modules
• Don’t need profileName.profile or profileName.install files
• profileName.info can be a “stub” file
(ADVANCED)
Friday, August 1, 14
33. Why use Profiles? (revisited)
• Easily separate common code from site-specific code
• Documents exact module dependencies and patches
(via drush make files)
• Easier to control module updates
• Can build upon other profiles (*)
Friday, August 1, 14
35. Making DEV like PROD
• Development environment often doesn’t match
configuration of Production environment:
• PROD has caching (Varnish, etc)
• OS Differences (PROD on Linux, DEV on Mac)
• Version consistency of Apache, PHP, MySQL, etc
• Configuration consistency
Friday, August 1, 14
36. Virtual Machines (VM)
• VirtualBox (free), VMware, etc
• Allows you to run a completely separate machine within your
own computer
• Can create a separate VM for each client project
• Works on PC, Mac, Linux
• Can take a while to configure
• Can use a lot of resources (memory, disk)
Friday, August 1, 14
37. Vagrant
• Vagrant is like a MAKE file for VMs
• Vagrant configuration sets RAM, CPU, etc
• Allows you to spin up a VM locally that matches PROD
(can also spin up on Amazon, Rackspace, etc)
• Acts as a command-line wrapper around
VirtualBox/VMWare
Friday, August 1, 14
38. Puppet (or Chef)
• Puppet is like a MAKE file for the Software configuration.
• Controls version and configuration of Apache, nginx, PHP, drush,
MySQL, etc.
• Can be used to configure both DEV and PROD
(doesn’t require a VM)
• Helps document exact server configurations
• See https://puphpet.com/ for interactive puppet script creator.
Friday, August 1, 14
39. IDE (Integrated Development Environment)
• Code styling (Drupal coding standard)
• Code analysis (unused variables, missing returns, etc)
• Integrated Debugging (breakpoints, step, variable inspect)
• Integration with version control (git)
• Integration with other tools (Vagrant, ssh, gitflow)
• Drupal integration
• (I personally use PHPStorm)
Friday, August 1, 14
40. Summary
• Define your environments
• Create a deployment process (and stick with it)
• Match DEV and PROD as much as possible
• Keep hands off PROD! (everything in code)
• Automate all the things
• Use all the tools
Friday, August 1, 14