Einen schönen Nikolaustag, euch allen! Ich hoffe der Nikolaus, oder auch Nikolo – wie er in Österreich auch genannt wird – bringt euch heute eine Kleinigkeit. All jenen, die gestern nicht der Krampus geholt hat, darf ich heute meinen Beitrag zum Adventskalender näher bringen: Magento 2 Deployment mit Capistrano.
Wer kennt das nicht: Nach Tage/Wochen/Monaten harter Arbeit in den lokalen Entwicklungssystemen ist es an der Zeit, die Ergebnisse in einem Staging- und später Live-System bereitzustellen. Nun stellt sich die Frage: Wie bekommen wir unser wunderschönes Magento 2 Projekt in eine andere Umgebung? Möglichst automatisch d.h. ohne die selben Befehle immer und immer wieder manuell auszuführen?
Folgende Schritte sind dazu notwendig:
- Der Source Code muss irgendwie in die neue Umgebung
- Maintenance Mode aktivieren/Wartungsseite setzen
- Production Mode aktivieren (deploy:mode:set production)
- Module aktivieren
- Code Generation anwerfen (setup:di:compile)
- Setup Skripte ausführen
- Statische Files deployen (setup:static-content:deploy)
- Cache leeren
- Maintenance Mode deaktivieren/Wartungsseite entfernen
Idealerweise führt man diese Schritte nicht immer im selben Verzeichnis aus, sondern baut sog. Releases.
Nun gibt es dafür mehrere Möglichkeiten:
- Alles via SFTP hochladen und die Befehle dann nacheinander händisch via SSH ausführen (ist eigentlich keine Möglichkeit)
- Ein fancy rsync Script schreiben (geht, geht aber besser)
- Ein modernes Deployment Tool verwenden
Die Auswahl an Build & Deployment Tools ist mittlerweile umfangreich, die bekanntesten sind wohl: phing, deployer,MageDeploy, Jenkins, usw.
Ich möchte in diesem Blogpost auf das Deployment mit Capistrano und dem Magento 2 Capistrano Plugin von David Alger näher eingehen, weil ich es ausprobiert und bei mehreren Projekten im Einsatz habe, und ich es sehr solide finde.
Capistrano
Capistrano ist eine in Ruby geschriebene Open Source Software. Besonders zur Verteilung von Software auf mehrere Server ist Capistrano gut geeignet, mit einem einzigen Server funktioniert es natürlich auch 😉
Voraussetzung ist also, das Ruby auf der jeweiligen Maschine (das kann das eigene Notebook/MacBook oder auch ein Docker Container sein) installiert ist. Danach kann Capistrano als Ruby Gem installiert werden:
$ gem install capistrano
Capistrano wird üblicherweise via Command Line (bash) ausgeführt.
Die Konfiguration ist recht einfach: Konfigurationen können global oder umgebungsspezifisch gesetzt werden:
- global
config/deploy.rb
- umgebungspezifisch
config/deploy/<stage_name>.rb
z.B: config/deploy/staging.rb
Auf dem Server sieht die Ordnerstruktur folgendermaßen aus:
├── current -> /var/www/magento/releases/20171206114500/
├── releases
│ ├── 20171205072500
│ ├── 20171205083000
│ ├── 20171205093500
│ ├── 20171206104000
│ └── 20171206114500
├── repo
├── revisions.log
└── shared
└── <linked_files and linked_dirs>
Deploy flow
Der Standard-Ablauf von Capistrano v3, wenn man z.B. cap production deploy
ausführt, ist folgender:
deploy:starting - start a deployment, make sure everything is ready
deploy:started - started hook (for custom tasks)
deploy:updating - update server(s) with a new release
deploy:updated - updated hook
deploy:publishing - publish the new release
deploy:published - published hook
deploy:finishing - finish the deployment, clean up everything
deploy:finished - finished hook
Ausführen
Damit dann alle Tasks entsprechend abgearbeitet werden, kann man das Deployment folgendermaßen anstoßen:
bundle exec cap staging deploy
bzw:
bundle exec cap production deploy
…und ab geht die Post!
Magento 2 Plugin für Capistrano
Die Standard Capistrano Tasks liefern unser Magento Setup aus, allerdings werden keine Magento 2 spezifischen Aktionen wie zB Deploy Mode setzen, Setup und Upgrade Scripts ausführen, etc. ausgeführt. Dazu bietet das Magento 2 Plugin für Capistrano super Unterstützung, in dem es Magento 2 spezifische Tasks definiert:
Ein Deployment (hier gekürzt – nur die Tasks) mit Capistrano Magento 2 Plugin, nach dem Aufruf von bundle exec cap staging deploy sieht dann zB so aus:
deploy:pending:log git:wrapper git:check deploy:check:directories deploy:check:linked_dirs deploy:check:make_linked_dirs git:clone git:update git:create_release deploy:set_current_revision deploy:symlink:linked_files deploy:symlink:linked_dirs magento:composer:install magento:setup:permissions magento:deploy:mode:production magento:setup:static-content:deploy magento:setup:di:compile magento:setup:permissions magento:maintenance:enable magento:setup:db:schema:upgrade magento:setup:db:data:upgrade magento:app:config:import deploy:symlink:release magento:cache:flush magento:maintenance:disable deploy:cleanup deploy:log_revision
That’s it!
Damit die Magento 2 Tasks so ausgeführt werden, ist nur diese minimale Konfiguration notwendig, damit es losgehen kann:
config/deploy.rb
set :application, "My Project" set :repo_url, "git@domain.com/repo.git" set :magento_deploy_languages, ['en_US', 'de_DE'] set :magento_deploy_themes, ['mypackage/mytheme']
config/deploy/staging.rb
server "10.0.0.1", user: "user", roles: %w{app db web} set :deploy_to, "/path/to/your/docroot"
So einfach und schnell kann man also mit dem Magento 2 Plugin für Capistrano losstarten.
Debuggen
Manchmal finde ich die Capistrano Fehlermeldungen auf den ersten Blick nicht sehr aussagekräftig.
Hier hilft der —trace Befehl am Ende, um einen genaueren Einblick zu bekommen, wo das Problem liegt:
bundle exec cap staging deploy --trace
Finetuning & Erweiterung
Wie die obenstehende Übersicht der Tasks zeigt, enthält das Magento 2 Plugin für Capistrano noch weitere Befehle. Außerdem ist auch das Erstellen eigener Tasks sehr einfach, die danach ebenfalls via Hooks ausgeführt werden können.
Die Reihenfolge kann recht einfach über die config files (deploy.rb bzw. staging.rb) definiert werden:
before "magento:maintenance:disable", "magento:indexer:reindex" after "magento:setup:static-content:deploy", "your:own:task"
Alternativen
Wie eingangs schon erwähnt, finde ich das Magento 2 Deployment via Capistrano sehr solide.
Wem das nicht zusagt, dem sei folgende Neuerung seit Magento 2.2 ans Herz gelegt: Neu seit Magento 2.2 ist das Pipeline Deployment, mit dem man mit Zero Downtime deployen kann. Ich habe es selbst noch nicht ausprobiert, freue mich aber über Erfahrungsberichte dazu.
Ich wünsche euch viele erfolgreiche Deployments 🙂