An verschiedenen Stellen habe ich schon zu meiner lokalen Entwicklungsumgebung geschrieben, aber vielleicht ist es ganz nützlich, wenn ich das nochmal etwas erläutere.

Normalerweise entwickle ich im Moment für PHP, manchmal auch für die Bash-Shell. Üblicherweise bin ich auch der einzige Entwickler bei meinen Projekten, daher bin ich komplett frei in meinen Rahmenbedingungen.

Vieles ist sicherlich trotzdem mehr oder weniger Standard, aber hin und wieder kann man sich ja doch etwas abschauen und besonders bei der Versionskontrolle und dem Deployment arbeite ich jetzt anders als früher.

Webserver: Standard LAMP-Stack

Zur Webentwicklung gehört natürlich ein lokaler Webserver, der bei mir relativ klassisch eingerichtet ist: Linux Mint, Apache2, MySQL, PHP.

Für Linux Mint habe ich mich entschieden, weil ich gute Erfahrungen mit Debian hatte und gleichzeitig aber auch bei Bedarf etwas modernere Pakete nutzen möchte. Da Linux Mint auf Ubuntu basiert, gibt es zudem einen guten Support. Meine Versionspolitik ist hier eher konservativ, zuletzt habe ich auf Linux Mint 19 geupdatet.

Beim Apache lässt sich nicht viel sagen. Aktuell läuft hier Version 2.4.29 und ich nutze eigentlich nur die Basisfunktionen und mod_rewrite. Zudem liegt mein Document-Root innerhalb meines Home-Verzeichnisses und ich richte für bestimmte Projekte eine lokale Subdomain ein, damit die Pfade ähnlich zum Live-Setup sind. Zudem ist bei mir lokal SSL aktiv um mögliche Fehlerquellen damit zu umschiffen.

MySQL ist ebenfalls Standard und im Moment in Version 5.7. Teilweise wird in meinem Live-Setup MariaDB eingesetzt, aber hier hatte ich noch keinerlei Probleme hinsichtlich Kompatibilität. Ich lege auch lokal User und Passwörter für MySQL an. Die User entsprechen dabei oft dem Live-Setup, die Passwörter natürlich nicht.

PHP ist bei mir lokal im Moment auf 7.2 auf Basis der normalen Linux Mint Quellen. Mit der PHP-Version hatte ich bisher die größten Anpassungsbedarfe, vor allem bei älterem Code und dem Upgrade von 5.6 auf 7.0. Daher bin ich hier auch nicht progressiv sondern update, wenn es erforderlich ist. Im Live-Setup läuft aktuell schon 7.3 und sicherlich werde ich bald auch lokal den nächsten Versionssprung machen wollen. Verschiedene PHP-Versionen parallel zu betreiben, vermeide ich.

Sublime Text als IDE

Zur Bearbeitung des Codes verwende ich aktuell Sublime Text. Ich hatte verschiedene IDEs ausprobiert und habe mich letztlich dafür entschieden, weil sie relativ schlank sowie durch Erweiterungen flexibel anpassbar ist. Damit deckt Sublime für mich alles ab, was ich für die Entwicklung benötige, zum Beispiel:

  • Highlighting in zahlreichen Sprachen
  • Hervorherbung von Klammern (über BracketHighlighter)
  • Prettifier (über HTML/CSS/JS-Prettify, nutze ich vor allem für HTML)
  • autom. Kommentarblöcke (über DoxyDoxygen)
  • Git-Integration (über GitSavvy)
  • Markdown-Support (über MarkdownPreview)
  • einfacher Wechsel zwischen verschiedenen Projekten
  • Makros, komplexes Suchen und Ersetzen, Multiline-Editing
  • Encoding-Handling (Konfiguration: show_encoding: true)

Insgesamt hat sich Sublime bei mir wirklich zur “eierlegenden Wollmilchsau” entwickelt und abgesehen von Datenbankoperationen (z.B. über Adminer) nutze ich es für nahezu alles. Dabei arbeite ich gern im Splitscreen mit Sublime rechts, während links der Browser oder die Bash ist:

Splitscreen: Browser links, Sublime Text rechts

Wenn’s komplett unübersichtlich wird, nehme ich teilweise noch einen einfachen Texteditor (z.B. xed oder Bluefish, teilweise auch Notepad++) hinzu, der praktisch als Zwischenablage fungiert, wenn ich bestimmte Code-Bausteine oder sonstige Infos irgendwo festhalten möchte. Damit spare ich mir meine frühere Zettelwirtschaft :)

Lokales Git zur Versionskontrolle

Für die Strukturierung meines Workflows hat sich Git als Werkzeug vor allem bei den Webprojekten etabliert. Da man seine Arbeit committen muss, arbeite ich sauberer und überlege besser, welche Reihenfolge sinnvoll ist und ob ein Arbeitsschritt wirklich beendet wurde. Zudem hat man ein praktisches Fangnetz, falls man sich irgendwo in einer Richtung verrannt hat. Ich achte hierbei auch auf semantisches Versionieren.

