Drupal kamp Pakistan: Automatiseren van Drupal Deployment

Posted by: 
Dominique De Cooman

Het doel van het automatiseren van deployment is om de introductie van nieuwe functies te vergemakkelijken. In deze post leren we hoe we een workflow opzetten welke code en configuratie van je drupal site verplaatst van je locale development station, naar development, naar staging en productie, allemaal met gebruik van jouw versie-controle en een druk op de knop.

Waarom Automatische deployment?

  • Het is sneller. Het automatisch of semi-automatisch uitvoeren van deployment is veel sneller. Je hoeft de database instellingen niet handmatig over te zetten. Je hoeft de code niet handmatig over te zetten. Je hoeft de instellingen niet juist in te stellen voor productie of staging.
  • Het is minder gevoelig voor fouten. Een geautomatiseerd proces dat iedere keer wordt uitgevoerd heeft een kleinere kans op fouten.
  • Het is goed gedocumenteerd. Een geautomatiseerd proces heeft bijna altijd een soort script dat wordt uitgevoerd. Dit script is in versie-controle. Je kunt zien hoe het zich ontwikkeld en waarom het de huidige vorm heeft.
  • Reproduceerbaar. Het proces kan nagemaakt worden. Je weet precies wat er met de site gebeurd is.
  • Geschiedenis. Je kunt een complete geschiedenis hebben van alle builds.
  • Continuous integration. Het Automatiseren van deployment brengt ons dichter bij CI. De mogelijkheid om veranderingen automatisch te introduceren en te testen verkleint regressie en geeft je een betere nachtrust.

Onze basis componenten

  • Een virtuele privé server met een lamp stack.
  • Versie-controle Git.
  • Drush
  • Drupal natuurlijk. Met een correcte repository lay-out.
  • Dev Staging Production setup.
  • Continous integration server
  • Deployment scripts

Hoe stel je het allemaal in?
TIP:
Als je het wilt uittesten op een gratis cloud server. Leer hoe je een gratis cloud server maakt om mee te spelen en het alles uit te proberen. Heel leuk en perfect voor proof-of-concepts.

Lamp stack
In deze post kun je lezen hoe je een vps configureert http://www.dominiquedecooman.com/blog/automate-installing-drupal-ubuntu-...

Drupal project
We zullen deze repository lay-out om ons project te structureren:
- bash
-- updates - update scripts (lees verder)
-- installs - install scripts
-- scripts - random scripts die nodig zijn in het project
- docroot - bevat de drupal site
- documentation - bevat documentatie
- etc
-- drupal - bevat settings files, robot.txt, ...
-- ssh - bevat de config settings (zie volgende)
-- aliasses - bevat de alias files (lees verder)
-- vhost - bevat een vhost template (zie volgende)

Vhost file

<VirtualHost *:80>
  ServerName ddcdemo.local
  ServerAlias *.ddcdemo.local
  DocumentRoot /home/quickstart/websites/ddcdemo.local/docroot
  <Directory /home/quickstart/websites/ddcdemo.local/docroot>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    allow from all
  </Directory>
</VirtualHost>

ssh config file

Host hera
HostName 92.243.15.236
User admin

Dev - staging - production
Creëer drie mappen op je server waar jenkins ingebouwd kan worden. Bijvoorbeeld:

  • /var/www/ddcdemo.dev
  • /var/www/ddcdemo.staging
  • /var/www/ddcdemo.production

Creëer vhosts op de server die aansluiten op deze map zodat je sites bereikbaar zijn. We gebruiken dummy urls maar het zullen voornamelijk echte zijn. (We plaatsen een entry in onze /etc/hosts locally om de sites te kunnen zien op ddcdemo.dev, ddcdemo.staging, ddcdemo.prod)

Versie-controle en Git flow
Lees hier alles over het gebruik van flow: http://dominiquedecooman.com/blog/git-flow-minimizing-overhead
Wij zullen het braching model als basis van onze workflow gebruiken.

Drush
Drush is de drupal shell. Als je het nog niet gebruikt, moet je het zeker even bekijken. http://drupal.org/project/drush

We zullen het gebruiken om onze commands uit te voeren om de site te bouwen. We gebruiken tevens aliassen. http://drupal.org/node/670460

Alias template: Moet in de "~/.drush" map geplaatst worden

// environment dev
$aliases['ddcdemo.dev'] = array(
  'root' => '/var/www/ddcdemo.dev/docroot',
  'remote-host' => '92.243.15.236',
  'remote-user' => 'admin',
);
 
// environment test
$aliases['ddcdemo.test'] = array(
  'root' => '/var/www/ddcdemo.test/docroot',
  'remote-host' => '92.243.15.236',
  'remote-user' => 'admin',
);
 
// environment prod
$aliases['ddcdemo.prod'] = array(
  'root' => '/var/www/ddcdemo.prod/docroot',
  'remote-host' => '92.243.15.236',
  'remote-user' => 'admin',
);
 
