4 Punkte von GN⁺ 2024-06-10 | 1 Kommentare | Auf WhatsApp teilen
  • Piku ist ein von Dokku inspiriertes Tool, mit dem sich Anwendungen selbst auf kleinen eigenen Servern per git push deployen lassen
  • Es orientiert sich an einem Heroku-/CloudFoundry-ähnlichen Ablauf, zielte aber auf einen einfacheren Deployment-Ansatz, weil Dokku damals auf ARM nicht lief und Docker oft zu schwergewichtig war
  • Beim Deployment erkennt es die Runtime, installiert Abhängigkeiten, liest das Procfile und startet Worker mit uwsgi; dabei sind Abläufe für Python, Node, Java, Clojure, Ruby und Go enthalten
  • Auf einem einzelnen Host lassen sich mehrere Apps unabhängig deployen, verwalten und skalieren; unterstützt werden virtuelle Hosts, SSL, statische Websites, URL-Pfad-Mapping und Backend-Response-Caching
  • Erfordert Python 3.10 oder neuer sowie Python, nginx, uwsgi und SSH und ist ein stabiles Projekt, das die letzten zwei Hauptversionen von Debian und Ubuntu LTS als Zielplattform unterstützt

Welches Problem Piku löst

  • Piku ist ein Tool, das git push-Deployments auf dem eigenen Server ermöglicht
  • Es ist von Dokku inspiriert und soll auch auf sehr kleinen Servern laufen
  • Man wollte ein Heroku-/CloudFoundry-ähnliches Deployment-Erlebnis auf einigen ARM-Boards nutzen, aber Dokku lief damals nicht auf ARM, und Docker war teils überdimensioniert, daher wurde eine einfachere Lösung benötigt
  • Heute können auf ARM- und Intel-Architekturen mehrere Anwendungen pro Host deployt, verwaltet und unabhängig skaliert werden
  • Es läuft bei Cloud-Anbietern und in Bare-Metal-Umgebungen, in denen Python, nginx und uwsgi ausgeführt werden können

Installation und Projektstatus

  • Die Basisinstallation ist mit folgendem Befehl möglich
curl https://piku.github.io/get | sh
  • Die Installationsdokumentation enthält auch weitere Installationsmethoden, darunter cloud-init und manuelle Installation
  • Das Projekt wird als STABLE betrachtet
    • Der Funktionsumfang ist nahezu vollständig
    • Updates erfolgen, wenn neue Sprach-Runtimes hinzukommen oder reproduzierbare Bugs auftreten
  • Aktuell wird Python 3.10 oder neuer benötigt; getestet wird ebenfalls mit Python 3.10 oder neuer
  • Als unterstützte Zielplattformen gelten die letzten zwei Hauptversionen von Debian und Ubuntu LTS

Git-Push-basierter Workflow

  • Piku unterstützt einen Heroku-ähnlichen Workflow
  • Es wird ein Git-SSH-Remote erstellt, das auf den Piku-Server zeigt und den App-Namen als Repository-Namen verwendet
git remote add piku piku@yourserver:appname
  • Deployment durch Push des Codes
git push piku master
  • Um einen anderen Branch als den aktuellen zu pushen, wird Folgendes verwendet
git push piku release-branch-name
  • Während des Deployments erkennt Piku die Runtime, installiert die erforderlichen Abhängigkeiten und führt bei Bedarf Builds aus
    • Python-Apps trennen Abhängigkeiten über ein app-spezifisches virtualenv
    • Go-Apps definieren ein separates app-spezifisches GOPATH
    • Node-Apps installieren die Einträge aus package.json in node_modules
    • Java-Apps werden gemäß pom.xml oder build.gradle gebaut
    • Clojure-Apps können leiningen oder die Clojure-CLI mit der Datei deps.edn verwenden
    • Ruby-Apps installieren Gems per bundle install in einen isolierten Ordner

