#acl fb3tGroup:read,write,delete,revert,admin All:read = Heroku-ish Apphosting via Dokku = [[https://dokku.com/|Dokku]] ist eine Software mit deren Hilfe man schnell von Code zu einer laufenden Webanwendung kommt. == Benutzung (Admins) == Man kann generell auf zwei Arten mit Dokku interagieren. Via SSH und lokal via sudo. Manche Befehle lassen sich aus Sicherheitsgründen nur lokal ausführen. Desweiteren wird über das Plugin [[https://github.com/dokku-community/dokku-acl|dokku-acl]] eingeschränkt, wer welche Befehle via SSH ausführen kann (siehe [[#ACLs|ACLs]]). Für das Ausführen von Befehlen via SSH wird folgendes Hilfs-Alias verwendet: {{{#!shell alias dokku='ssh dokku@dokku.informatik.uni-bremen.de --' }}} Über die lokale Gruppe {{{dokku}}} wird gesteuert, wer sich mit seinem UNIX-Account auf dem Server anmelden und lokal {{{dokku}}} via sudo ausführen darf. Im Folgenden werden die wichtigsten Aktionen kurz erklärt: === Account anlegen === * Ausführbarkeit: lokal Für die Erstellung eines Benutzer-Accounts wird ein Accountname und ein SSH-Public-Key benötigt. {{{#!shell ssh dokku echo "$PUB_KEY" | sudo dokku ssh-keys:add $USER }}} === Anwendung anlegen === * Ausführbarkeit: lokal, SSH (nur Super-User) {{{#!shell dokku apps:create $APP }}} === Anderen Benutzern Rechte auf eine Anwendung geben === * Ausführbarkeit: lokal {{{#!shell ssh dokku sudo dokku acl:add $APP $USER }}} === Datenbank anlegen (Optional) === * Ausführbarkeit: lokal, SSH (nur Super-User) Dokku hat ein Konzept von Diensten, i.d.R. Datenbanken, die persistente Daten für Anwendungen aufbewahren. Dienste werden separat angelegt und müssen danach mit der jeweiligen Anwendung verlinkt werden. Wenn eine Anwendung keine Datenbank benötigt kann dieser Schritt übersprungen werden. Derzeit ist nur ein Dienst-Plugin für PostgreSQL installiert. Siehe die [[https://dokku.com/docs/community/plugins/|Liste von Plugins]] in der Dokku-Dokumentation für weitere Optionen. {{{#!shell dokku postgres:create $DB dokku postgres:link $DB $APP }}} ==== Zugriff auf gelinkte Postgres-Datenbanken ==== Siehe [[https://github.com/dokku/dokku-postgres#link-the-postgres-service-to-the-app|link the postgres service to the app]] und [[https://github.com/dokku/dokku-postgres#promote-service--as-database_url-in-|promote service as DATABASE_URL in]] in der Dokumentation des Postgres-Plugins. === Anderen Benutzern Rechte auf eine Datenbank geben === * Ausführbarkeit: lokal {{{#!shell ssh dokku sudo dokku acl:add-service postgres $DB $USER }}} === Persistente Daten === * Ausführbarkeit: lokal, SSH (nur Super-User) Dokku verpackt Anwendungen in Docker-Container, welche keine persistenten Verzeichnisse haben. Das bedeutet, dass Dateien die von einer Anwendung im lokalen Dateisystem gespeichert werden nach einem Neustart der Anwendung verfallen. Falls persistente lokale Dateien benötigt werden, können Verzeichnisse des Host-Systems in die Container gemountet werden. {{{#!shell dokku storage:ensure-directory $DIRNAME dokku storage:mount $APP /var/lib/dokku/data/storage/$DIRNAME:$MOUNTPATH }}} Dabei ist {{{/var/lib/dokku/data/storage/$DIRNAME}}} der lokale Pfad auf dem dokku-Server und {{{$MOUNTPATH}}} der Mountpoint innerhalb des Containers. Ein Beispiel hierfür, um ein Verzeichnis aus dem NFS in den Container zu mounten kann folgendermaßen aussehen: {{{#!shell dokku storage:ensure-directory $DIRNAME dokku storage:mount $APP /home/dml.uni-bremen.de/docroot/apps/$DIRNAME:/app/storage }}} Im Container ist dann in /storage das Verzeichnis aus dem NFS gemountet. /app/ stellt im Container selbst die root-Ebene / dar. Das gemountete NFS-Verzeichnis muss die erforderlichen Berechtigungen haben, damit dokku hier auch lesen und schreiben darf. Da Dokku im NFS jedoch nicht bekannt ist, müssen hier die Rechte für andere User angepasst werden. Es empfiehlt sich zwei Unterverzeichnisse anzulegen. Ein Verzeichnis bspw. /data, um persistente Daten dem Container zur Verfügung zu stellen, mit den Rechten 775 und ein weiteres Verzeichnis bspw. /export, mit den Rechten 773, in das Dokku schreiben darf. ==== Persistente Daten exportieren ==== Persistente Daten können von Accounts mit Rechten auf die jeweilige Anwendung als tgz-Archiv exportiert werden. * Ausführbarkeit: lokal, SSH {{{#!shell dokku storage:export $APP > /path/to/archive.tgz }}} === Benutzung (Endbenutzer) === Wie auch Admins, können Endbenutzer via SSH Dokku-Befehle ausführen, für die sie die entsprechenden Rechte haben (siehe [[#ACLs|ACLs]]). Das oben gelistete Hilfs-Alias ist also auch hier Voraussetzung, um die folgenden Kommandos ausführen zu können. Das Hilfsalias wird nicht von allen Shells unterstützt. Unter Windows eignet sich die Git-Shell. Der Alias gilt nur für die Laufzeit der Shell und muss nach Beendigung dieser erneut eingerichtet werden. {{{#!shell alias dokku='ssh dokku@dokku.informatik.uni-bremen.de --' }}} ==== App aus Git-Repository installieren ==== Nachdem eine Person Zugang zu einer Anwendung bekommen hat, kann diese mit ihrem SSH-Public-Key ihren Code direkt via git auf den Dokku-Server pushen. Bei jedem Push wird die Anwendung mit dem aktualisierten Code neu gebaut. Falls dies nicht gewünscht ist, kann eine Anwendung via {{{dokku apps:lock $APP}}} bzw. {{{dokku apps:unlock $APP}}} ge- und entsperrt werden. {{{ git remote add dokku dokku@dokku:$APP git push dokku main }}} ==== Anforderungen an den Code ==== Der Build-Prozess von Dokku erkennt automatisch die verwendete Programmiersprache und baut ein Docker-Image aus dem Code in das alle Abhängigkeiten installiert werden. Zusätzlich muss eine Datei mit Namen {{{Procfile}}} in das Wurzelverzeichnis des Quelltextes abgelegt werden, das den [[https://devcenter.heroku.com/articles/procfile|Heroku-Procfile]] Spezifikationen entspricht. Kurz zusammengefasst definiert das Procfile wie die Anwendung zu starten ist. Für eine Streamlit-Anwendung könnte {{{Procfile}}} z.B. wie folgt aussehen: {{{ web: streamlit run --server.port $PORT --server.address 0.0.0.0 --browser.serverAddress appnane.apps.informatik.uni-bremen.de --server.runOnSave=false --server.allowRunOnSave=false --server.fileWatcherType=none --browser.gatherUsageStats=false --global.developmentMode=false app.py }}} Wichtig ist, dass die Anwendung auf dem Port lauscht, der in der Umgebungsvariable {{{$PORT}}} definiert ist (i.d.R. 5000) und nicht nur auf {{{localhost}}}. ==== Domain(s) ==== Die Standard-Domain einer Anwendung ist {{{$APP.apps.informatik.uni-bremen.de}}}. Es werden automatisch via Letsencrypt TLS-Zertifikate bezogen. Die Domain einer Anwendung kann via {{{dokku domains:*}}} Befehle geändert werden. Voraussetzung dafür ist, dass der jeweilige Domainname auf den Dokku-Server zeigt. Die aktuellen URLs, unter der eine Anwendung erreichbar ist, können via {{{dokku urls $APP}}} angezeigt werden. ==== Starten, Stoppen, Neustarten, Neubauen einer Anwendung ==== Mit den Befehlen unter {{{dokku ps:*}}} kann mit dem laufenden Container einer Anwendung interagiert werden. Diese Befehle können via SSH von jedem Account mit Zugriffsrechten auf die jeweilige Anwendung ausgeführt werden. {{{ ps:rebuild $APP ps:restart $APP ps:start $APP ps:stop $APP }}} ==== Ausrollen von Anwendungen via Gitlab-CI ==== Wenn man eine Anwendung in Gitlab verwalten und dessen CI/CD-Funktion nutzen möchte, um Änderungen an Dokku zu übertragen, geht das wie folgt: * Im Gitlab-Projekt unter ''Settings -> General -> Visibility, project features, permissions'' sicherstellen, dass der Punkt ''CI/CD'' aktiviert ist. * Unter ''Settings -> CI/CD -> Runners -> Shared runners'' die Option ''Enable shared runners for this project'' aktivieren. * Unter ''Settings -> CI/CD -> Variables'' über den Button ''Add variable'' eine Variable mit dem Namen {{{SSH_PRIVATE_KEY}}} anlegen, die den Wert des zu benutzenden SSH-Private-Key hat (hier sollte ein separater Key verwendet werden, der nur für die jeweilige Dokku-Anwendung genutzt wird und sonst nichts). * Im Git-Repository eine Datei mit dem Namen {{{.gitlab-ci.yml}}} anlegen, die folgenden Inhalt hat (dabei "$APP" mit dem Namen der Dokku-Anwendung ersetzen und ggf. den Branch-Namen "main" anpassen): {{{#!yaml --- image: dokku/ci-docker-image stages: - deploy variables: GIT_DEPTH: 0 deploy: stage: deploy only: - main variables: BRANCH: main GIT_REMOTE_URL: ssh://dokku@dokku.informatik.uni-bremen.de:22/$APP script: - dokku-deploy after_script: - dokku-unlock }}} == ACLs == Siehe {{{~dokku/.dokkurc/acl}}} für die tatsächliche Liste der ACLs. Das ACL-Plugin staffelt Berechtigungen wie folgt: * Super-User die alles dürfen. * Befehle die alle Benutzer immer ausführen dürfen. ({{{DOKKU_ACL_USER_COMMANDS}}}) * Befehle die von Benutzern mit Rechten auf eine Anwendung ausführen dürfen (via {{{dokku acl:add $APP $USER}}}). ({{{DOKKU_ACL_PER_APP_COMMANDS}}}) * Befehle die von Benutzern mit Rechten auf einen Dienst ausführen dürfen (via {{{dokku acl:add-service postgres $DB $USER}}}). ({{{DOKKU_ACL_PER_SERVICE_COMMANDS}}}) * Befehle die von Benutzern mit Rechten auf eine Anwendung und verlinkten Dienst ausführen dürfen. ({{{DOKKU_ACL_LINK_COMMANDS}}}) Derzeit gelten die folgenden ACLs: * DOKKU_ACL_USER_COMMANDS * help * version * apps:exists * apps * apps:list * DOKKU_ACL_PER_APP_COMMANDS * logs * urls * ps:rebuild * ps:restart * ps:stop * ps:start * git-upload-pack * git-upload-archive * git-receive-pack * git-hook * apps:lock * apps:locked * apps:unlock * apps:report * apps:destroy * config * config:bundle * config:clear * config:export * config:get * config:keys * config:show * config:set * config:unset * cron:list * cron:report * cron:run * DOKKU_ACL_PER_SERVICE_COMMANDS * postgres:export * postgres:import * postgres:app-links * postgres:info * postgres:logs * postgres:restart * postgres:enter * postgres:promote