// Local instance
$aliases['ddcdemo.local'] = array(
  'root' => '/home/quickstart/websites/ddcdemo.local/docroot',
  'uri' => 'ddc.local',
);

CI server
Installeer -> https://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins+on+Ubuntu
Waarom?
We gebruiken jenkins om onze workflow te automatiseren. Jenkins stelt je in staat om opdrachten te configureren die commands uitvoeren om de site te bouwen en de nieuwe code en configuratie introduceert. Het zal vervolgens tests uitvoeren en feedback leveren. Het biedt tevens een geschiedenis van alle builds.

Automatiseer de workflow
Het exporteren van database veranderingen
Om continous integration te gebruiken met drupal en om in een team te functioneren in het algemeen kun je geen database veranderingen maken op de environments. Dit zal niet alleen een grote kans op fouten met zich meebrengen, je zou iets kunnen vergeten bij de implementatie van je functie, het is oncontroleerbaar.

De features module stelt ons in staat om de drupal configuratie (code) te exporteren naar bestanden. Het maakt bijvoorbeeld een weergave van een view en exporteert dat naar een bestand. Dit bestand kan verbonden worden aan de repository en op een gecontroleerde manier worden geïmplementeerd. (http://drupal.org/project/features)

Features stellen je in staat de meeste componenten te exporteren. Hier volgt een overzicht hoe je ze kunt structureren en enkele ideeën voor het gebruik van installatie profielen in het deployment proces: http://www.slideshare.net/nuvoleweb/code-driven-development-using-featur...

Wat je niet kunt implementeren met features moet met hook_update() gedaan worden. Je kunt de database verandering in deze hook coderen en de drush updb command in het deploy script zal alle hook updates uitvoeren en je verandering zal worden geïmplementeerd.

//Hook update example

Het configureren van jenkins taken
Allereerst maken we een taak per omgeving. Vervolgens zullen we een of meerdere testbot taken maken. Om deze manier kunnen we onze nieuwe code in iedere omgeving implementeren. Jenkins zal altijd verbinden met de repository en een checkout doen van een code in een workspace. We zullen vervolgens deze workspace directoeries synchroniseren met onze mappen.

  • Basis setup
    • Algemene instellingen settings
    • Repository configuratie
    • Build triggers
    • Post build acties
  • Bouw sectie
    • Herstel de meest recente productie-database
    • Deze site wordt gebouwd
    • Kopieer bestanden
    • Update de code
    • Kopieer build script
    • Overrides
    • Voer deploy script uit op de test database
    • Voer geautomatiseerde tests uit en sla resultaten op
    • Voer deploy script uit op de echte database
    • Schakel de build message uit

//Testbot job - development job
#!/bin/sh
 
cd ../../docroot
 
#D7
 
#Update site
drush updb -y
 
#Enable ui modules
drush en field_ui update schema devel feeds_ui views_ui switcheroo dblog glue -y
 
#Feature reverts
drush fra -y
 
# Clear caches
drush cc all
 
#Reindex content Optional
#drush search-api-clear apachesolr_index
#drush sapi-aq
#drush queue-run-concurrent search_api_indexing_queue 8
 
# Run cron
drush cron
 
#Set dev settings
drush vset --yes --always-set preprocess_css 0
drush vset --yes --always-set preprocess_js 0
drush vset --yes --always-set cache 0
drush vset --yes --always-set block_cache 0
drush vset --yes --always-set page_compression 0
drush vset --yes --always-set error_level 2
 
#Run tests
drush en simpletest -y
drush test-run DDCDEMO

//Staging job
#!/bin/sh
 
cd ../../docroot
 
#D7
 
#Update site
drush updb -y
 
#Enable ui modules
drush dis field_ui update schema devel feeds_ui views_ui switcheroo dblog -y
 
#Feature reverts
drush fra -y
 
# Clear caches
drush cc all
 
#Reindex content Optional
#drush search-api-clear apachesolr_index
#drush sapi-aq
#drush queue-run-concurrent search_api_indexing_queue 8
 
# Run cron
drush cron
 
#Set dev settings
drush vset --yes --always-set preprocess_css 1
drush vset --yes --always-set preprocess_js 1
drush vset --yes --always-set cache 1
drush vset --yes --always-set block_cache 1
drush vset --yes --always-set page_compression 1
drush vset --yes --always-set error_level 0
 
#Run tests
drush en simpletest -y
drush test-run DDCDEMO

//Production job
#!/bin/sh
 
cd ../../docroot
 
#D7
 
#Update site
drush updb -y
 
#Enable ui modules
drush dis field_ui update schema devel feeds_ui views_ui switcheroo dblog -y
 
#Feature reverts
drush fra -y
 
# Clear caches
drush cc all
 
#Reindex content Optional
#drush search-api-clear apachesolr_index
#drush sapi-aq
#drush queue-run-concurrent search_api_indexing_queue 8
 
# Run cron
drush cron
 
#Set dev settings
drush vset --yes --always-set preprocess_css 1
drush vset --yes --always-set preprocess_js 1
drush vset --yes --always-set cache 1
drush vset --yes --always-set block_cache 1
drush vset --yes --always-set page_compression 1
drush vset --yes --always-set error_level 0

Het schrijven van het deployment script

  • Activeer/Deactiveer ui modules
  • Stel omgeving specifieke variabelen in
    • Error_level
    • Set Cache
  • Revert features
  • Update de database
  • Optioneell: reindex
  • Run cron
  • Flush cache
  • Running tests

Dit is een speciale blog post over wat je moet gebruiken in het script http://www.dominiquedecooman.com/blog/drupal-7-tip-how-automate-and-cont... De post overlapt een beetje met deze post, maar heeft de focus meer op wat je moet automatiseren dan hoe je moet automatiseren.

Verschillen per omgeving
Elke omgeving heeft, zoals je in het script kunt zien, verschillen. Op deze manier kun je controleren wat je in iedere omgeving doet.

Reroll
Om iets opnieuw te doen gebruik je eenvoudigweg git om veranderingen terug te draaien en recommit een hotfix en deploy. Door de automatisering kun je dit snel en gemakkelijk doen.

Je moet dit nu kunnen doen
Lokaal ontwikkelen op feature branch

git flow feature start news
drush dl views
drush en views -y
drush dl features
drush dl ftools
drush en features ftools -y
//Create a feature called ddcdemo_news add the article content type
git add *
git commit -m "initial setup"

Nu moeten we onze feature delen met onze teamleden en het testen in onze CI. We moeten de code pushen zodat we deze kunnen bekijken in onze testbot om onze feature te testen.

git flow feature publish news

Je kunt nu de jenkins taak gebruiken om de code van de feature branch te implementeren. Typ in het branch veld "origin/feature/news". Repareer tests indien nodig.

Om te stoppen met de ontwikkeling van een feature

git flow feature finish news
git push origin develop

Nu heeft git flow al ons werk samengebracht in de develop branch. Daarna pushen we het naar de origin. Ons CI systeem moet nu de verandering detecteren en automatisch onze develop build uitvoeren. De code die samengebracht was in de develop wordt nu geïmplementeerd in onze ontwikkel omgeving en wordt getest.

Let op: Je kunt ook lokaal tests doen maar simpletest is redelijk traag dus het is gemakkelijker om de server het te laten doen. Er zijn enkele optimistations die gedaan kunnen worden, maar die vallen buiten de reikwijdte van deze post.

Als er testen mislukken dan moeten we deze repareren.

Release
Nu moeten we een release maken om te implementeren in onze staging environment zodat onze klant het kan testen.

git flow release start v0.1.2

Zodra we klaar zijn met het toevoegen aan onze release branch kunnen we het op afstand duwen en het gebruiken als een branch om in te zetten bij staging.

git flow release publish v0.1.2

Nu kunnen we in Jenkins onze branch naam invullen in onze staging taak en dat testen. Als alles goed gaat kunnen we onze release branch afmaken en zal het zowel in de master als de develop branch samengevoegd worden.

git flow release finish v0.1.2
git push origin master

Nu moeten we klaar zijn om de master branch te implementeren in onze productie omgeving. Laten we onze productie taak uitvoeren. Let erop dat er geen tests worden uitgevoerd. We hebben al onze testen uitgevoerd op onze andere omgevingen. We gebruiken de contributed simpletest module en de remotetestcase wat ons in staat stelt om de testen direct op de database uit te voeren, zodat we geen gecompliceerde instellingen hoeven te doen. Het nadeel is echter dat het de database vervuilt met test inhoud.

Hotfix
Maak een hotfix branch - v0.1.2.1

git flow hotfix start v0.1.2.1

Maak de hotfix branch af. Hierdoor zal de verandering fuseren met de develop en de master. Duw de master naar de centrale repository. Duw de production taak en de fix is in production.

git flow hotfix finish v0.1.2.1
git push origin master

Voor meer info over gitflow lees dit: http://yakiloo.com/getting-started-git-flow/

Conclusie
We hebben nu een krachtige manier om op een gecontroleerde manier code te implementeren. Bij het ontwikkelen van tests voor iedere feature kunnen we de regressie minimaliseren en kunnen we op een gecontroleerde manier automatisch releasen.

Reacties

Drupal kamp Pakistan: Automatiseren van Drupal Deployment

Super post. Eindelijk van begin tot eind een ci flow. 1maar: potentieel is je rollback stuk na een updb. Ik zou ergens een back-up maken voor de deploy met bv drush archive-dump oid. Dan kan je met een rollback ook de db terugzetten.

Reactie toevoegen