Laufzeitmodell und Konfiguration

  • Piku liest das Procfile und startet die zugehörigen Worker über uwsgi
  • uwsgi wird als universeller Prozessmanager verwendet
  • Optional kann ein release-Worker angegeben werden, der beim Deployment der App einmal ausgeführt wird
  • Anwendungskonfigurationen lassen sich remote ändern, ebenso können Worker-Prozesse hoch- und herunterskaliert werden
    • Mit config:set wird die Anwendungskonfiguration geändert
    • Mit ps:scale werden Worker-Prozesse skaliert
  • Die Datei ENV kann Anwendungskonfigurationen und nginx-Konfiguration enthalten
  • Mit dem Worker-Typ static lassen sich auch statische Websites im gh-pages-Stil deployen
    • Als Argument wird der Root-Pfad angegeben
    • Es kann auch ein release-Task ausgeführt werden, der nach git push Verarbeitungen auf dem Server übernimmt

Virtuelle Hosts, SSL und statische Pfade

  • Piku unterstützt virtuelle Hosts vollständig
    • Auf demselben VPS können mehrere Apps gehostet werden
    • Über DNS-Aliase können Apps unter verschiedenen Hostnamen erreicht werden
  • Zur Aktivierung von SSL kann ein privates Zertifikat eingerichtet oder ein Zertifikat von Let's Encrypt bezogen werden
  • Wenn im LAN mit macOS-, iOS- oder Linux-Clients zugegriffen wird, kann piku/avahi-aliases verwendet werden, um für dieselbe IP verschiedene Hosts über Avahi/mDNS/Bonjour bekannt zu machen
  • Zusätzlich zu statischen Websites können bestimmte URL-Präfixe direkt auf Dateisystempfade gemappt werden
  • Unterstützt wird auch das Caching von Backend-Antworten, um die Last auf Anwendungen zu reduzieren
  • Statische Pfade und Caching werden über Werte in der Datei ENV konfiguriert

Unterstützte Plattformen und Runtimes

  • Piku ist für POSIX-ähnliche Umgebungen mit Python, nginx, uwsgi und SSH ausgelegt
  • Zu den Deployment-Beispielen gehören Linux, FreeBSD, Cygwin und Windows Subsystem for Linux
  • Die Entwicklung begann auf einem Raspberry Pi Model B mit 256 MB und läuft dort bis heute stabil
  • Der Haupteinsatzzweck ist ein Micro-PaaS zum Ausführen von Apps auf Cloud-Servern mit Intel- und ARM-CPUs
  • Zielplattformen sind Debian und Ubuntu Linux
  • Aktuell werden Python-, Node-, Clojure- und Java-Apps unterstützt; an einigen weiteren Sprachen wie Go wird gearbeitet
  • Als allgemeines Prinzip gilt: Was sich in der Shell aufrufen lässt, kann auch innerhalb von Piku ausgeführt werden

Designprinzipien

  • Der Betrieb auf leistungsschwachen Geräten ist wichtig
  • Es soll auch für Hobbyentwickler und K-12-Schulen zugänglich sein
  • Angestrebt werden etwa 1500 Zeilen gut lesbaren Codes
  • Ein funktionaler Codestil wird bevorzugt
  • Ziel sind möglichst wenige Abhängigkeiten
  • Es folgt 12 factor app
  • Großer Wert wird auf eine einfache User Experience gelegt
  • Ziel ist es, 80 % der üblichen Anwendungsfälle abzudecken
  • Für alle Funktionen werden sinnvolle Standardwerte bereitgestellt
  • Es nutzt Distributionspakete aus Raspbian, Debian und Ubuntu
    • Unterstützung für Alpine und RHEL ist in Arbeit
  • Es nutzt Standardwerkzeuge wie git, ssh, uwsgi und nginx
  • Wo immer möglich, wird Abwärtskompatibilität gewahrt