Als GUI habe ich GitKraken für mich entdeckt. Mich hat die grafische Darstellung überzeugt und generell bedient sich dieser Git-Client sehr angenehm. Zudem hat er eine gute Integration für Remote-Repos, etwa bei GitHub oder GitLab.

GitKraken als Git-Client

Durch die farbenfrohe Visualisierung hab ich nun auch Branching für mich entdeckt, was die Arbeit weiter strukturiert, auch wenn ich beim Merging, Rebasing und Cherry Picking immer noch überlegen muss, was nun worauf angewendet wird :)

Deployment über Git-FTP

Für die Auslieferung zum Live-Server habe ich in der Vergangenheit einfach einen FTP-Client wie etwa Filezilla bemüht. Auf den genutzten Servern habe ich in der Regel ohnehin keinen SSH-Zugang und da ist das der einfachste Weg.

Allerdings ist es etwas mühselig bei größeren Updates in alle Ordner einzeln abzusteigen und entsprechende Uploads oder Löschungen vorzunehmen. In der Praxis hab ich dann oft einfach den alten Ordner umbenannt und alles neu hochgeladen.

Hier habe ich auf GitHub mit Git-FTP ein nützliches Tool gefunden, welches mir die Arbeit erleichtert. Die Installation habe ich über das Paketmanagement durchgeführt:

$ sudo -s
$ add-apt-repository ppa:git-ftp/ppa
$ apt-get update
$ apt-get install git-ftp

Die notwendige Konfiguration für die Verbindungsdaten zum FTP-Server kann man mit git config durchführen, wodurch sie in .git/config gespeichert werden.

$ git config git-ftp.url "ftp://servername.de:21/pfad/zum/httpdocs/"
$ git config git-ftp.user "username"
$ git config git-ftp.password "passwort"
$ git config git-ftp.syncroot "pfad/zum/httpdocs/"

Statt die Konfiguration dort abzulegen, kann man diese natürlich auch als Parameter auf der Kommandozeile angeben, bei regelmäßigen Updates ist meine Konfiguration aber weniger fehleranfällig und man muss weniger tippen.

Für den initialen Upload sollte man git-ftp init benutzen. Damit werden alle Dateien im Git auf den Server übertragen. Dabei werden automatisch die Einträge von .gitignore berücksichtigt. Zusätzlich kann man mit .git-ftp-ignore weitere Dateien oder Pfade ausnehmen. Alternativ gibt es mit git-ftp catchup eine Variante das Setup ohne Upload zu initialisieren.

Git-FTP merkt sich den jeweils letzten Commit-Hash beim Upload und ab sofort kann man dann von diesem Stand aus alle neuen Änderungen automatisch übertragen. Dies geschieht mit git-ftp push, wobei hierbei neben Uploads auch Löschungen vorgenommen werden. Insofern ist es sinnvoll die geplanten Veränderungen vorab mittels --dry-run zu prüfen.

Dafür müssen alle aktuellen Änderungen im Git entweder committet, im Stash oder durch die Ignore-Files ausgenommen sein, sonst erscheint ein Fehler:

git-ftp push --dry-run 
fatal: Dirty repository: Having uncommitted changes. Exiting.

Im Erfolgsfall sieht man eine Liste aller zu ändernden Dateien und kann dies mit der eigenen Erwartung abgleichen. Es werden dabei zuerst alle Uploads und dann die Löschungen aufgelistet:

git-ftp push --dry-run 
2 files to sync:
[1 of 2] Buffered for upload 'httpdocs/gruniversal.de/index.html'.
[2 of 2] Buffered for delete 'httpdocs/gruniversal.de/randomquote.php'.
Last deployment changed from d8ef36d1d8801a6754b65d0b746afa191e502757 to 88309104bc6c6c14a9a4b4331448315c6d80f72c.

Ist alles OK, kann man durch Weglassen von --dry-run die Aktualisierung tatsächlich durchführen. Erst dadurch werden auch im Live-System Dateien verändert.

Um damit noch komfortabler arbeiten zu können, lag es nahe dies in mein Makefile zu übernehmen. Dort habe ich auch eine einfache Form der automatischen Protokollierung der Updates implementiert:

timestamp:=$(shell date +%Y%m%d_%H%M%S)

# Deployment auf LIVE-System durchführen
deploy-live:
	git-ftp push | tee ".git-ftp/$(timestamp).live"

Git-FTP hat noch einige andere Funktionen und Parameter, die ich aber für meinen Workflow nicht brauche. Bei Bedarf hilft hier die man-Seite weiter.

Fazit

Aus der Kombination von Linux Bordmitteln und wertvollen Ergänzungen wie Sublime Text, GitKraken und Git-FTP habe ich mir einen netten kleinen Workflow geschaffen, der sowohl einfach als auch effizient und flexibel ist und alle meine Anforderungen erfüllt.

Mehr noch: die Arbeit sowohl mit Sublime als auch GitKraken machen wirklich Freude und Git-FTP gibt mir die Sicherheit vollständige Uploads ohne großes Nachdenken durchzuführen. Wenn also meine Werke fehlerhaft sind, liegt es schon mal nicht am Workflow :)