1 Kommentare

 
GN⁺ 2024-06-10
Hacker-News-Kommentare
  • Ich mochte piku so sehr, dass ich ein Webapp-Tutorial für piku geschrieben habe, und es wurde in ein Repository der offiziellen GitHub-Organisation von piku aufgenommen.
    https://github.com/piku/webapp-tutorial?tab=readme-ov-file#b...
    Es erklärt, wie piku intern funktioniert, und zeigt aus Nutzersicht auch ein minimales Beispiel für eine Python-Webapp.

    • Die neue piku-Dokumentation sieht zwar hübsch aus, war aus Sicht neuer Nutzer, die piku ausprobieren wollen, aber nahezu nutzlos.
      Es wirkte, als setze die Doku bereits voraus, dass man alles weiß, was nötig ist, um piku zu starten und zu verwenden, also habe ich aufgegeben; dieses Tutorial schließt genau diese Lücke.
      Allerdings habe ich ziemlich lange gesucht und dieses Dokument trotzdem nicht gefunden; ohne diesen Kommentar hier hätte ich nicht einmal gewusst, dass es existiert.
      Mindestens sollte dieses Dokument im piku-Repository und auf der Dokumentations-Startseite deutlich verlinkt werden; wenn möglich, wäre es besser, es komplett in die Dokumentations-Startseite aufzunehmen.
      Noch hilfreicher wäre außerdem ein End-to-End-Tutorial, das von einem neuen Bare-Metal-Server bis zu einer öffentlich erreichbaren Custom Domain und einem SSL-Zertifikat führt.
      Auch wenn solche Schritte nicht direkt mit piku zu tun zu haben scheinen: Was neue Nutzer tatsächlich wollen, ist, ihre eigene Site auf so etwas wie einem 5-Dollar-Droplet online zu stellen, und viele kennen die Zwischenschritte noch nicht.
      Welche Methode man wählt, ist egal; wer sich über die Methode Gedanken macht, kennt seine bevorzugte Vorgehensweise ohnehin schon.
      Zum Vergleich gibt es hier ein End-to-End-Beispiel für Coolify: https://billyle.dev/posts/self-hosting-your-website-with-coo...
      Ziel ist nicht, es funktional möglich zu machen, sondern mehr Menschen den Einstieg leicht zu machen und so die piku-Adoption deutlich zu steigern.
    • Mir gefiel, dass erklärt wurde, was „Deployment im Heroku-Stil“ bedeutet.
      Ich wusste überhaupt nicht, was Heroku ist oder was es macht.
    • Allein anhand des offiziellen Repositorys war es nicht klar genug, die Erklärung hat geholfen.
      Wenn ich es richtig verstanden habe, installiert piku einen Agenten auf der Remote-Maschine und Commit-Hooks auf der lokalen Maschine?
      Ich frage mich, ob man den Overhead nicht hätte reduzieren können, indem man die Remote-Maschine einfach zu einem Git-Remote-Repository macht und beim Push auf einen bestimmten Branch alle Arbeiten remote ausführen lässt.
    • Dieses Tutorial ist jetzt auf der Dokumentations-Startseite verlinkt.
  • Sieht gut aus, und Dokku war für mich ebenfalls sehr stabil, aber wenn man die Docker-Abhängigkeit entfernt, ist man nun an die vom Betriebssystem bereitgestellten Optionen gebunden.
    Für Apps, die möglicherweise jahrelang ohne Wartung laufen sollen, ist das nicht ideal, und man stößt am Ende schnell darauf, dass eine bestimmte Betriebssystemversion nötig ist.

    • Eine andere Nische als piku, aber ich empfehle auch Dokku.
      Für kleine Nebenprojekte auf einem VPS habe ich eine Dokku-Installation über 3 bis 4 Ubuntu-LTS-Upgrades hinweg mitgenommen, und sie lief problemlos.
    • Manchmal ist Docker überdimensioniert, und es ist wirklich erfreulich, dass es Tools gibt, die ohne Docker nutzbar sind.
    • Man kann piku auch zusammen mit Docker verwenden. Ich habe ein paar Procfiles, in denen docker run-Anweisungen stehen, auch wenn es dafür natürlich nicht entworfen wurde.
      Die meisten Deployments, die ich gesehen habe, liefen auf sehr stabilen Distributionen, meist LTS-Versionen, sodass man die Runtime nicht alle sechs Monate aktualisieren musste; auch meine Website lief über mehr als zwei Ubuntu-LTS-Wechsel hinweg weiterhin auf piku.
      Wenn man nur die Umgebungsvariablen setzt, lassen sich auch Dinge wie pyenv und nvenv leicht verwenden.
      Mein Home-Automation-System braucht inzwischen zwei unterschiedliche Node-Versionen, und ich habe sie jeweils pro App konfiguriert.
    • Wie löst man bei solchen Tools die Dependency Hell?
      Die „funktioniert einfach“-Haltung ist elegant, und ich verstehe auch, dass Docker wegen seines technischen und mentalen Overheads nicht überall eingesetzt werden kann; aber Container sind praktisch, weil sie alles isolieren und gewissermaßen in der Zeit einfrieren können, sodass es auch fünf Jahre später noch „einfach läuft“.
      In meinem kleinen Workflow erledige ich Container-Management mit lazydocker, Push-Deployments über einen GitLab-Workflow, und Build, Push in die GitLab Registry sowie Ausführung laufen auf einem kleinen VPS.
      Es ist etwas überdimensioniert; vermutlich ginge es auch mit der Kombination aus Dockerfile, compose.yml und docker compose build.
      Skalierung habe ich noch nicht sauber geklärt, aber zum Glück brauche ich sie derzeit nicht; wenn es so weit ist, werde ich wohl Docker durch k8s und lazydocker durch k9s ersetzen.
      Ich bin gerade erst in DevOps eingestiegen, Vorschläge sind also jederzeit willkommen.
    • Ich verwende docker compose + traefik.
      Für mich ist das besser als Dokku, weil es weniger magische Abstraktionen hat.
  • Es hängt nicht direkt mit git push-Deployments zusammen, aber sehr eng mit der PaaS-Erfahrung: Mein Team previewt derzeit die öffentliche CNCF-Spezifikation Cloud Native Buildpacks (CNB).
    Das sind Buildpacks für OCI als Ziel, was bedeutet, dass man lokal Docker-Images mit einem Build-Tool erstellen kann, das ähnlich wie Herokus git push-Logik Sprachunterstützung erkennt und entsprechend behandelt.
    Ein Tutorial zum Builden einer Rails-App mit einem von mir gepflegten Buildpack gibt es hier: https://www.schneems.com/2024/05/01/build-a-ruby-on-rails-ap...
    Wenn ihr es ausprobiert, hinterlasst eure Erfahrungen — ob gut, schlecht oder auch eine eher verhaltene Reaktion — in der verlinkten Diskussion; das hilft bei der Verbesserung.

  • Ich habe piku gerade zum ersten Mal gesehen.
    Ich weiß nicht genau warum, aber dieses Gefühl, dass ein Deployment mit git push startet, wirkte auf mich immer magisch – und einfacher kann es eigentlich nicht werden.
    Passenderweise habe ich gestern ein Open-Source-Projekt für Kubernetes im selben Bereich veröffentlicht; es ist hier: https://github.com/pier-oliviert/sequencer
    Jedenfalls: Glückwunsch, sieht gut aus.

    • Es funktioniert wie Magie, aber wenn man es lernen möchte, ist es auch sehr einfach, es selbst zu bauen.
      Auf dem Server legt man mit git init --bare ein Git-Repository an und setzt git config receive.denyCurrentBranch updateInstead.
      Danach kann man über Git-Hooks, genauer gesagt den push-to-checkout-Hook, Uploads entgegennehmen, kompilieren und ausführen.
      Der Hook ist ein einfaches Shell-Skript; in der grundlegendsten Form reicht eine Variante wie compile && install && systemctl restart service.
      Wenn man anschließend das Repository lokal klont, wird beim Pushen von Änderungen der konfigurierte Hook ausgeführt.
      git clone root@yourserver.com:/path/to/git/folder
    • Vielleicht übersehe ich etwas Offensichtliches, aber wenn sequencer Heroku/Dokku/piku ähnelt, würde mich interessieren, wie Deployment per Git dort funktioniert.
      Der Beschreibung nach scheint es eher um Kubernetes-Templates und kubectl zu gehen als um git push-Deployments; dann wirkt es auf mich wie ein Projekt aus einem völlig anderen Bereich.
  • Die neu überarbeitete piku-Dokumentation findet man hier: https://piku.github.io/

    • Ist das der Nachfolger von Dokku? Ich wusste nicht, dass es ein zweites Projekt gibt.
  • Der erste Commit war vor 8 Jahren?
    Ich wünschte, ich hätte dieses Projekt vor etwa 18 Monaten gekannt; damals suchte ich nach einer Möglichkeit, mit einer Heroku-ähnlichen Developer Experience auf einen Raspberry Pi zu deployen, und piku scheint genau darauf abzuzielen.

    • Genau. Es gibt ein Sichtbarkeitsproblem.
      Ich habe gerade einen neuen VPS mit CapRover eingerichtet, und während ich etwa eine Stunde lang Vergleiche zu „Heroku-artigem Self-Hosting-PaaS“ gesucht habe, bin ich auf Dokku, CapRover, Coolify und Dokploy gestoßen, aber piku habe ich überhaupt nicht gesehen.
  • Ich bin Maintainer und Mitautor.
    Wenn ihr einfache, minimalistische Deployment-Tools mögt, schaut euch auch https://github.com/rcarmo/ground-init an, das cloud-init deutlich praxisnäher handhabt.

    • Nur anhand des README sehe ich nicht wirklich die Antwort darauf, warum es nicht cloud-init sein sollte.
  • Mich würde interessieren, ob es eine Möglichkeit gibt, Deployments ohne Downtime zu handhaben.
    Wenn zum Beispiel ein Python-Service auf einer Maschine hinter nginx auf Port 8080 läuft: Wie schaltet piku auf eine neue Instanz auf demselben Port um?

    • Aktuell wird der laufende Prozess erst beendet, nachdem ein neues git push-Deployment abgeschlossen ist.
      Wie Sockets und Sessions behandelt werden, hängt davon ab, wie der Code aufgebaut ist und ob uwsgi genutzt wird oder ein eigener HTTP-Daemon läuft.
      Eine der bereits optional unterstützten Funktionen ist, ungenutzte und idle Instanzen zu beenden und sie bei neuen eingehenden Verbindungen verzögert zu starten.
    • Ein wenig am Thema vorbei, aber mit systemd-Socket-Aktivierung kann man Deployments ohne Downtime umsetzen.
  • Ich mag Epinio, das dasselbe auf Kubernetes macht.
    Es wird von SUSE unterstützt und ist zum Beispiel leichtergewichtig als KNative, das die Grundlage von GCP Cloud Run bildet; da es aber auf Kubernetes basiert, benötigt es immer noch mehr Ressourcen als Dokku oder piku.
    Trotzdem bevorzuge ich k8s wegen des breiten Ökosystems aus ausgereiften Lösungen.
    Man kann alles auch auf einem einzelnen Server betreiben, braucht dann nur einen etwas größeren Server.
    Der neue Hetzner CX42 hat 8 vCPU, 16 GB RAM und 160 GB Speicher für 16,40 € pro Monat bzw. 0,0273 € pro Stunde, was völlig ausreicht; mit dem Kube-Hetzner-Projekt lässt sich in unter 5 Minuten ein automatisch aktualisierender Kubernetes-Cluster auf MicroOS-Basis einrichten.
    https://github.com/epinio/epinio/
    https://github.com/kube-hetzner/terraform-hcloud-kube-hetzne...

    • Wenn „Epinio dasselbe auf Kubernetes macht“, ist es dann nicht eigentlich überhaupt nicht dasselbe?
      Der Kern von piku scheint zu sein, eine Heroku-ähnliche Erfahrung ohne Docker zu bieten, mit einer wirklich einfachen Architektur, die auch auf ARM läuft.
      Ich erkenne an, dass Kubernetes auf ARM läuft, aber soweit ich weiß, verlangt Kubernetes irgendeine Form von Containern, ob Docker oder etwas anderes, und die Architektur ist aus offensichtlichen Gründen keineswegs einfach.
      Außerdem bin ich mir nicht einmal sicher, ob Epinio einen git push-Flow ermöglicht.
      Das Quickstart-Tutorial scheint für das Deployment einer Anwendung einen Befehl wie epinio push manifest.yaml vorzusehen, was ebenfalls nicht zur „Heroku-ähnlichen Erfahrung“ passt.
      Am Ende besteht die Gemeinsamkeit wohl nur darin, dass beide Deployments abwickeln.
  • Mir gefällt der minimalistische Ansatz, daher werde ich es ausprobieren.
    Es gibt auch ähnliche Dinge, die einen Blick wert sind.
    https://kamal-deploy.org/
    https://github.com/basecamp/kamal
    https://dokku.com/
    https://github.com/dokku/dokku/
    https://clace.io/
    https://github.com/claceio/clace