# FabAccess Installation

Wie wird FabAccess installiert? Das findet sich hier! FabAccess hat grundlegend eine Server-Client-Struktur. Diese Dienste müssen entsprechend separat kompiliert bzw. installiert werden. Details, wie diese im Anschluss konfiguriert werden, beinhaltet das Kapitel [FabAccess Konfiguration](https://docs.fab-access.org/books/fabaccess-konfiguration "FabAccess Konfiguration").

# Getting Started / Onboarding

Nachdem ihr [Was ist FabAccess?](https://docs.fab-access.org/books/was-ist-fabaccess-grundkonzepte/page/was-ist-fabaccess "Was ist FabAccess?") gelesen habt und hier gelandet seid, freuen wir uns über eure Entscheidung, FabAccess in eurer Umgebung zu implementieren und möchten euch mit hier einen reibungslosen Einstieg in die Nutzung ermöglichen.

Man fragt sich vielleicht, mit welchen Ressourcen begonnen werden und ob am Ende alles wie geplant funktionieren wird. Mit diesem **Getting Started** möchten wir euch die Angst nehmen und eine Anleitung geben, wie ihr Schritt für Schritt FabAccess bei euch einführen könnt.

Wir empfehlen euch

- sich vorher in die FabAccess Basics etwas einzulesen. Keine Angst! Am Anfang ist es nicht so einfach zu überschauen. Anhaltspunkte über die grundlegende Funktionsweise zu FabAccess findest du bei den [Grundkonzepten](https://docs.fab-access.org/books/was-ist-fabaccess-grundkonzepte/chapter/grundkonzepte "Grundkonzepte").
- einen Überblick (Liste) über euren Space zu erhalten und zu klären, wo und wie genau ihr FabAccess einsetzen möchtet. Das bezieht sich auf die Ressourcen (z.B. Maschinen, Gerätschaften, ...) und etwaige Berechtigungen (Rollen), die später einmal Anwendung finden sollen.

## Gründe für die Nutzung von FabAccess (Vorteile)

Warum sollten wir FabAccess nutzen? Die Gründe dafür können vielseitig sein. In der Regel sind es Ziele wie

- Ressourcen, die gefährlich sind, viel Strom verbrauchen oder in Anschaffung und Reparatur kostenintensiv sind, nur geschulten / eingewiesenen Personen überlassen
- Eine Übersicht über die Gerätschaften und ggf. deren Nutzung (Zeiten) und/oder Verbräuche (Strom) erfassen

## Was wird für FabAccess allgemein benötigt?

- ein oder mehrere Personen, die einen FabAccess Server aufsetzen und betreuen können/wollen - hierzu gibt es verschiedene Rollen, z.B. IT-Administrator, Lab Manager (Schichtleiter, Werstattverantwortlicher, Bereichsleiter oder sonstige Synonyme), Mitglieder, Studenten, sonstige Nutzer
- Zeit zur Integration von Hardware und Software
- Wille, sich Dokumentation durchzulesen und zu verstehen
- Motivation
- ein stabiles Wifi-Netzwerk (Mesh) am Standort - denn Aktoren sind häufig per 2,4 GHz IoT eingebunden

## Was sollten wir integrieren?  


In FabAccess lässt sich grundsätzlich jeder Wunsch integrieren. Allerdings ist es nicht immer sinnvoll, da es entweder zu komplex ist, zu viel Zeit kosten würde oder sozial nicht verträglich ist.

Für einen guten Einstieg empfehlen wir, mit den Ressourcen beginnen, deren Nutzung eingeschränkt werden muss. Sobald die Nutzer das System verstanden haben, kann das System auf andere Ressourcen ausgeweitet werden.

## Und wo sollen wir anfangen?  


Einen guten Start bieten 3D-Drucker, da sich diese einfach mit 230V-Zwischensteckern freischalten lassen. Zudem gibt es dadurch eine direkte Referenz, von welchem Nutzer der letzte Druck stammt.

## Testen, Downloaden, Installieren, Konfigurieren

Da am Anfang nicht abzuschätzen ist, ob FabAccess euren Wünschen entspricht, empfehlen wir den Client zunächst auszuprobieren, um ein Gefühl dafür zu bekommen. Dafür wird ein Server benötigt. Hierzu gibt es verschiedene Möglichkeiten:

- den [Testserver unter test.fab-access.org](https://docs.fab-access.org/books/fabaccess-installation/page/server-online-demo-server-testfab-accessorg "Server - Demo Server zum Ausprobieren von FabAccess ohne Installation") ausprobieren
- ein Debian-Paket installieren
- ein Docker Image installieren
- [selber kompilieren](https://docs.fab-access.org/books/fabaccess-installation/page/server-anleitung-zum-selber-kompilieren "Server - Anleitung zum selber kompilieren")
- ein [Demo-Setup ausleihen](https://docs.fab-access.org/books/fabaccess-installation/page/server-online-demo-server-testfab-accessorg#bkmrk-ausleihen---fabacces "Server - Demo Server zum Ausprobieren von FabAccess ohne Installation")
- [eine Werkstatt besuchen](https://docs.fab-access.org/books/mitmachen-unterstutzen-join-the-community/page/werde-teil-der-fabinfra-community#bkmrk-%C3%9Cbersicht-%C3%BCber-das-f "Mitmachen / Unterstützen / Join the Community"), die FabAccess schon benutzt

## Welche Hardware sollte gekauft bzw. vorgehalten werden?

FabAccess ist frei skalierbar und der Bedarf hängt von der Werkstatt und den Nutzern ab. Je mehr Räume, Ressourcen und Nutzer existieren, desto höher ist der Anspruch an das System.

Ein simples und kostengünstiges Setup von FabAccess lässt sich bereits mit einem Raspberry Pi, einer FRITZ!Box und ein ein paar 230V-Schaltsteckdosen ("Zwischenstecker") mit MQTT-Schnittstelle realisieren. Mit diesen können bereits die ersten Ressourcen in ein funktionsfähiges FabAccess Setup integriert werden. Alles andere an Hardware kann dann nachgerüstet werden, sobald das System läuft und die entsprechenden Berechtigungen vorhanden sind.

Nach oben hin gibt es bekanntlich keine Grenzen. Hinsichtlich Performance, Sicherheit und Administrierbarkeit ist für viele User durchaus auch ein Serveraufbau empfehlenswert. Hier gibt es verschiedenste Aufbauten.

### Struktur-Beispiel Sternenlabor Plauen

- getrennte Wifi SSIDs in der Werkstatt: eine SSID für das "normale" Benutzernetz zum Surfen und eines für Geräte (IoT-Netz)
- Proxmox Server mit 
    - einer virtuellen Maschine, in der wiederrum mehrere [Docker](https://www.docker.com/)-Container laufen: 
        - Docker Container für FabAccess BFFH
        - Docker Container für [einzelne Prometheus Exporter](https://docs.fab-access.org/books/schnittstellen-und-apis/page/monitoring-prometheus-loki-und-grafana "Monitoring: Prometheus + Grafana") (z.B. FabAccess Exporter, MQTT Exporter)
        - Docker Container für [Prometheus](https://prometheus.io/) Service (Metriken sammeln)
        - Docker Container für [Grafana](https://grafana.com/) (Monitoring / Alerting)
        - Docker Container für [Watchtower](https://github.com/containrrr/watchtower) (Docker Images automatisch aktualisieren, um alles auf den neuesten Stand zu halten)
        - sonstige Container für gekapselte Dienste
    - einer weiteren virtuellen Maschine, auf der Portainer läuft. Mit [Portainer](https://www.portainer.io/) lassen sich die obigen Container über eine Web-Oberfläche gut administrieren/orchestrieren
    - Systemübersicht mit [Glances](https://github.com/nicolargo/glances) (eine Art `htop`-Variante mit Web Interface)
    - eine weitere virtuelle Maschine für [OPNsense](https://opnsense.org/) - eine Open Source Firewall, die es erlaubt, dass Nutzer aus dem normalen Benutzer-Wifi auf die FabAccess-Instanz zugreifen können, welche letztlich in einem anderen Netz agiert.

## Ressourcennerfassung für die Integration mit FabAccess

Um einen detaillierten Überblick über eure Ressourcen, also z.B. Maschinen oder auch Dinge wie Außenleuchten oder Türschlösser, zu erhalten und eine reibungslose Integration mit FabAccess zu gewährleisten, haben wir eine gedankliche Tabellenstruktur vorbereitet, in der ihr die erforderlichen Informationen zu euren Dingen eintragen könnt.

Da FabAccess nicht nur für stationäre Maschinen konzipiert ist, könnt ihr auch andere Geräte in der Tabelle erfassen, deren Nutzung ihr nachverfolgen möchtet. Ressourcen können überdies auch virtuell oder menschlich sein (aka "Human Resources"). D.h. es lässt sich so auch Support-Personal (ein guter Name ist z.B. "Joris hilft") über FabAccess abbilden: Schaltet ein Nutzer z.B. einen Thekendienstmitarbeiter frei, dann wird dessen Arbeitszeit für die anfragende Person reserviert und kann danach beispielsweise zum Abrechnen verwendet werden (z.B. minütlich, viertelstündlich, stündlich, ...). Hierdurch lassen weiterführend Fallbeispiele konstruieren, die z.B. den Support innerhalb und außerhalb allgemeiner (ggf. kostenloser) Öffnungszeiten unterscheiden und ggf. ebenso Relevanz für die etwaige Berechnung haben.

Welche Informationen sollten erfasst werden? Grundsätzlich lassen sich Dinge nach verschiedenen Stichworten einordnen, z.B.

- nach Kategorie/Geräteart/Funktionsprinzip (Drucker, Computer, Laser, Nähmaschine, Werkzeugmaschine, Handgerät, CNC, etc., ...)
- nach Tätigkeit (z.B. Schleifen, Bohren, Reinigen, Schweißen, Heizen, Nähen, Messen, ...=
- nach Medium (Druckluft, Strom, Gas, Flüssigkeit, ...)
- nach Ort/Werkstattbereich (Gebäude, Raum, Zone, Bereich, Werkstatt, Gewerk, ...)
- nach Betriebsmittelart (beweglich, ortsfest, stationär, ...)
- nach Name oder eindeutiger Kennzeichnung (ID, Inventarnummer, Seriennummer, ...)
- nach Schutzklasse (ohe Schutz, Schutzerdung, Schutzisolierung, Schutzkleinspannung, ...)
- nach Ansprechpartner (z.B. Werkstattleiter, Bereichsleiter, Abteilung, ...)
- nach Nutzungsberechtigung (ohne Einweisung, mit Kurzeinweisung, mit Maschinenführerschein, mit bestandenem Kurs, ...)

Diese Metainformationen können an verschiedenen Stellen eingearbeitet werden, z.B. in Name, Beschreibung und/oder Kategorie.

1. **Name, Modell und Anzahl**
    - Name: Gebt jeder Ressource einen eindeutigen Namen
    - Modell: Erfasst das genaue Modell der Ressource
    - Anzahl: Falls mehrere Ressourcen dasselbe Modell haben, notiert die Anzahl
2. **Beschreibung**
    - eine kurze Beschreibung der Sache - hilfreich, wenn die Ressource z.B. einen Namen trägt, aus dem sich der Zweck nicht sofort erschließen lässt (z.B. falls die Schleifmaschine "Hildegard" heißt)
3. **Kategorie**
    - Weist jeder Ressource einer Kategorie zu für eine bessere Übersicht. Ein Schema könnte z.B. sein: &lt;Werkstatt&gt;/&lt;Geräteart&gt;, also z.B. Holzwerkstatt/Bandschleifer
4. **Einweisung**
    - Klärt, ob eine Einweisung für die Nutzung der Ressource erforderlich ist
    - Notiert, wenn es spezielle Einweisungen gibt. Für viele Ressourcen ist keine Einweisung notwendig. Dennoch ist es hilfreich zu wissen, wer die Ressource nutzt und wie häufig sie in Gebrauch ist. Diese Informationen könnt ihr in FabAccess hinterlegen, um eine detaillierte Übersicht über die Nutzung zu erhalten.
5. **Wiki**
    - Falls bereits ein Wiki-Eintrag für eine Ressource existiert, fügt den entsprechenden Link in FabAccess hinzu
6. **Wifi**
    - Prüfe bei der Ressource, ob eine stabile Wifi Verbindung verfügbar ist. Ressourcen müssen nicht über Wifi freigeschaltet werden, jedoch ist das der einfachste Einstieg in FabAccess. Wenn ihr FabAccess längerfristig einsetzen möchtet oder schon einen Umbau in eurem Space geplant habt, bietet es sich an auch eine Ethernet-Anbindung an der Ressource zur Verfügung zu haben. So kann der Betrieb mit FabAccess noch reibungsloser verlaufen.
7. **Freischaltung**
    - Gebt an, wie die Ressource freigeschaltet wird (z.B., smarte Steckdosen für 230 V, Schütze für 400 V). Um eine Ressource freizuschalten, benötigt FabAccess die Möglichkeit, einen Freischaltbefehl an die Ressource zu senden. Die Ansteuerung kann je nach Ressourcentyp unterschiedlich erfolgen: 
        - Für einfache Ressourcen mit einem 230 V Anschluss: Hierfür können smarte Steckdosen verwendet werden
        - Für Ressourcen mit 400 V Anschluss: Die Ansteuerung erfolgt über ein Schütz, um den Strom zuzuschalten
        - Für Ressourcen, die nicht hart ausgeschaltet werden sollten: Die Ansteuerung kann evtl. über den Not-Aus-Kreis erfolgen. Es ist wichtig zu beachten, dass bei der Ansteuerung über die Stromzufuhr darauf geachtet werden muss, dass die Ressource eine Abschaltung des Stroms während des Betriebs verkraften kann. Für mobile Geräte, die nicht über den Strom geschaltet werden können, empfiehlt sich die Verwendung eines elektromechanischen Schlosses zur Freigabe einer Aufbewahrungsbox.
8. **Stromanschluss/Leistungsaufnahme**
    - Notiert den benötigten Stromanschluss (z.B., 230 V, 400 V)
    - Notiert auch die Leistungsaufnahme der Ressource. Die verbrauchte Leistung der Ressource kann entweder durch eigene Messgeräte oder spezielle Zwischenstecker gemessen werden. Diese Informationen sind nicht nur wichtig, um die Nutzungsdauer der Ressource zu verstehen, sondern ermöglichen auch eine Abschätzung der Betriebskosten oder ein automatisiertes Abschalten, wenn die Ressource länger als eine einstellbare Zeit nicht aktiv ist. Mit diesen Informationen könnt ihr nun mit der Modellierung der Berechtigungen fortfahren.

[![image.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/xZKnmVqp6owVTOHs-image.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/xZKnmVqp6owVTOHs-image.png)

*Beispiel einer manuell ausgefüllten Tabelle (nicht ganz vollständig)*

<p class="callout info">Diese Infos lassen sich zum Beispiel auch im [**FabAccess Config Generator**](https://docs.fab-access.org/books/fabaccess-konfiguration/page/einfache-konfiguration-mit-dem-fabaccess-config-generator "Einfache Konfiguration mit dem FabAccess Config Generator") erfassen, der viel Arbeit von obigen Konzepten generalisiert abnimmt!</p>

## Modellierung der Berechtigungen

FabAccess ermöglicht eine präzise Kontrolle über die Nutzung von Ressourcen. Das System basiert auf einem Rollensystem, das die Berechtigungen für Ressourcen in einer Rolle zusammenfasst. Nutzer können diese Rollen erhalten und erhalten dadurch die entsprechenden Ressourcenberechtigungen. Ressourcen verfügen über vier Berechtigungsfelder (**read**, **write**, **disclose**, **manage**). Diese Details finden sich unter [RBAC (Benutzerrollen und Berechtigungen)](https://docs.fab-access.org/books/was-ist-fabaccess-grundkonzepte/page/rbac-benutzerrollen-und-berechtigungen "RBAC (Benutzerrollen und Berechtigungen)").

Für einen einfachen Einstieg in dieses System empfiehlt es sich, zwei Standardrollen zu verwenden:

1. **"Offene Rolle":** Jeder Nutzer, der sich im Space anmeldet, erhält diese Rolle. Mit dieser Rolle können alle frei zugänglichen Ressourcen verwendet werden, und es besteht die Möglichkeit, alle öffentlichen Ressourcen über die Ressourcenliste zu entdecken und Informationen abzurufen.
2. **Administrator-Rolle:** Diese Rolle ermöglicht das Anlegen von Nutzern, das Ansehen aller Ressourcen und das Verwalten von Ressourcen. Wichtig ist dabei, auch Berechtigungen für das Nutzermanagement hinzuzufügen. Sollten im Space weitere Unterstützer aktiv sein, die jedoch keine Nutzer und Rollen verwalten sollen, kann eine eigene Rolle mit Manage-Berechtigungen erstellt werden.

Für alle weiteren Rollen können diese nach Bedarf entsprechend den erforderlichen Einweisungen für die Ressourcen erstellt werden. Als Beispiel: Wenn für 3D-Drucker eine Einweisung erforderlich ist, kann eine Rolle "3D-Drucken" erstellt werden. Wenn jedoch zwischen verschiedenen 3D-Drucker-Typen unterschieden werden soll, können zwei separate Rollen erstellt werden, wie "3D-Drucken FDM" und "3D-Drucken SLA". Wenn Nutzer alle 3D-Drucker verwenden können sollen, kann entweder jedem Nutzer alle relevanten Rollen zugewiesen oder eine vererbte Rolle wie "3D-Drucken Gesamt" erstellt werden.

Es wird empfohlen, zu Beginn mit feinen Rollen zu arbeiten, da das Entfernen von Rollen für Nutzer im Nachhinein mehr Aufwand bedeutet.

Mit der Berechtigungstabelle könnt ihr erste Entscheidungen darüber treffen, wer auf welche Ressource zugreifen darf und welche Ressourcen gemeinsam in einer Berechtigung genutzt werden können. Ebenso könnt ihr festlegen, welche Ressourcen für alle zugänglich sein sollen und welche ausschließlich nach einer Freischaltung verwendet werden dürfen.

Die Installation von FabAccess **Difluoroborane** (BFFH) ist auf jedem Server möglich, der das Ausführen einer kompilierten Rust-Binary erlaubt. Das kann ein Bare Metal Linux Server, ein Proxmox, ein Docker-Container oder sonstige Systeme sein.

Neben der reinen Installation sind weitere Schritte der Vor- und Nachkonfiguration notwendig oder empfehlenswert, um ein sinnvolles und praxistaugliches System zu erhalten.

## Vorüberlegungen und Best Practices

Die Installation von FabAccess **Difluoroborane** (BFFH) ist auf jedem Server möglich, der das Ausführen einer kompilierten Rust-Binary erlaubt. Das kann ein Bare Metal Linux Server, ein Proxmox, ein Docker-Container oder sonstiges System sein.

Neben der reinen Installation sind weitere Schritte der Vor- und Nachkonfiguration notwendig oder empfehlenswert, um ein sinnvolles und praxistaugliches System zu erhalten.

### Separierte Netzwerke  


Für ein funktionierendes FabAccess-System sollten die Geräte, die Ressourcen freischalten, in einem separaten Netzwerk betrieben werden - also zum Beispiel Tasmota Schaltsteckdosen oder FabReader. Dadurch wird das Risiko minimiert, dass unerwartete Freischaltungen stattfinden.

Wir separieren sozusagen Notebooks und Smartphones der Nutzer (und Gäste), die sich meistens im regulären Netz befinden, von den [IoT](https://docs.fab-access.org/books/awesome-fabinfra/page/glossar-begrifflichkeiten-und-abkurzungen#bkmrk-iot)-Geräten, die an den Ressourcen anhängen und die die FabAccess-Struktur bilden.

Die Netzwerkseparation kann adminstrativ durch verschiedene Wege erfolgen - zum Beispiel durch [VLAN](https://docs.fab-access.org/books/awesome-fabinfra/page/glossar-begrifflichkeiten-und-abkurzungen#bkmrk-vlan-%28virtual-local-)s oder eigens für die Geräte aufgespannte Wifi-SSIDs.

Wifi SSIDs können auf 2,4 GHz oder 5 GHz ausgestrahlt werden und unterschiedlich anhand ihrer Frequenz benannt werden. Natürlich kann auch für beide Frequenzbänder die gleiche SSID vergeben werden. Je nach Setup sollte hier überlegt werden, was besser ins eigene Space-Konzept passt. Prinzipiell ist es häufig so, dass einige MQTT-fähige Geräte nur im 2,4 GHz Band arbeiten können. Für eine leichtere Unterscheidung kann eine passende Benennung von SSIDs und Geräten hilfreich sein, um Fehler schneller zu finden.

### Nutzer anlernen und aktiv einbeziehen  


- Erklärt das Konzept von FabAccess
- Erklärt, wie der Space FabAccess verwendet

### Überautomatisierung vermeiden  


Nicht alles, was automasiert werden kann, sollte auch automatisiert werden. Nicht jedes Werkzeug oder jede Ressource sollte weggeschlossen bzw. verriegelt werden. Das nimmt u.U. zu viele Grundrechte oder übertechnisiert den Ausstattungsbedarf und die Wartung des Spaces.

### FabAccess sicher machen (physisch + digital)

- Vermeide den physischen Zugriff auf Schalter: Zum Schutz vor Manipulation können z.B. Tasmota Stecker oder Shellys außer Reichweite platziert werden - zum Beispiel unter dem Tisch oder über oder hinter dem Regal
- Etabliere eine sinnvolle Ausgabe von DESFire Karten zum Zugriff auf Ressourcen, um die unerlaubte Weitergabe durch Nutzer zu unterbinden
- Verwende sichere Verschlüsselung für die Funkverbindung im MQTT-Netzwerk und anderen Stellen, wo es möglich ist (TLS Verschlüsselung, LetsEncrypt Zertifikate)
- Verwende aktuelle Standardsicherheitswerkzeuge wie Firewalls, fail2ban und Co.
- sichere (komplexe) Passwörter für Wifi SSIDs verwenden
- Falls FabAccess BFFH öffentlich gehosted wird, also der Standardport 59961 nach außen hin geöffnet ist, sollte trotz TLS-gesicherter Client-Kommunikation bedacht werden, dass Angriffe von außen prinzipiell möglich sind. Im Falle, dass ein Server auf irgendeine Weise erfolgreich gehacked wird, sollten Sicherheitsmaßnahmen in der Konfiguration von Anfang an getroffen werden: 
    - dedizierten Benutzer `bffh` anlegen, der den Service verwaltet und startet/stoppt. BFFH sollte nie als `root` Nutzer laufen, sondern stets beschränkte Rechte haben. Insbesondere dann, wenn BFFH z.B. Zugriff auf Aktoren-/Initiatoren-Plugins hat, die z.B. weitere Prozesse ausführen (z.B. Python, Perl, Bash).
    - bei Hacking besteht in der Regel immer das Risiko des Verlusts oder Offenlegung persönlicher Daten wie Benutzernamen oder Passwörtern. Glücklicherweise ist FabAccess so datensparsam, dass hier maximal Benutzernamen und Rollenzuweisungen (an denen ein Mitgliedsstatus ggf. genauer ausgelesen werden kann) verloren gehen können (die Argon2 Passwort-Hashes sind sehr sicher im Diebstahlfall!)
    - Insbesondere, weil FabAccess auf den Zugriff von physischer Hardware ausgelegt ist, wären etwaige Maschinenbestromungen, z.B. nachts unter fehlender Anwesenheit, durch illegale Fremdeinwirkung u.U. fatal. Hier könnte z.B. auch entgegengewirkt werden, indem der FabAccess Server oder das verwendete IoT-Wifi-Netz nur zu bestimmten Uhrzeiten für Nutzer erreichbar ist.

### Verwende einen Test bzw. Staging Server

Neben dem Produktivserver wird empfohlen eine Staging Instanz zu installieren, die baugleich zur Produktivinstanz ist, jedoch verwendet werden kann, um etwaige Änderungen vorher auszutesten. Insbesondere beim Integrieren von neuen Ressourcen oder beim Ändern von Benutzerrollen- und berechtigungen in einem lebendigen Werktattumfeld kann sonst u.U. turbulent werden. Es ist mit geringem Aufwand möglich mehrere BFFH Instanzen (auch ohne Docker) auf dem gleichen Server laufen zu lassen.

### Erstelle regelmäßig Backups  


Auch bei FabAccess ist es wichtig, regelmäßig Backups der Benutzerdatenbank und der Konfiguration zu erstellen. Nichts wirft einen mehr zurück als der Verlust aller zugewiesenen Rollen durch einen Ausfall.

Es gibt verschiedene Backup-Strategien, je nach vorhandener IT-Infrastruktur, eigenem Geschmack und natürlich auch der Art und Weise, wie FabAccess installiert wurde.

Backups könnten sein:

- kompletter System-Dump (Kopie der Festplatte mitsamt Betriebssystem)
- inkrementelle Backups des Systems oder der FabAccess-relevanten Daten
- Docker-Container Backup
- ein git-Repository, in das wir Konfigurationsdateien pushen und versionieren

Häufig lohnt es sich 1-2 Backup-Strategien zu kombinieren.

<p class="callout success">Tipp: Backups erstellen ist gut! Noch besser: **Testen**, ob die Backups im Ernstfall dann auch funktionieren, also ob ein Restore auch problemlos möglich ist!</p>

Siehe auch [Backup einrichten](https://docs.fab-access.org/books/fabaccess-konfiguration/page/backup-fur-die-benutzerdatenbank-einrichten "Backup einrichten")

### Audit und Zeitsynchronisation

Für Abrechnungsvorgänge oder zum Nachvollziehen von Ereignissen in der Werkstatt sind genaue Zeitstempel wichtig. Es ist deshalb ratsam den Server, auf dem FabAccess BFFH läuft, mit einem Zeitserver zu synchronisieren. Generell ist es empfehlenswert, wenn sich alle Serverdienste und Clients in der Werkstatt auf den gleichen Zeitserver beziehen.

Bei Verwendung von kleinen Geräten wie einem [Raspberry Pi ist es zudem ggf. hilreich ein RTC (Echtzeituhr)](https://docs.fab-access.org/books/fabaccess-konfiguration/page/echtzeituhr-rtc-modul-ds3231-fur-raspberry-pi "Echtzeituhr (RTC) Modul DS3231 für Raspberry Pi") einzubauen, da diese meistens keine eigene Uhrzeit haben. Im Falle eines Internetausfalls hat der Server so trotzdem eine valide Uhrzeitquelle.

## Deine Fragen sind nicht beantwortet?

Schau unsere unsere [FAQs](https://docs.fab-access.org/books/awesome-fabinfra/page/frequently-asked-questions-faqs "Frequently Asked Questions (FAQs)"). Dort finden sich viele häufige Fragen und Antworten!

# Downloads / Demo

## Borepin (Mobile App)

[![512x512_borpin.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/S8hDmbzEQ4DYduvO-512x512-borpin.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/S8hDmbzEQ4DYduvO-512x512-borpin.png)

*Der offizielle Borepin Icon*

Borepin ist die Client-Anwendung zur Nutzung von FabAccess. Borepin ist in [C#](https://docs.fab-access.org/search?term=%5Bc_sharp%5D) mit [Xamarin](https://docs.fab-access.org/search?term=%5Bxamarin%5D) geschrieben.

 [![borepin_menu.png](https://docs.fab-access.org/uploads/images/gallery/2024-10/scaled-1680-/zfWSFiAR88iZNrlf-borepin-menu.png)](https://docs.fab-access.org/uploads/images/gallery/2024-10/zfWSFiAR88iZNrlf-borepin-menu.png) [![borepin_connectserver.png](https://docs.fab-access.org/uploads/images/gallery/2024-10/scaled-1680-/BkNhIjDjAdgFX1hC-borepin-connectserver.png)](https://docs.fab-access.org/uploads/images/gallery/2024-10/BkNhIjDjAdgFX1hC-borepin-connectserver.png) [![Screenshot_20241121-202850_FabAccess.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/76TJYAKK61UErR4r-screenshot-20241121-202850-fabaccess.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/76TJYAKK61UErR4r-screenshot-20241121-202850-fabaccess.png) [![borepin_serverlist.png](https://docs.fab-access.org/uploads/images/gallery/2024-10/scaled-1680-/ddovwRH1G4WaEmTb-borepin-serverlist.png)](https://docs.fab-access.org/uploads/images/gallery/2024-10/ddovwRH1G4WaEmTb-borepin-serverlist.png) [![borepin_usermanagement.png](https://docs.fab-access.org/uploads/images/gallery/2024-10/scaled-1680-/NcBcDmePnkGgWeMO-borepin-usermanagement.png)](https://docs.fab-access.org/uploads/images/gallery/2024-10/NcBcDmePnkGgWeMO-borepin-usermanagement.png) [![Screenshot_20241120-152922_FabAccess.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/EUJQR6DBCXOgmBDr-screenshot-20241120-152922-fabaccess.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/EUJQR6DBCXOgmBDr-screenshot-20241120-152922-fabaccess.png) [![borepin_machineoverview.png](https://docs.fab-access.org/uploads/images/gallery/2024-10/scaled-1680-/JLps0djMQmd2RWug-borepin-machineoverview.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/Wuu4RQmF55TXS4Cx-screenshot-20241123-152802-fabaccess.png) [![borepin_usemachine.png](https://docs.fab-access.org/uploads/images/gallery/2024-10/scaled-1680-/jrfiz5lVgjxoVqOQ-borepin-usemachine.png)](https://docs.fab-access.org/uploads/images/gallery/2024-10/jrfiz5lVgjxoVqOQ-borepin-usemachine.png)

*Ein paar Screenshots von Borepin. Weitere finden sich im [Handbuch](https://docs.fab-access.org/books/fabaccess-konfiguration/page/client-benutzen-und-typische-konfigurationsfehler-bei-server-und-clients "Client benutzen und typische Konfigurationsfehler bei Server und Clients").*

### Sprache

Borepin ist in Deutsch und Englisch verfügbar. Die Sprache wird automatisch eingestellt (die des zu Grunde liegenden Betriebssystems).

### Downloads

Borepin kann auf verschiedenen Plattformen durch vorkompilierte Pakete schnell und einfach installiert werden.

[![store-gitlab.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/s70PBsVweY54fajY-store-gitlab.png)](https://gitlab.com/fabinfra/fabaccess/borepin/-/releases) [![store_android.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/GZKTRbHhWSURYu9T-store-android.png)](https://fdroid.fab-access.org/fdroid/repo) [![store_google.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/Re0YWiTvloHoaoHy-store-google.png)](https://play.google.com/store/apps/details?id=org.fab_infra.fabaccess) [![store_huawei.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/kZ4PcZ3PxmgM58DE-store-huawei.png)](https://appgallery.huawei.com/app/C107570627) [![store_microsoft.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/uoHIxWpnMUGWsGWU-store-microsoft.png)](https://apps.microsoft.com/detail/9p69mwzjf2mv) [![store_apple.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/XXQHfQSSqcOxraDL-store-apple.png)](https://apps.apple.com/us/app/fabaccess/id1531873374) [![store-linux.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/NpdJgluvPyt5TULT-store-linux.png)](https://docs.fab-access.org/books/fabaccess-installation/page/client-fur-linux-mit-waydroid-installieren)

<p class="callout info">Hinweis: auf iOS heißt die App "Borepin", auf Android und Microsoft Windows heißt sie "FabAccess"</p>

- **Android \*.apk (Version 0.3.11 Build: 791217633)**
    - Direkter Download von GitLab: [https://gitlab.com/fabinfra/fabaccess/borepin/-/releases](https://gitlab.com/fabinfra/fabaccess/borepin/-/releases)
    - Google Play Store: [https://play.google.com/store/apps/details?id=org.fab\_infra.fabaccess](https://play.google.com/store/apps/details?id=org.fab_infra.fabaccess)**<span style="color: rgb(230, 126, 35); background-color: rgb(0, 0, 0);"> - DER PLAYSTORE DOWNLOAD FUNKTIONIERT LEIDER AKTUELL NICHT (SEIT 31.01.2025)</span>**
    - Huawei App Gallery: [https://appgallery.huawei.com/app/C107570627](https://appgallery.huawei.com/app/C107570627)
    - F-Droid: [https://fdroid.fab-access.org/fdroid/repo](https://fdroid.fab-access.org/fdroid/repo) (Anleitung: [HowTo: F-Droid Repository einbinden](https://docs.fab-access.org/books/fabaccess-installation/page/client-fur-android-howto-f-droid-repository-einbinden "HowTo: F-Droid Repository einbinden"))
    - Mirror: [https://downloads.fab-access.org/?dir=borepin-apk](https://downloads.fab-access.org/?dir=borepin-apk)
- **Apple iOS / iPadOS / macOS (Version 0.3.11)<span style="color: rgb(230, 126, 35); background-color: rgb(0, 0, 0);"> - DER APPSTORE DOWNLOAD FUNKTIONIERT LEIDER AKTUELL NICHT (SEIT 27.02.2025)</span>**
    - Apple Store: [https://apps.apple.com/us/app/fabaccess/id1531873374](https://apps.apple.com/us/app/fabaccess/id1531873374)
    - Beta-Versionen: [https://testflight.apple.com/join/KfeUaHT4](https://testflight.apple.com/join/KfeUaHT4)
- **Microsoft Windows - UWP (Universal Windows Platform - Win 10 + 11) (Version 0.3.6.0 Build: 6 - <span style="background-color: rgb(0, 0, 0); color: rgb(230, 126, 35);">veraltet</span>!)** 
    - Microsoft App Store: [https://apps.microsoft.com/detail/9p69mwzjf2mv](https://apps.microsoft.com/detail/9p69mwzjf2mv)
- **Linux**
    - der offizielle Linux-Build ist derzeit defekt. Die Alternativlösung besteht in der Verwendung von [Waydroid (Android Emulator)](https://docs.fab-access.org/books/fabaccess-installation/page/client-fur-linux-mit-waydroid-installieren "Client für Android - mit Waydroid auf Linux installieren")

### Borepin Source Code Build

Borepin kann außerdem auch für die o.g. Plattformen selbst kompiliert werden. Diese Informationen findest du unter [Client (alle Plattformen) - Anleitung zum selber kompilieren](https://docs.fab-access.org/books/fabaccess-installation/page/client-alle-plattformen-anleitung-zum-selber-kompilieren "Client (alle Plattformen) - Anleitung zum selber kompilieren").

<p class="callout success"><span style="color: rgb(185, 106, 217);">Die **aktuelle Version** von Borepin ist ["Final INTERFACER" **v0.3.11**](https://gitlab.com/fabinfra/fabaccess/borepin/-/releases/release%2Fv0.3.11) vom 17.03.2023.</span></p>

### Changelog / Release History

Hier geht's zum [Changelog](https://gitlab.com/fabinfra/fabaccess/borepin/-/blob/main/CHANGELOG.md?ref_type=heads)

### Vorraussetzungen zum Installieren / Nutzen  


- Minimale Apple Versionen: 
    - iOS: 8.0
    - iPadOS: 8.0
    - macOS: 11.0 (mit Apple M1 Chip oder neuer)
- Minimale Android Version: 5.0 Lollipop (API SDK Level 21)
- <dl class="information-list__item__definition__item"></dl>
- benötigt wird ein laufender, erreichbarer und konfigurierter FabAccess Server. Diese Server-Anwendung nennt sich Difluoroborane oder kurz "BFFH". Der Server **muss** selbst aufgesetzt sein (self hosted) und im eigenen Space laufen!

### Bedienungsanweisungen

Ein Manual inkl. Troubleshooting-Hinweisen für Borepin findest du [hier](https://docs.fab-access.org/books/fabaccess-konfiguration/page/client-benutzen-und-typische-konfigurationsfehler-bei-server-und-clients "Client benutzen und typische Konfigurationsfehler bei Server und Clients").

---

## Server Anwendung Difluoroborane (BFFH)

[![512x512_bffh.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/kpR2lkZ6NaquA5B1-512x512-bffh.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/kpR2lkZ6NaquA5B1-512x512-bffh.png)

*Der offizielle BFFH Icon*

### Downloads

[![store-linux.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/NpdJgluvPyt5TULT-store-linux.png)](https://gitlab.com/fabinfra/fabaccess/bffh/-/tags?sort=updated_desc&search=release) [![docker.png](https://docs.fab-access.org/uploads/images/gallery/2025-02/scaled-1680-/I9XFvNomGn1pUTia-docker.png)](https://gitlab.com/fabinfra/fabaccess/bffh/container_registry/1395655)

BFFH kann auf folgende Weise installiert werden:

- [Als fertiges Paket für eine Linux-Distribution](https://docs.fab-access.org/books/fabaccess-installation/page/server-installation-mit-distributionspaketen-deb-rpm "Server - Installation mit Distributionspaketen (*:deb, *.rpm)")
- [Source Code für Kompilierung mit Rust](https://docs.fab-access.org/books/fabaccess-installation/page/server-anleitung-zum-selber-kompilieren "Server - Anleitung zum selber kompilieren")
- [Als Container (z.B. Docker / Podman)](https://docs.fab-access.org/books/fabaccess-installation/page/server-installation-mit-docker-podman "Server - Installation mit Docker")
- [Als Raspberry Pi Image zum Flashen](https://docs.fab-access.org/books/fabaccess-installation/page/server-raspberry-pi-image-flashen-fabaccess-wander-setup "Server - Demo Server zum Ausprobieren von FabAccess ohne Installation") (**Achtung**: hinkt der Entwicklung in der Regel um mehrere Monate hinterher!)

### Changelog / Release History

Hier geht's zum [Changelog](https://gitlab.com/fabinfra/fabaccess/bffh/-/blob/development/CHANGELOG.md?ref_type=heads)

### Vorraussetzungen zum Installieren / Nutzen

Je nach Installationsmethode gibt es verschiedene Vorraussetzungen. BFFH ist in der Programmiersprache [Rust](https://docs.fab-access.org/search?term=%5Brust%5D) geschrieben und die API, die verwendet wird, implementiert [Cap'n Proto](https://docs.fab-access.org/search?term=%5Bcapn_proto%5D). BFFH kannst selbst kompiliert werden oder du verwendest z.B. ein fertiges Docker Image.

- Zeig mir die Infos zu [Anforderungen und Kompabilität](https://docs.fab-access.org/books/fabaccess-installation/page/server-anforderungen-und-kompabilitat) des Servers
- Zeig mir die [Installationsanleitungen](https://docs.fab-access.org/books/fabaccess-installation "FabAccess Installation")
- Zeig mir das [Getting Started](https://docs.fab-access.org/books/fabaccess-installation/page/getting-started-onboarding "Getting Started / Onboarding")

<p class="callout success"><span style="color: rgb(185, 106, 217);">Die **aktuelle Version** von BFFH ist **v0.4.3** vom 11.02.2025.</span></p>

### Welche Version nutze ich eigentlich gerade?  


Siehe hier: [Version anzeigen](https://docs.fab-access.org/books/fabaccess-konfiguration/page/cheat-sheet-wichtigste-befehle-ubersicht#bkmrk-version-anzeigen-%28-v)

---

### Demo Server

FabAccess vor dem Installieren einfach ausprobieren per Demo-Server. Siehe [hier](https://docs.fab-access.org/books/fabaccess-installation/page/server-online-demo-server-testfab-accessorg).

---

## Roadmap

Siehe hier: [Roadmap](https://docs.fab-access.org/books/fabaccess-roadmap-ziele/page/fabaccess-versionen-changelog-roadmap "FabAccess - Versionen, Changelog, Roadmap")

## Übersicht Software-Lizenzen

Siehe hier: [Lizenzübersicht](https://docs.fab-access.org/books/rechtliches-n1G/page/lizenzubersicht "Lizenzübersicht")

## BookStack Wiki Offline-Download

Du kannst diese Wiki auch herunterladen. Sie wird täglich 1x komplett exportiert und unter [https://downloads.fab-access.org](https://downloads.fab-access.org) bereitgestellt

# Server - Anforderungen und Kompabilität

BFFH kann auf einer ganzen Reihe von Systemen zu Laufen gebracht werden.

## Kompatible Architekturen

Wir bieten die fertige `bffhd` und `fabfire_provision` binaries in GitLab und im [FabAccess Server Paket (\*.deb*, \**.rpm)](https://docs.fab-access.org/books/fabaccess-installation/page/server-installation-mit-distributionspaketen-deb-rpm) für folgende Architekturen an:

<table border="1" id="bkmrk-aarch64-unknown-linu" style="border-collapse: collapse; width: 75%; height: 152.217px; border-width: 1px;"><colgroup><col style="width: 35.5037%;"></col><col style="width: 10.2647%;"></col><col style="width: 34.7791%;"></col><col style="width: 19.4425%;"></col></colgroup><thead><tr style="height: 38.0333px;"><td style="height: 38.0333px;">Rust Target</td><td style="height: 38.0333px;">Debian</td><td style="height: 38.0333px;">Auch bekannt als</td><td>Adressierung</td></tr></thead><tbody><tr style="height: 38.0333px;"><td style="height: 38.0333px;">`x86_64-unknown-linux-gnu`</td><td style="height: 38.0333px;">amd64</td><td style="height: 38.0333px;">x86-64, x86\_64, AMD64 oder x64</td><td>64 Bit</td></tr><tr style="height: 38.1167px;"><td style="height: 38.1167px;">`aarch64-unknown-linux-gnu`</td><td style="height: 38.1167px;">arm64</td><td style="height: 38.1167px;">ARMv8</td><td>64 Bit</td></tr><tr style="height: 38.0333px;"><td style="height: 38.0333px;">`armv7-unknown-linux-gnueabihf`</td><td style="height: 38.0333px;">armhf</td><td style="height: 38.0333px;">ARMv7</td><td>32 Bit</td></tr></tbody></table>

<p class="callout success">**Konkrete Beispielhardware:** kompatibel sind beispielweise Raspberry Pi Zero 2 W, Pi 2, Pi 3, Pi 4 und Pi 5, sowie diverse Synology NAS und natürliche alle gewöhnlichen Computer und Server. Nicht kompatibel sind jedoch Raspberry Pi 1, Raspberry Pi Zero und Raspberry Pi Zero 2. Die nachfolgende Tabelle zeigt ein paar weitere Details.</p>

**Übersicht gängiger Geräte (Raspberry Pi, Synology) und deren Architekturen (<span style="color: rgb(45, 194, 107);">grün</span> = unterstützt, <span style="color: rgb(230, 126, 35);">orange</span> = nicht unterstützt).**

<table border="1" id="bkmrk-modell-cpu-architekt" style="border-collapse: collapse; width: 100%; height: 1044.45px; border-width: 1px; background-color: rgb(230, 126, 35);"><colgroup><col style="width: 23.2643%;"></col><col style="width: 15.0886%;"></col><col style="width: 13.4268%;"></col><col style="width: 10.5022%;"></col><col style="width: 18.8773%;"></col><col style="width: 18.8773%;"></col></colgroup><thead><tr style="height: 38.1167px;"><td style="height: 38.1167px;">Modell</td><td style="height: 38.1167px;">CPU</td><td style="height: 38.1167px;">Architektur</td><td style="height: 38.1167px;">Erschienen</td><td style="height: 38.1167px;">Rust Compiler Target</td><td style="height: 38.1167px;">Kommentar</td></tr><tr style="height: 84.8667px; background-color: rgb(230, 126, 35);"><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">Raspberry Pi Zero</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">ARM11</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">ARMv6 (32 Bit)</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">11/2015</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">`arm-unknown-linux-gnueabi` `arm-unknown-linux-gnueabihf`</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">Betrachten wir als deprecated, weil über 10 Jahre alt und weil 32 Bit  
</td></tr><tr style="height: 84.8667px; background-color: rgb(230, 126, 35);"><td style="height: 84.8667px;">Raspberry Pi Zero W</td><td style="height: 84.8667px;">ARM11</td><td style="height: 84.8667px;">ARMv6 (32 Bit)</td><td style="height: 84.8667px;">02/2017</td><td style="height: 84.8667px;">`arm-unknown-linux-gnueabi` `arm-unknown-linux-gnueabihf`</td><td style="height: 84.8667px;">Betrachten wir als deprecated, weil über 10 Jahre alt und weil 32 Bit  
</td></tr><tr style="height: 39.5667px;"><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Raspberry Pi Zero 2 W</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">ARM Cortex-A</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">ARMv8 (64 Bit)</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">10/2021</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">`aarch64-unknown-linux-gnu`</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">  
</td></tr><tr style="height: 84.8667px;"><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">Raspberry Pi 1 Model A</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">ARM1176JZF-S </td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">ARMv6 (32 Bit)</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">02/2013</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">`arm-unknown-linux-gnueabi` `arm-unknown-linux-gnueabihf`</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">Betrachten wir als deprecated, weil über 10 Jahre alt und weil 32 Bit  
</td></tr><tr style="height: 84.8667px;"><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">Raspberry Pi 1 Model A+</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">ARM1176JZF-S </td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">ARMv6 (32 Bit)</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">11/2014</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">`arm-unknown-linux-gnueabi` `arm-unknown-linux-gnueabihf`</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">Betrachten wir als deprecated, weil über 10 Jahre alt und weil 32 Bit  
</td></tr><tr style="height: 84.8667px;"><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">Raspberry Pi 1 Model B+</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">ARM1176JZF-S </td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">ARMv6 (32 Bit)</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">04/2012</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">`arm-unknown-linux-gnueabi` `arm-unknown-linux-gnueabihf`</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">Betrachten wir als deprecated, weil über 10 Jahre alt und weil 32 Bit  
</td></tr><tr style="height: 84.8667px;"><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">Raspberry Pi 1 Model B+</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">ARM1176JZF-S </td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">ARMv6 (32 Bit)</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">07/2014</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">`arm-unknown-linux-gnueabi` `arm-unknown-linux-gnueabihf`</td><td style="height: 84.8667px; background-color: rgb(230, 126, 35);">Betrachten wir als deprecated, weil über 10 Jahre alt und weil 32 Bit  
</td></tr><tr style="height: 80.35px;"><td style="height: 80.35px; background-color: rgb(191, 237, 210);">Raspberry Pi 2 Model B</td><td style="height: 80.35px; background-color: rgb(191, 237, 210);">Cortex-A7</td><td style="height: 80.35px; background-color: rgb(191, 237, 210);">ARMv7 (32 Bit)</td><td style="height: 80.35px; background-color: rgb(191, 237, 210);">02/2015</td><td style="height: 80.35px; background-color: rgb(191, 237, 210);">`armv7-unknown-linux-gnueabihf`</td><td style="height: 80.35px; background-color: rgb(191, 237, 210);">  
</td></tr><tr style="height: 39.5667px;"><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Raspberry Pi 2 Model B v1.2</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Cortex-A53</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">ARMv8 (64 Bit)</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">09/2016</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">`aarch64-unknown-linux-gnu`</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">  
</td></tr><tr style="height: 39.5667px;"><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Raspberry Pi 3 Model A+</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Cortex-A53</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">ARMv8 (64 Bit)</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">11/2018</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">`aarch64-unknown-linux-gnu`</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">  
</td></tr><tr style="height: 39.5667px;"><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Raspberry Pi 3 Model B</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Cortex-A53</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">ARMv8 (64 Bit)</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">02/2016</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">`aarch64-unknown-linux-gnu`</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">  
</td></tr><tr style="height: 39.5667px;"><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Raspberry Pi 3 Model B+</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Cortex-A53</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">ARMv8 (64 Bit)</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">03/2018</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">`aarch64-unknown-linux-gnu`</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">  
</td></tr><tr style="height: 39.5667px;"><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Raspberry Pi 4 Model B</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Cortex-A72</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">ARMv8 (64 Bit)</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">07/2019</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">`aarch64-unknown-linux-gnu`</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">  
</td></tr><tr style="height: 39.5667px;"><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Raspberry Pi 5</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">Cortex-A76</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">ARMv8 (64 Bit)</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">10/2023</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">`aarch64-unknown-linux-gnu`</td><td style="height: 39.5667px; background-color: rgb(191, 237, 210);">  
</td></tr><tr style="height: 62.2167px;"><td style="background-color: rgb(191, 237, 210); height: 62.2167px;">Synology Ds218j</td><td style="background-color: rgb(191, 237, 210); height: 62.2167px;">Armada38x</td><td style="background-color: rgb(191, 237, 210); height: 62.2167px;">ARMv7 (32 Bit)</td><td style="background-color: rgb(191, 237, 210); height: 62.2167px;">10/2017</td><td style="background-color: rgb(191, 237, 210); height: 62.2167px;">`armv7-unknown-linux-gnueabihf`</td><td style="background-color: rgb(191, 237, 210); height: 62.2167px;">  
</td></tr><tr style="height: 39.5667px;"><td style="background-color: rgb(191, 237, 210); height: 39.5667px;">Synology RS819  
</td><td style="background-color: rgb(191, 237, 210); height: 39.5667px;">rtd1296</td><td style="background-color: rgb(191, 237, 210); height: 39.5667px;">ARMv8 (64 Bit)</td><td style="background-color: rgb(191, 237, 210); height: 39.5667px;">04/2019</td><td style="background-color: rgb(191, 237, 210); height: 39.5667px;">`aarch64-unknown-linux-gnu`</td><td style="background-color: rgb(191, 237, 210); height: 39.5667px;">  
</td></tr><tr style="height: 38.0333px;"><td style="background-color: rgb(191, 237, 210); height: 38.0333px;">Synology DS718+</td><td style="background-color: rgb(191, 237, 210); height: 38.0333px;">Intel Celeron J3455

</td><td style="background-color: rgb(191, 237, 210); height: 38.0333px;">amd64 (64 Bit)</td><td style="background-color: rgb(191, 237, 210); height: 38.0333px;">09/2017</td><td style="background-color: rgb(191, 237, 210); height: 38.0333px;">`x86_64-unknown-linux-gnu`</td><td style="background-color: rgb(191, 237, 210); height: 38.0333px;">  
</td></tr><tr><td style="background-color: rgb(191, 237, 210);">A20-OLinuXino-LIME2

</td><td style="background-color: rgb(191, 237, 210);">Allwinner A20/T2 (Cortex-A7)

</td><td style="background-color: rgb(191, 237, 210);">ARMv7 (32 Bit)</td><td style="background-color: rgb(191, 237, 210);">03/2015</td><td style="background-color: rgb(191, 237, 210);">`armv7-unknown-linux-gnueabihf`</td><td style="background-color: rgb(191, 237, 210);">  
</td></tr></thead></table>

**Architekturreferenzen**

- Raspberry Pi 
    - [https://de.wikipedia.org/wiki/Raspberry\_Pi#Raspberry-Pi-Modelle](https://de.wikipedia.org/wiki/Raspberry_Pi#Raspberry-Pi-Modelle)
- Synology 
    - [https://kb.synology.com/de-de/DSM/tutorial/What\_kind\_of\_CPU\_does\_my\_NAS\_have](https://kb.synology.com/de-de/DSM/tutorial/What_kind_of_CPU_does_my_NAS_have)
    - [https://github.com/SynoCommunity/spksrc/wiki/Architecture-per-Synology-model#rtd1296-armv8](https://github.com/SynoCommunity/spksrc/wiki/Architecture-per-Synology-model#rtd1296-armv8)
- Debian Pakete 
    - [https://wiki.debian.org/SupportedArchitectures](https://wiki.debian.org/SupportedArchitectures)
- Rust 
    - [https://doc.rust-lang.org/nightly/rustc/platform-support.html](https://doc.rust-lang.org/nightly/rustc/platform-support.html)


## Kompatible Betriebssysteme

- auf Linux/Unix-Basis, zum Beispiel ... 
    - Ubuntu/Kubuntu
    - Arch Linux
    - Raspberry OS
    - Fedora
    - CentOS
    - NixOS → Luca Lutz vom Hackwerk e.V. fragen
    - Synology
    - WSL (Windows Subsystem for Linux)
- FreeBSD
- MacOS (**aktuell ungetestet!**)

<p class="callout info">**Hinweis:** BFFH kann **nicht** auf Windows nativ kompiliert werden. Das liegt an der `winapi`. Dazu gibt es auch einen [Kommentar](https://gitlab.com/fabinfra/fabaccess/bffh/-/issues/120#note_2352425411).</p>

## Geeignete Container/Virtualisierungswerkzeuge

Wer BFFH nicht nativ installieren möchte, kann auch eine Containerumgebung [und enstprechend damit aufsetzen](https://docs.fab-access.org/books/fabaccess-installation/page/server-installation-mit-docker-podman "Server - Installation mit Docker"), zum Beispiel:

- [Docker](https://www.docker.com/)
- [Portainer](https://www.portainer.io/)
- [Kubernetes](https://kubernetes.io/) → Luca Lutz vom Hackwerk e.V. fragen
- [Moby](https://mobyproject.org/)
- [Podman](https://podman.io/)
- [Proxmox](https://www.proxmox.com/en/)
- [LXC](https://linuxcontainers.org/)
- [runC](https://github.com/opencontainers/runc)
- [Containerd](https://containerd.io/)
- [VirtualBox](https://www.virtualbox.org/)
- [Boxes](https://apps.gnome.org/de/Boxes/)
- ...

## Empfehlungen für Hardware

Allgemeine Empfehlungen sind immer relativ schwer zu treffen. Je nach Größe der Institution und der vorhandenen Software- und Personallandschaft gibt es unterschiedlichste Auffassungen davon, was benötigt wird und wie es mit anderen Systemkomponenten zusammenspielen soll bzw. muss.Grundsätzlich versuchen wir, FabAccess Server mit möglichst wenig Ressourcenverbrauch zu installieren. Grundsätzlich benötigt:

- **Festplatte:**
    - BFFH benötigt prinzipiell kaum Speicherplatz. Die Binary ist ca. 200 MB groß. Dazu kommen noch winzige Konfigurationsdateien. Allerdings sollten Auslagerungsdatei, Systemdateien und Platz für Umgebungen wie python3-venv gelassen werden.
    - BFFH schreibt u.U. fleißig Log-Files (Audit). Außerdem werden ggf. weitere Systeme installiert, wie z.B. Scripts oder Monitoring-Services.
    - Wir empfehlen deshalb pauschal 16 GB oder mehr (für Betriebssystem, BFFH, Services, Log Files und Sonstige + Puffer)
    - idealerweise eine schnelle SSD oder Industrial Grade SD-Karte (mit erhöhter Lebensdauer)
- **Arbeitsspeicher**: ≥ 1,5 GB (nur zum Kompilieren der Binary - trifft nicht für die fertig ausführbare `bffhd` Binary zu!)
- **CPU Kerne**: ≥ 1
- **Netzwerkkarte** (idealerweise LAN, nicht nur Wifi)

## Sonstige Empfehlungen in der Werkstatt

- u.U. sinnvoll: USV (unterbrechungsfreie Stromversorgung)
- **stabiles** Wifi-Netzwerk (viele Aktoren werden u.U. lediglich per WLAN angebunden!)

<p class="callout success">Weiterführende Informationen zu Empfehlungen sind im Guide [Getting Started / Onboarding](https://docs.fab-access.org/books/fabaccess-installation/page/getting-started-onboarding "Getting Started / Onboarding") beschrieben.</p>

# Server - Anleitung zum selber kompilieren

## Setup auf Linux

<p class="callout info">Diese Setup-Dokumentation ist am Beispiel eines Raspberry Pi 3 mit Raspberry Pi OS (64 Bit) erstellt, eignet sich in gleicher Weise jedoch auch für Debian, Ubuntu, etc.</p>

Wir flashen auf einem beliebigen Rechner eine neue SD-Karte mit Hilfe von `rpi-imager`. Siehe [https://www.raspberrypi.com/software](https://www.raspberrypi.com/software).

<p class="callout success">Ein fertig eingerichtetes Image kann unter folgender Seite gefunden werden: [Server - Raspberry Pi Image flashen / FabAccess Wander-Setup](https://docs.fab-access.org/books/fabaccess-installation/page/server-raspberry-pi-image-flashen-fabaccess-wander-setup).</p>

Unser Raspberry Pi 3 Model B+ ist vergleichsweise ziemlich alt und hat folgende Specs:

<details id="bkmrk-raspberry-pi-3-b%2B-sp"><summary>Raspberry Pi 3 B+ Specs</summary>

- Broadcom BCM2837B0, Cortex-A53 (ARMv8) 64-Bit-SoC @ 1,4GHz
- 1GB LPDDR2 SDRAM
- 2,4GHz und 5GHz IEEE 802.11.b/g/n/ac Wireless LAN, Bluetooth 4.2, BLE
- Gigabit Ethernet über USB 2.0 (maximaler Durchsatz 300 Mbps)
- Erweiterte 40-polige GPIO-Stiftleiste
- HDMI® in voller Größe
- 4 USB 2.0-Anschlüsse
- CSI-Kamera-Port für den Anschluss einer Raspberry Pi-Kamera
- DSI-Display-Port für den Anschluss eines Raspberry Pi-Touchscreen-Displays
- 4-poliger Stereoausgang und Composite-Video-Anschluss
- Micro-SD-Anschluss zum Laden Ihres Betriebssystems und Speichern von Daten
- 5V/2.5A DC Stromeingang
- Power-over-Ethernet (PoE)-Unterstützung (separater PoE-HAT erforderlich)

</details>### Raspberry Pi Imaging / Provisioning

Wir installieren den Imager, um damit das Raspberry Pi OS aufzuspielen:

```bash
sudo apt install rpi-imager
```

<details id="bkmrk-setup-schritte-anzei"><summary>Setup-Schritte mit Screenshots zeigen (aufklappen)</summary>

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/UZSG1X7SRm6RYUht-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/UZSG1X7SRm6RYUht-grafik.png)

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/TxCqtJJMOPjLwOij-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/TxCqtJJMOPjLwOij-grafik.png)

Wir vergeben als Benutzername `fabinfra-root` und das Passwort `vulca`

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/k8yyWPtUJX8djKgF-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/k8yyWPtUJX8djKgF-grafik.png)

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/fkn1lLtqavjx8oXG-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/fkn1lLtqavjx8oXG-grafik.png)

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/cnUMgSemqocH1F9G-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/cnUMgSemqocH1F9G-grafik.png)

</details>Unser Image: Debian Bookworm Linux `MP PREEMPT Debian 1:6.6.51-1+rpt3 (2024-10-08) aarch64`

### Standardpakete installieren

Wir installieren zunächst Pflichtbibliotheken. Einige der folgenden Pakete sind unter Umständen bereits standardmäßig vorinstalliert. Wir geben sie der Vollständigkeit halber trotzdem an.

```bash
sudo apt update && sudo apt upgrade
sudo apt install -y gsasl libgsasl7-dev libssl-dev libclang-dev build-essential cmake clang capnproto mosquitto mosquitto-clients
```

### Rust + Cargo installieren

Wir installieren rustc und cargo. Für die aktuellen Versionen siehe.

- [https://releases.rs](https://releases.rs)
- [https://doc.rust-lang.org/nightly/cargo/CHANGELOG.html](https://doc.rust-lang.org/nightly/cargo/CHANGELOG.html)

<p class="callout info">Zum Zeitpunkt der letzten Aktualierung dieser Doku wurde Rust 1.84.1 verwendet.</p>

#### Systemeigenes Rust entfernen (optionaler Schritt)

Wir empfehlen die Verwendung von Rustup zum Installieren einer Rust-Umgebung (siehe nachfolgender Schritt).

```bash
# Zeige die aktuell installierten Versionen von rustc und cargo
rustc --version
cargo --version

rustc 1.63.0
cargo 1.65.0

# Zunächst entfernen wir das von Raspberry Pi mitgelieferte Rust
sudo apt purge rustc cargo libstd-rust-* libstd-rust-dev
```

#### Rust und Cargo per Rustup installieren

```bash
# Wir installieren nun das aktuelle Rust per rustup (als normaler Nutzer). Rustup erlaubt das flexible Installieren beliebiger Rust-Versionen - dauert ca. 10 Minuten - wir installieren die Standardvariante 1) 
curl https://sh.rustup.rs -sSf | sh

# cargo in .bashrc einfügen und Umgebung neu laden
echo 'source "$HOME/.cargo/env"' >> ~/.bashrc
source ~/.bashrc

# wir prüfen, ob wir die aktuelle Rust Version haben
rustup show

#  oder installieren sie ...
rustup install stable
rustup default stable

# Update auf aktuelles Release. Falls die letzte Kompilation länger her ist
rustup update

# (optional) eine spezifische Version kann wie folgt installiert werden
rustup install 1.84.1
rustup default 1.84.1

# Version erneut checken
rustc --version
cargo --version

cargo 1.84.1 (66221abde 2024-11-19)
rustc 1.84.1 (e71f9a9a9 2025-01-27)

# Zum Herausfinden, welche genaue Version sich hinter "stable" befindet:
rustc +stable --version
cargo +stable --version
```

<p class="callout info">Compile schlägt fehl? Sind alle Bibliotheken installiert? Wurde das Git-Repository rekursiv ausgecheckt (Abhängigkeiten)?</p>

### Mosquitto vorbereiten

```bash
sudo vim /etc/mosquitto/mosquitto.conf
```

Wir lassen Mosquitto auf IPv4 und IPv6 lauschen und binden es an alle Interfaces (`0.0.0.0` bzw `::`), da unsere MQTT Aktoren im Netzwerk sonst den Server nicht erreichen. Aus Sicherheitsgründen erlauben wir keine anonymen Zugriffe (`allow_anonymous false`). Außerdem legen wir eine Passwortdatei an, die mindestens einen Nutzer + Passwort enthält, gegen den sich sowohl der BFFH Server, als auch die MQTT Geräte später authentifizieren.

```ini
# Place your local configuration in /etc/mosquitto/conf.d/
# /usr/share/doc/mosquitto/examples/mosquitto.conf.example

# note: :: does not automatically configure 0.0.0.0
listener 1883 ::
listener 1883 0.0.0.0

allow_anonymous false
password_file /etc/mosquitto/pw.file
pid_file /run/mosquitto/mosquitto.pid
persistence true
persistence_location /var/lib/mosquitto/
#log_dest file /var/log/mosquitto/mosquitto.log
#log to journald
log_dest syslog
include_dir /etc/mosquitto/conf.d
```

<div class="document" id="bkmrk-" itemscope="itemscope" itemtype="http://schema.org/Article" role="main"><div itemprop="articleBody"><div class="section"><div class="section"><div class="section" id="bkmrk-sudo-apt-update-%26%26-s-1"></div></div></div></div></div>#### Passwortdatei anlegen

Wir erzeugen einen Standardnutzer und nennen ihn `fabaccess-defaultuser` (kann beliebig genannt werden) und vergeben ein Passwort. Wir verwenden als Passwort den Wert `default`.

```bash
sudo mosquitto_passwd -c /etc/mosquitto/pw.file fabaccess-defaultuser
sudo chmod 400 /etc/mosquitto/pw.file
```

<p class="callout info">Es können beliebig viele Nutzer in die Passwortdatei geschrieben werden. Das hängt vom gewünschten Setup ab!</p>

#### Berechtigungen anpassen

```bash
sudo chown -R mosquitto:mosquitto /etc/mosquitto/
```

#### Mosquitto Dienst starten  


```bash
sudo systemctl restart mosquitto.service
sudo journalctl -f -u mosquitto.service
```


Je nach Konfiguration von Mosquitto finden wir die Log-Einträge nun entweder per journalctl im syslog oder in einer separaten Datei.

### Swap File erhöhen

BFFH benötigt zum Kompilieren mehr als 1 GB RAM. Ein Raspberry Pi 3 hat nur 1 GB. Dadurch stürzt er beim Kompilieren mit OOM-Fehlern ab. Deshalb erhöhen wir den Swap temporär auf 2 GB. Dieser Trick basiert auf [https://www.alibabacloud.com/blog/optimization-on-memory-usage-during-rust-cargo-code-compiling\_601189](https://www.alibabacloud.com/blog/optimization-on-memory-usage-during-rust-cargo-code-compiling_601189)

```bash
sudo su
dphys-swapfile swapoff
echo "CONF_SWAPSIZE=2048" > /etc/dphys-swapfile
dphys-swapfile setup
dphys-swapfile swapon

# Überprüfen von "Swp" mit htop
htop
```

### BFFH Nutzer anlegen

Wir legen einen gesonderten Nutzer zum Ausführen von BFFH an. Es ist ein Systembenutzer ohne eigenes Homeverzeichnis (`-s` Parameter).

```bash
sudo useradd -m -s /bin/bash bffh
```

### BFFH Git Projekt auschecken

<p class="callout info">Zum Zeitpunkt der letzten Aktualierung dieser Doku wurde das [**Release 0.4.3**](https://docs.fab-access.org/books/fabaccess-installation/page/downloads-demo#bkmrk-server-anwendung-dif "Downloads / Demo") genutzt.</p>

Nach dem Installieren von Mosquitto können wir uns unserem BFFH Server widmen. Wir arbeiten nachfolgend im Verzeichnis `/opt/fabinfra/`. Es kann aber jedes andere Verzeichnis verwendet werden. Zunächst checken wir unser Git Projekt aus (und zwar **rekursiv**, da es Abhängigkeiten gibt!).

```bash
TGT="/opt/fabinfra"
mkdir -p $TGT/
cd  $TGT/
git clone https://gitlab.com/fabinfra/fabaccess/bffh.git --recursive 
cd bffh/

# wir wechseln den Branch auf die aktuellste Entwicklerversion. Siehe https://gitlab.com/fabinfra/fabaccess/bffh/-/commits/feature%2Fclaims_api -> das lassen wir, denn es klappt nicht mit "cargo build --release"
#git checkout feature/claims_api

# wir wechseln zum Branch "development"
git checkout development

# Submodules updaten
git submodule update --remote
```

### BFFH testen / entwickeln

Wir müssen BFFH zum Code-Testing nicht als optimierte Binary kompilieren. Das Ausführen ist möglich über cargo und dafür stehen [verschiedene Befehle](https://doc.rust-lang.org/cargo/commands/cargo-run.html) zur Verfügung.

BFFH Hilfe anzeigen:

```bash
cargo run -- --help
```

`bffhd` mit Konfigurationsdatei starten

```bash
cargo run -- -c /etc/bffh/bffh.dhall
```

BFFH nutzt die Tokio Bibliothek und kann auch [per Console](https://docs.rs/tokio-console/latest/tokio_console/) inspiziert werden. Dafür kann über cargo der Befehl `tokio-console` installiert werden. Dieser Befehl wird automatisch in `$HOME/.cargo/bin/` installiert und steht dem Nutzer fortan global zur Verfügung.

```bash
cargo install --locked tokio-console
```

Bei laufendem bffhd Prozess können wir uns dann einklinken:

```bash
tokio-console http://localhost:49289
```

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2025-03/scaled-1680-/0B18fXwbmDD6Sx77-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2025-03/0B18fXwbmDD6Sx77-grafik.png)

<p class="callout success">Weitere Infos zu [Logging und Debugging](https://docs.fab-access.org/books/fabaccess-konfiguration/page/server-logs-konfigurieren-und-debugging)</p>

### BFFH kompilieren

BFFH mit `release`-Flag zu einer ausführbaren Datei kompilieren, um optimierte Compile-Artefakte zu erzeugen - auf einem leistungsstarken PC dauert das ca. 2 Minuten, auf einem Raspberry Pi 3 zwischen 30 Minuten und 2,5 Stunden. Die fertige Binary liegt danach in `target/release/bffhd`.

```bash
cargo build --release
```

Wir können auch einen erweiteren Build erzeugen, der debuginfo erhält. Die erzeugte Binary findet sich dann in `target/debug/bffhd`.

```bash
RUSTFLAGS=-g cargo build --release
#    Finished release [optimized + debuginfo] target(s) in 2m 42s
```

<p class="callout warning">Die erzeugte Binary `bffhd` ist ca. 200 MB groß! Es ist möglich diese Binary deutlich zu [verkleinern](https://github.com/johnthagen/min-sized-rust), jedoch werden in der Regel hilfreiche Debug Symnole entfernt.</p>

### BFFH installieren

Die fertige Binary kopieren ein Linux-typisches Standardverzeichnis (`/usr/bin`) kopieren und Rechte anpassen:

```bash
# Installiere alle kompilierten Binaries in das Zielverzeichnis
cargo install --path /usr/bin/
```

oder per gewöhnlichem Kopierbefehl:

```bash
cp /opt/fabinfra/bffh/target/release/bffhd /usr/bin
sudo chown root:root /usr/bin/bffhd
```

### BFFH konfigurieren

Die Konfiguration von BFFH wird in diesem Kapitel vorbereitet und grundlegend erzeugt. Die Feinjustageschritte sind im dedizierten Kapitel [FabAccess Konfiguration](https://docs.fab-access.org/books/fabaccess-konfiguration "FabAccess Konfiguration") beschrieben.

#### Verzeichnisse anlegen und Besitzer anpassen

```bash
sudo mkdir -p /etc/bffh/
sudo mkdir -p /etc/bffh/certs/
sudo mkdir -p /var/lib/bffh/ #hier wird die Datenbank gespeichert

sudo chown bffh:bffh /etc/bffh/
sudo chown bffh:bffh /etc/bffh/certs/
sudo chown bffh:bffh /var/lib/bffh/

sudo chmod 750 /etc/bffh/
sudo chmod 750 /etc/bffh/certs/
sudo chmod 750 /var/lib/bffh/
```

#### Zertifikat erzeugen (self signed)

Das Zertifikat benötigen wir für den BFFH Server, da wir es in der Konfigurationsdatei angeben müssen. Es muss vom [Typ X.509 Version 3](https://de.wikipedia.org/wiki/X.509#Struktur_eines_X.509-v3-Zertifikats) sein.

```bash
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/bffh/certs/bffh.key -out /etc/bffh/certs/bffh.crt

# Wir füllen die Fragen mit Beispielwerten aus:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:DE
State or Province Name (full name) [Some-State]:Saxony
Locality Name (eg, city) []:FabInfra Headquarter
Organization Name (eg, company) [Internet Widgits Pty Ltd]:FabInfra Community
Organizational Unit Name (eg, section) []:Demo          
Common Name (e.g. server FQDN or YOUR name) []:fabaccess.local
Email Address []:webmaster@fab-access.org
```

Wir prüfen die geforderte Version **X.509** v3 des Zertifikats:

```bash
sudo openssl x509 -in /etc/bffh/certs/bffh.crt -noout -text | grep "Version"
```




Das Ergebnis muss lauten: `Version: 3 (0x2)`

Üblicherweise sollten Zertifikate und Schlüssel nur von previligierten Benutzern gelesen werden können, deshalb passen wir Berechtigungen und Eigentümer an:

```bash
chown bffh:bffh /etc/bffh/certs/bffh.key
chown bffh:bffh /etc/bffh/certs/bffh.crt
chmod 640 /etc/bffh/certs/bffh.key
chmod 640 /etc/bffh/certs/bffh.crt
```

#### Konfiguration (bffh.dhall) anlegen

Wir legen ein neues Verzeichnis an und kopieren die Beispielkonfiguration dort hin.

```bash
cp /opt/fabinfra/bffh/examples/bffh.dhall /etc/bffh/bffh.dhall
```

```bash
vim /etc/bffh/bffh.dhall
```

Wir passen die Konfiguration nun an unsere Wünsche an. Die Referenz für die Konfiguration findest du [hier](https://docs.fab-access.org/books/fabaccess-konfiguration/page/hauptkonfiguration-bffhdhall "Hauptkonfiguration - bffh.dhall").

#### Nutzerdatenbank (users.toml) anlegen und importieren  


```bash
cp /opt/fabinfra/bffh/examples/users.toml /etc/bffh/users.toml
```

```bash
vim /etc/bffh/users.toml
```

Hier geht's zur Dokumentationen der [users.toml](https://docs.fab-access.org/books/fabaccess-konfiguration/page/benutzerkonfiguration-userstoml "Benutzerkonfiguration - user.toml")

Nach dem Anlegen der Nutzerdatenbank importieren wir diese in BFFH mit folgendem Kommando (dabei ist auch die Hauptkonfiguration `bffh.dhall` anzugeben!). Alternativ kann auch [ein Script](https://docs.fab-access.org/books/fabaccess-konfiguration/page/nutzerdatenbank-laden-hashen-prufen "Nutzerdatenbank laden / hashen / prüfen") verwendet werden, welches ein paar Pre-Checks ausführt.

```bash
/usr/bin/bffhd --config /etc/bffh/bffh.dhall --load /etc/bffh/users.toml
```

<p class="callout danger">Bei jeder Änderung der `users.toml` Datei muss ein Import durchgeführt werden, da BFFH die Änderungen nicht automatisch einliest!</p>

Berechtigungen und Besitzer anpassen

Damit nur Nutzer und Gruppe, nicht aber Externe auf die Dateien zugreifen können, beschränken wir den Zugriff auf unseren Ordner `/opt/fabinfra`. In diesem Verzeichnis befinden sich nur Dienste und Configs, die von BFFH ausgeführt werden sollen. Sollten Dateien nachträglich hinzugefügt oder modifiziert werden ist darauf zu achten, dass der Eigentümer und die Berechtigungen entsprechend angepasst werden.

```bash
BFFH_DIR="/opt/fabinfra/"
sudo find $BFFH_DIR -type d -exec chmod 750 {} +
sudo find $BFFH_DIR -type f -exec chmod 640 {} +
chown -R bffh:bffh $BFFH_DIR
```

### Server starten (manueller Test)

Wir starten den Dienst `bffhd` manuell und dann prüfen wir, ob er auf dem richtigen Port und Interface lauscht:

```bash
/usr/bin/bffhd --verbose --config /etc/bffh/bffh.dhall --log-format Pretty

netstat -an | grep "LISTEN" | grep -v "LISTENING"
```

<p class="callout info">Hinweis: `bffhd` erzeugt oder verwendet beim Starten zwei Dateien, und zwar eine Lock-Datei namens `bffh-lock` und eine interne Datenbankdatei `bffh`, die die Machine States und die Benutzer enthält, die aus `users.toml` stammen.  
</p>

<p class="callout info">BFFH startet standardmäßig auf dem TCP-Port `59661`, wenn nicht geändert. Außerdem wird im Hintergrund auf dem TCP-Port `49289` eine [Debugger Console](https://github.com/tokio-rs/console) gestartet.</p>

### systemd Service anlegen und BFFH automatisch starten

Wenn unser manueller Test geklappt hat, dann sollten wir bffh als Dienst installieren und uns die Arbeit abnehmen lassen:

```bash
vim /etc/systemd/system/bffh.service
```

```ini
[Unit]
Description=FabAccess BFFH Service
After=network.target
  
[Service]
Type=simple
User=bffh
Group=bffh
ExecStartPre=/usr/bin/bffhd --check --config /etc/bffh/bffh.dhall
Environment="BFFH_LOG=warn"
ExecStart=/usr/bin/bffhd --verbose --config /etc/bffh/bffh.dhall --log-format Pretty
Restart=on-failure
RestartSec=30
LogsDirectoryMode=750
LogsDirectory=bffh

[Install]
WantedBy=multi-user.target
```

Dienst aktivieren, starten und prüfen

```bash
sudo systemctl daemon-reload
sudo systemctl enable bffh.service --now
journalctl -f -u bffh.service
```

<p class="callout warning">**Achtung beim Naming:** `bffhd` ist unser BFFH [**Daemon**](https://docs.fab-access.org/books/awesome-fabinfra/page/glossar-begrifflichkeiten-und-abkurzungen#bkmrk-daemon) und impliziert mit seinem Namen, dass das Programm permanent laufen soll. Wir verwenden nachfolgend systemd zum Installieren von `bffhd` als Service. Den Service nennen wir jedoch `bffh.service` - so, wie der Serverdienst heißt.</p>


Wir erlauben unserem Nutzer bffh außerdem den Dienst selbstständig zu starten und zu stoppen:

```bash
sudo echo "bffh ALL=NOPASSWD: /usr/bin/systemctl start bffh.service" > /etc/sudoers.d/bffh
sudo echo "bffh ALL=NOPASSWD: /usr/bin/systemctl stop bffh.service" > /etc/sudoers.d/bffh
sudo echo "bffh ALL=NOPASSWD: /usr/bin/systemctl restart bffh.service" > /etc/sudoers.d/bffh
```

Wenn wir uns als bffh Nutzer einloggen, können wir dann ausführen:

```bash
sudo su - bffh

# als bffh Nutzer
sudo systemtctl start bffh.service
sudo systemtctl stop bffh.service
sudo systemtctl restart bffh.service
```

Nach dem Starten von BFFH haben wir im Idealfall einen stabilen Dienst am Laufen, welcher möglichst keine Fehlerausgaben produziert. Falls doch, sollten wir in die Logs schauen bzw. vorher prüfen, wie die [Log-Ausgabe konfiguriert](https://docs.fab-access.org/books/fabaccess-konfiguration/page/server-logs-konfigurieren-und-debugging "Server Logs konfigurieren") ist.

<p class="callout info">**Log-Größe von journalctl beachten:** Je nach Konfiguration des Log Levels von BFFH und der Anzahl der aktiven Nutzer kann die Logdatei innerhalb von 1-2 Wochen auf über 5 GB und mehr anwachsen und insbesondere bei Systemen auf Basis von SD-Karten zum Defekt des Schreibmediums führen, denn diese altern durch die vielen Schreibzyklen sehr schnell. im produktiven Fall ist deshalb zum einen darauf zu achten, dass die SD-Karte stets überlebt (Log Level auf `Info` setzen), und dass das System nicht voll läuft. Hier ein paar Kommandos, um das Journal zu leeren (dies schützt nicht vor den Schreibzyklen, aber erlaubt eine bessere Übersicht).</p>

```bash
sudo journalctl --rotate
sudo journalctl --vacuum-time=1s
```

Auch syslog läuft unter Umständen voll und kann geleert werden. Das ist allerdings ein sehr unschöner Trick und sollte nur zu absoluten Testzwecken angewendet werden:

```bash
sudo truncate -s 0 /var/log/syslog
```

<div class="code panel pdl conf-macro output-block" data-hasbody="true" data-macro-name="code" id="bkmrk--5" style="border-width: 1px;"><div class="codeContent panelContent pdl"><div><div class="syntaxhighlighter sh-django  bash" id="bkmrk--6"></div></div></div></div>## Arch Linux

```bash
sudo pacman -Syu
sudo pacman -S make cmake clang gsasl
sudo pacman -S git rust capnproto
```

<p class="callout warning">Todo ...</p>

## CentOS

```bash
sudo yum update
sudo yum install curl && curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
sudo yum install epel-release && sudo yum install capnproto
sudo yum install https://packages.endpointdev.com/rhel/7/os/x86_64/endpoint-repo.x86_64.rpm && sudo yum install git
sudo yum install centos-release-scl && yum install llvm-toolset-7 && scl enable llvm-toolset-7 bash (Change bash to youre shell)
sudo yum install gcc-c++ libgsasl-devel openssl-devel cmake
```

<p class="callout warning">Todo ...</p>

<div class="document" id="bkmrk--7" itemscope="itemscope" itemtype="http://schema.org/Article" role="main"><div itemprop="articleBody"><div class="section"><div class="section"><div class="section" id="bkmrk--8"></div></div></div></div></div>

# Server - Installation mit Docker / Podman

Neben der Installation durch [Selbstkompilieren](https://docs.fab-access.org/books/fabaccess-installation/page/server-anleitung-zum-selber-kompilieren "Server - Anleitung zum selber kompilieren") oder [Installieren mit vorpaketierten Setups](https://docs.fab-access.org/books/fabaccess-installation/page/server-installation-mit-distributionspaketen-deb-rpm "Server - Installation mit Distributionspaketen (*:deb, *.rpm)") kann BFFH relativ simpel als Container appliziert werden. Wir beschreiben hier exemplarisch die Installation mit Docker. Es gibt außerdem alternative Container-Dienste wie z.B. Podman. Wir freuen uns hier über Zuarbeit in der Dokumentation.

## Intro

Es gibt prinzipiell die Wege mit Docker Compose (hierzu erstellen wir eine `docker-compose.yml` Datei) oder nutzen den simplen `docker run` Befehl.

Das in beiden Fällen dafür nötige Docker-Image können wir dabei entweder aus dem Repository per `Dockerfile` selbst erzeugen oder aus der [BFFH Container Registry](https://gitlab.com/fabinfra/fabaccess/bffh/container_registry/1395655) laden (pull).

Außerdem gibt es verschiedene Testumgebungen zum Ausprobieren, welche mehr oder weniger gepflegt sind. Diese enthalten `docker-compose.yml` Dateien.

Container bieten eine relativ generische und simple Methode, um mehrere Instanzen parallel zu betreiben, schnell zu modifizieren und wieder zu zerstören. Wir können damit relativ sauber mehrere Instanzen voneinander isolieren - zum Beispiel mehrere Produktivinstanzen oder ein Testsystem von einem Stagingsystem. Container bieten durch aus viele Möglichkeiten und Vorteile. Klare Nachteile sind der erhöhte Administrations- und Ressourcenaufwand, sowie zusätzliche Konfiguration von Firewalls, Upgrades, Deploy-Scripts oder das kompliziertere Einbinden von externen Tools - wieim Falle von BFFH beispielsweise das Einbinden von Monitoring oder Aktoren.

## Anforderungen und Kompabilität

Mindestanforderungen und kompatible Hardware finden sich [hier](https://docs.fab-access.org/books/fabaccess-installation/page/server-anforderungen-und-kompabilitat).

## Installation mit Docker

Diese Beschreibung ist für ein Ubuntu-System erstellt und ist analog anzuwenden/anzupassen für andere Systeme wie Fedora, CentOS, Arch Linux, etc.

### Docker installieren

<p class="callout info">Siehe auch [https://phoenixnap.com/kb/docker-on-raspberry-pi](https://phoenixnap.com/kb/docker-on-raspberry-pi)  
</p>

```bash
sudo apt update && sudo apt upgrade
sudo apt install ca-certificates curl gnupg lsb-release

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io
```

### bffh Benutzer anlegen

Ein gesonderter Nutzer wird den Container als Non-Root ausführen. Es ist ein Systembenutzer ohne eigenes Homeverzeichnis (`-s` Parameter).

```bash
sudo useradd -m -s /bin/bash bffh
```


### Docker Image erstellen mit Dockerfile

<p class="callout info">TODO</p>

### Docker Compose installieren

<p class="callout info">Siehe auch [https://dev.to/elalemanyo/how-to-install-docker-and-docker-compose-on-raspberry-pi-1mo](https://dev.to/elalemanyo/how-to-install-docker-and-docker-compose-on-raspberry-pi-1mo)</p>

```bash
sudo useradd -m -s /bin/bash bffh
```

### BFFH Git Projekt klonen

Get Docker-Compose Files `<span class="pre">git</span> <span class="pre">clone</span> <span class="pre">https://gitlab.com/fabinfra/fabaccess/dockercompose.git</span> <span class="pre">fabaccess-server</span>`

The Dockerfile is in the root directory of the main repo docker-compose.yml is available in a seperate [git repo](https://gitlab.com/fabinfra/fabaccess/dockercompose)

Edit config files in `<span class="pre">config</span>` folder to taste

Start Server with `<span class="pre">docker-compose</span> <span class="pre">up</span> <span class="pre">-d</span>`

To make it eaysier to apply youre changes in your config and keep the dockercompose uptodate, you should “fork” this respository.

### Server Logs

Wir können auch die Logs einsehen, um zu prüfen, ob alles funktioniert:

```bash
docker-compose logs
```

### Docker mit [Certbot](https://certbot.eff.org/) oder [DNSRoboCert](https://github.com/adferrand/dnsrobocert)

Mit Hilfe von Certbort oder DNSRoboCert können wir automatisch und einfach SSL-Zertifikate für BFFH und für Mosquitto erstellen.

<p class="callout info">ToDo</p>

<div class="document" id="bkmrk--1" itemscope="itemscope" itemtype="http://schema.org/Article" role="main"><div itemprop="articleBody"><div class="section" id="bkmrk--2"></div></div></div>

# Server - Installation mit Distributionspaketen (*:deb, *.rpm)

Mit Hilfe fertiger Installationspakete ersparen wir dem Anwender das Installieren von Kompilierungswerkzeugen und Bibliotheken und reduzieren dadurch erheblich den Ressourcen- und Zeitverbrauch. Alternativ zu den Installationspaketen gibt es auch Beschreibungen für das [Selbstkompilieren](https://docs.fab-access.org/books/fabaccess-installation/page/server-anleitung-zum-selber-kompilieren "Server - Anleitung zum selber kompilieren") sowie das [Deployment mit Containern](https://docs.fab-access.org/books/fabaccess-installation/page/server-installation-mit-docker-podman "Server - Installation mit Docker / Podman").

Im Paket `fabaccess-bffh` enthalten sind der BFFH Server, sowie das [FabFire Provisioning Tool](https://docs.fab-access.org/books/plugins-aktoren-initiatoren/page/fabfire-tools#bkmrk-fabfire-provisioning "FabFire Tools"). Die zwei Binaries, die installiert werden, sind damit:

- `/usr/bin/bffhd`
- `/usr/bin/fabfire_provision`

Im optionalen Paket `fabaccess-bffh-dbgsym` finden sich außerdem Debug Symbols für das [Fehleraufspüren](https://docs.fab-access.org/books/fabaccess-konfiguration/page/server-logs-konfigurieren-und-debugging "Server Logs konfigurieren und Debugging"), z.B. durch `gdb`, `valgrind` oder `strace`. Beim Installieren werden hierbei kryptische binäre Dateien in `/usr/lib/debug/.build-id/` abgelegt.

## Anforderungen und Kompabilität

Mindestanforderungen und kompatible Hardware finden sich [hier](https://docs.fab-access.org/books/fabaccess-installation/page/server-anforderungen-und-kompabilitat).

## Downloads

Fertige Pakete für Debian / Ubuntu / Kubuntu (\*.deb) und Fedora / CentOS / RHEL / Rocky Linux (\*.rpm) finden sich in unter folgenden Quellen.

### Direkter Download

[https://downloads.fab-access.org/?dir=bffh-packages](https://downloads.fab-access.org/?dir=bffh-packages) - auch direkt über CLI auflist- und abrufbar:

```bash
cd /tmp/ && wget --spider -r -np https://downloads.fab-access.org/bffh-packages/development/ 2>&1 | grep "\--" | grep fabaccess-bffh | awk -F ' ' '{print $3}' && cd -
```

Wir suchen das passende Paket aus (kann mit dem Kommando `arch` oder `uname -a` überprüft werden) und laden es ins Verzeichnis `/tmp/` herunter (im Bespiel `_amd64.deb`):

```bash
wget https://downloads.fab-access.org/bffh-packages/development/fabaccess-bffh_0.4.4_amd64.deb -P /tmp/
```

Und optional:

```bash
wget https://downloads.fab-access.org/bffh-packages/development/fabaccess-bffh-dbgsym_0.4.4_amd64.deb -P /tmp/
```

### GitLab Releases

[https://gitlab.com/fabinfra/fabaccess/bffh/-/releases](https://gitlab.com/fabinfra/fabaccess/bffh/-/releases) (**Achtung**: es gibt hier **noch** keine fertigen Pakete. Dies ändert sich mit den nächsten Versionen!)

### Signaturen prüfen

Der öffentliche Teil des **PGP-Schlüssels**, der für die Paketerzeugung verwendet wird, findet sich hier: [https://gitlab.com/fabinfra/fabaccess/bffh/-/blob/feature/deb+rpm/debian/public.pgp](https://gitlab.com/fabinfra/fabaccess/bffh/-/blob/feature/deb+rpm/debian/public.pgp) bzw. unter [https://keys.openpgp.org/search?q=D793B5E8A754285F9F776D22C4505B2062532D6E](https://keys.openpgp.org/search?q=D793B5E8A754285F9F776D22C4505B2062532D6E). Dieser kann verwendet werden, um die Signaturen vor dem Installieren zu überprüfen.

```bash
gpg --keyserver keys.openpgp.org --recv-keys D793B5E8A754285F9F776D22C4505B2062532D6E
```

Debian / Ubuntu / Kubuntu:

<p class="callout info">Für das Verifizieren mit gpg benötigen wir noch die die \*.sig oder *\**.sig.asc Datei (nur für \*.deb notwendig):</p>

```bash
gpg --verify /tmp/fabaccess-bffh_0.4.4_amd64.sig.asc /tmp/fabaccess-bffh_0.4.4_amd64.deb
gpg --verify /tmp/fabaccess-bffh_0.4.4_amd64.sig.asc /tmp/fabaccess-bffh-dbgsym_0.4.4_amd64.deb #optional

# Ergebnisse:
gpg: Signatur vom Mi 19 Mär 2025 01:33:43 CET
gpg:                mittels EDDSA-Schlüssel D793B5E8A754285F9F776D22C4505B2062532D6E
gpg: Korrekte Signatur von "FabInfra <info@fab-access.org>" [ultimativ]
gpg: Signatur vom Mi 19 Mär 2025 01:33:45 CET
gpg:                mittels EDDSA-Schlüssel D793B5E8A754285F9F776D22C4505B2062532D6E
gpg: Korrekte Signatur von "FabInfra <info@fab-access.org>" [ultimativ]
```

Fedora / CentOS / RHEL / Rocky Linux:

```bash
KEY=$(gpg --export --armor D793B5E8A754285F9F776D22C4505B2062532D6E) && echo $KEY > rpm --import -

rpm --verbose --checksig /tmp/fabaccess-bffh-0.4.4-1.x86_64.rpm
rpm --verbose --checksig /tmp/fabaccess-bffh-dbgsym-0.4.4-1.x86_64.rpm #optional

# Ergebnisse:
/tmp/fabaccess-bffh-0.4.4-1.x86_64.rpm:
    Header SHA256 digest: OK
    Header SHA1 digest: OK
    Payload SHA256 digest: OK
    MD5 digest: OK
/tmp/fabaccess-bffh-dbgsym-0.4.4-1.x86_64.rpm:
    Header SHA256 digest: OK
    Header SHA1 digest: OK
    Payload SHA256 digest: OK
    MD5 digest: OK
```


### Paket per Dry-run testen

#### Debian / Ubuntu / Kubuntu


Wer nicht gleich installieren will, kann vorher testen und Infos vom Paket abrufen:

```bash
dpkg-deb --info /tmp/fabaccess-bffh_0.4.4_amd64.deb

sudo apt install --simulate /tmp/fabaccess-bffh_0.4.4_amd64.deb
```


## Installation

<p class="callout warning">**Achtung**: BFFH benötigt zwingend einen laufenden Eclipse Mosquitto Server. Dieser kann sich entweder auf dem gleichen Server befinden wie BFFH, oder auf einer anderen Maschine. Deshalb wird `mosquitto` standardmäßig nicht installiert!</p>

### Debian / Ubuntu / Kubuntu

<p class="callout info">Das Paket schlägt beim Installieren die Installation weiterer optional empohlener (recommended) und abhängiger (dependent) Pakete vor. Diese Infos lassen über `dpkg-deb --info fabaccess-bffh_0.4.4_amd64.deb | grep "Depends:\|Recommends:"` abrufen oder sie werden angezeigt, wenn nicht mit `dpkg`, sondern mit `apt` installiert wird. Ein empfehlenswertes Paket ist z.B. `dhall`.</p>

Variante 1: Installation über apt (bevorzugt):

```213594
sudo apt install --no-install-recommends /tmp/fabaccess-bffh_0.4.4_amd64.deb
sudo apt install /tmp/fabaccess-bffh-dbgsym_0.4.4_amd64.deb #optional
```

Wer die empfohlenen Zusatzpakete installieren will, bekommt diese über `apt` angezeigt und kann auch wie folgt installieren, indem der Parameter `--no-install-recommends` weggelassen wird:

```213594
sudo apt install /tmp/fabaccess-bffh_0.4.4_amd64.deb
sudo apt install /tmp/fabaccess-bffh-dbgsym_0.4.4_amd64.deb #optional
```

Variante 2: Installation über `dpkg`:

```213594
sudo dpkg -i /tmp/fabaccess-bffh-0.4.4_amd64.deb
sudo dpkg -i /tmp/fabaccess-bffh-dbgsym-0.4.4_amd64.deb #optional
```

### Fedora / CentOS / RHEL / Rocky Linux

```bash
sudo rpm -i /tmp/fabaccess-bffh-0.4.4-1.x86_64.rpm
sudo rpm -i /tmp/fabaccess-bffh-dbgsym-0.4.4-1.x86_64.rpm #optional
```

Installation prüfen:

```bash
sudo dpkg -l | grep fabaccess-bffh
```

### BFFH als Service aktivieren und Logs prüfen

```bash
sudo systemctl enable bffh --now
sudo journalctl -f -u bffh.service
```

<p class="callout info">BFFH startet standardmäßig auf dem TCP-Port `59661`, wenn nicht geändert. Außerdem wird im Hintergrund auf dem TCP-Port `49289` eine [Debugger Console](https://github.com/tokio-rs/console) gestartet.</p>

## BFFH Hilfe anzeigen

Es gibt eine minimale [Manpage](https://de.wikipedia.org/wiki/Manpage) für BFFH. Diese kann angezeigt werden:

```583287
man bffhd
man fabfire_provision
```

## BFFH Konfiguration

Nach der Installation muss der Server passend konfiguriert werden. Das ist kein Bestandteil des Installers und ist komplett individuell, je nach Gebrauchszweck. Alle wichtige Infos finden sich im Kapitel [FabAccess Konfiguration](https://docs.fab-access.org/books/fabaccess-konfiguration "FabAccess Konfiguration").

## Metainformationen anzeigen

<p class="callout info">Das ist rein informativ und nicht notwendig!</p>

Ein paar Kommandos für verschiedene Zwecke (z.B. nach Tags suchen, Infos zu Paket anzeigen):

```bash
sudo apt install debtags

debtags update
debtags show fabaccess-bffh

apt-cache search fabaccess
apt-cache search bffh
apt search fabaccess
apt search bffh
apt search difluoroborane

aptitude search '?tag(network::server)'
aptitude search fabaccess
aptitude search bffh
aptitude search difluoroborane
```


## Deinstallation

Die Deinstallation von BFFH ist relativ rückstandsfrei, bis auf Konfigurationsdateien, Datenbanken und Logs. Bitte ggf. die Verzeichnisse manuell danach überprüfen:

- `/var/log/bffh/`
- `/etc/bffh/`
- `/var/lib/bffh/`

**Debian / Ubuntu / Kubuntu**

```bash
sudo apt remove fabaccess-bffh
sudo apt remove fabaccess-bffh-dbgsym
```

oder:

```bash
sudo apt purge fabaccess-bffh
sudo apt purge fabaccess-bffh-dbgsym
```

**Fedora / CentOS / RHEL / Rocky Linux**

<p class="callout info">`dnf` hat **keinen** `purge` Befehl (bei apt kann man deinstallieren oder deinstallieren + restlos bereinigen = purge). Bei `dnf` gibt nur remove!</p>

```bash
sudo dnf remove fabaccess-bffh
```

## Benennung von Debian Paketen

Diese Entscheidungen sind grundlegend, deshalb finden sie hier Ewähnung.

### `fabaccess-bffh` - BFFH Server

Der Server hat mehrere Namen: FabAccess Server, BFFH, bffh, bffhd, Diflouroborane - welcher ist der beste? Wir entscheiden uns für den Paketname `fabaccess-bffh`, weil

- der Paketname relativ klar ist und erlaubt, später weitere Pakete im Zusammenhang `fabaccess-*` zu publizieren
- mit dem Nachteil, dass es etwas länger ist als einfach `bffh` und der systemd Service `bffh` heißt. Das müssen wir im Setup also klar heraus stellen!

# Server - Online Demo Server test.fab-access.org

Du bist neu und willst FabAccess vorher antesten? Dann lohnt sich der Aufwand der Installation vermutlich nicht, bevor du einen ersten Eindruck gewonnen hast. Hier findest du Details zu unserem Demo Server. Informationen zum Download des Clients, den du für das Testen in jedem Fall benötigst, findest du [hier](https://docs.fab-access.org/books/fabaccess-installation/page/downloads-demo "24.04.2022 / Roadmap").

## Zwecke eines Demo-Servers

- Client damit verbinden, um diesen auszuprobieren - die getriggerten Aktionen durch den Server können in einem Log angezeigt werden
- dem Demo-Tester Zugriff auf ein Sample-Grafana-Monitoring geben, was an BFFH gekoppelt ist

## Infos zu test.fab-access.org

Der BFFH Server ist erreichbar unter `test.fab-access.org:59661` und diese Dokumentation unter [https://test.fab-access.org](https://test.fab-access.org) bzw. der konfigurierbaren Shortener-URL [https://y.fab-access.org/testserver](https://y.fab-access.org/testserver). Unser FabAccess Client [Borepin](https://docs.fab-access.org/books/fabaccess-konfiguration/page/client-benutzen-und-typische-konfigurationsfehler-bei-server-und-clients "Client benutzen und typische Konfigurationsfehler bei Server und Clients") ist passend auf `test.fab-access.org` vorkonfiguriert.

Die aktuelle Konfiguration basiert auf dem Demo Setup von [tfom2023](https://gitlab.com/fabinfra/fabaccess/demos-environments/tfom23-demo "03.03.2023 // INTERFACER Abschlussveranstaltung zur Konferenz und Expo "the future of making" (tfom) 2023").

Der Server wurde per Paket installiert - zusammen mit der minimalen Abhängigkeit `mosquitto`.

Aktuell am Laufen (Stand 13.03.2025) ist das [Development-Paket 0.4.4](https://downloads.fab-access.org/bffh-packages/development/fabaccess-bffh_0.4.4_amd64.deb).

Weitere Details zum Installieren ersparen wir uns, da wir diese an geeigneten Stellen ausführlich beschreiben:

- [Server - Installation mit Distributionspaketen (\*:deb, \*.rpm)](https://docs.fab-access.org/books/fabaccess-installation/page/server-installation-mit-distributionspaketen-deb-rpm "Server - Installation mit Distributionspaketen (*:deb, *.rpm)")
- [Server - Anleitung zum selber kompilieren](https://docs.fab-access.org/books/fabaccess-installation/page/server-anleitung-zum-selber-kompilieren "Server - Anleitung zum selber kompilieren")

<p class="callout info">Der Testserver wird stündlich auf die Standardeinstellungen zurückgesetzt (z.B. falls Nutzer gelöscht oder Passwörter verändert wurden).</p>

### Benutzer (users.toml)

Folgende Benutzer (mit verschiedenen Rollen) sind für die Demo freigeschalten (das Passwort ist immer gleich und lautet `secret`).

```ini
[Admin]
roles = ["Admin"]
passwd = "secret"

[Manager]
roles = ["Default", "Manage"]
passwd = "secret"

[Maker]
roles = ["Default", "EuroBox", "LBoxx", "Locker", "Prusa"]
passwd = "secret"

[Maker-Lasercutter]
roles = ["Default", "Lasercutter"]
passwd = "secret"

[Maker-CNC]
roles = ["Default", "CNC"]
passwd = "secret"

[Maker-Printer]
roles = ["Default", "Printer"]
passwd = "secret"

[Bot]
roles = ["Default"]
passwd = "secret"
```

### Hauptkonfiguration (bffh.dhall)

Wir verwenden folgende `bffh.dhall` Hauptkonfiguration:

<details id="bkmrk-bffh.dhall-anzeigen-"><summary>bffh.dhall anzeigen</summary>

```ini
{ listens = [ { address = "test.fab-access.org", port = 59661 } ]
, mqtt_url = "mqtt://fabaccess-defaultuser:fabaccess@localhost:1883"
, auditlog_path = "/var/log/bffh/audit.json"
, db_path = "/var/lib/bffh/bffh.db"
, certfile = "/etc/bffh/certs/bffh.crt"
, keyfile = "/etc/bffh/certs/bffh.key"
, verbosity = 3
, spacename = "TFOM23-Demo"
, instanceurl = "tfom23-demo.fab-access.org"
, roles =
  { Default.permissions = [ "tfom23.disclose", "tfom23.read" ]
  , Admin.permissions =
    [ "tfom23.*", "bffh.users.info", "bffh.users.manage", "bffh.users.admin" ]
  , Manage.permissions = [ "tfom23.manage" ]
  , EuroBox.permissions = [ "tfom23.eurobox.write" ]
  , LBoxx.permissions = [ "tfom23.lboxx.write" ]
  , Locker.permissions = [ "tfom23.locker.write" ]
  , Lasercutter.permissions = [ "tfom23.lasercutter.write" ]
  , Printer.permissions = [ "tfom23.printer.write" ]
  , Prusa.permissions = [ "tfom23.prusa.write" ]
  , CNC.permissions = [ "tfom23.cnc.write" ]
  }
, machines =
  { LBoxx_0 =
    { name = "Filament"
    , description = "LBoxx with 1,75mm PLA"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.lboxx.write"
    , manage = "tfom23.manage"
    , category = "LBoxx"
    , prodable = True
    }
  , LBoxx_1 =
    { name = "FabLock Tools"
    , description = "LBoxx with Tools of the FabLock Project"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.lboxx.write"
    , manage = "tfom23.manage"
    , category = "LBoxx"
    , prodable = True
    }
  , LBoxx_2 =
    { name = "FabReader Tools"
    , description = "LBoxx with Tools of the FabReader Project"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.lboxx.write"
    , manage = "tfom23.manage"
    , category = "LBoxx"
    , prodable = True
    }
  , LBoxx_3 =
    { name = "Sticker"
    , description = "LBoxx with FabAccess Sticker and NTAGs"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.lboxx.write"
    , manage = "tfom23.manage"
    , category = "LBoxx"
    , prodable = True
    }
  , LBoxx_4 =
    { name = "Demo Parts"
    , description = "LBoxx with Parts for the TFOM23 Demo"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.lboxx.write"
    , manage = "tfom23.manage"
    , category = "LBoxx"
    , prodable = True
    }
  , EuroBox_0 =
    { name = "Haribo"
    , description = "EuroBox with Haribo"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.eurobox.write"
    , manage = "tfom23.manage"
    , category = "EuroBox"
    , prodable = True
    }
  , EuroBox_1 =
    { name = "Goldschatz"
    , description = "EuroBox with Rittersport Goldschatz"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.eurobox.write"
    , manage = "tfom23.manage"
    , category = "EuroBox"
    , prodable = True
    }
  , Drawer_0 =
    { name = "Drawer 0 ???"
    , description = "Kallax Drawer"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.locker.write"
    , manage = "tfom23.manage"
    , category = "Locker"
    , prodable = True
    }
  , Drawer_1 =
    { name = "Drawer 1 ???"
    , description = "Kallax Drawer"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.locker.write"
    , manage = "tfom23.manage"
    , category = "Locker"
    , prodable = True
    }
  , Drawer_2 =
    { name = "Drawer 2 ???"
    , description = "Kallax Drawer"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.locker.write"
    , manage = "tfom23.manage"
    , category = "Locker"
    , prodable = True
    }
  , Drawer_3 =
    { name = "Drawer 3 ???"
    , description = "Kallax Drawer"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.locker.write"
    , manage = "tfom23.manage"
    , category = "Locker"
    , prodable = True
    }
  , Door_0 =
    { name = "3D-Printer Accesories"
    , description = "Kallax Door"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.locker.write"
    , manage = "tfom23.manage"
    , category = "Locker"
    , prodable = True
    }
  , Printer_0 =
    { name = "Prusa MK3"
    , description = "FabAccess Prusa MK3"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.prusa.write"
    , manage = "tfom23.manage"
    , category = "Printers"
    }
  , Printer_1 =
    { name = "Other Printer ???"
    , description = "TFOM23 Printer"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.printer.write"
    , manage = "tfom23.manage"
    , category = "Printers"
    }
  , Lasercutter_0 =
    { name = "Other Lasercutter ???"
    , description = "TFOM23 Lasercutter"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.lasercutter.write"
    , manage = "tfom23.manage"
    , category = "Lasercutter"
    }
  , CNC_0 =
    { name = "Some Open Hardware CNC Router"
    , description = "TFOM23 CNC"
    , disclose = "tfom23.disclose"
    , read = "tfom23.read"
    , write = "tfom23.cnc.write"
    , manage = "tfom23.manage"
    , category = "CNC"
    }
  }
, actors =
  { shellyplug-s-C8C9A3B942DB = { module = "Shelly", params = {=} }
  , shellyplug-s-C8C9A3B943D7 = { module = "Shelly", params = {=} }
  , shellyplug-s-C8C9A3B8DB67 = { module = "Shelly", params = {=} }
  , shellyplug-s-3CE90ED72CEF = { module = "Shelly", params = {=} }
  , shellyplug-s-3CE90ED72481 = { module = "Shelly", params = {=} }
  , shellyplug-s-C8C9A3B8E88A = { module = "Shelly", params = {=} }
  , shellyplug-2C94AA = { module = "Shelly", params = {=} }
  , shellyplug-C198E8 = { module = "Shelly", params = {=} }
  , fablock_locker_0 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fablock/main.py --host localhost --fablock 00000 --lock 00000"
      }
    }
  , fablock_locker_1 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fablock/main.py --host localhost --fablock 00000 --lock 00001"
      }
    }
  , fablock_locker_2 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fablock/main.py --host localhost --fablock 00000 --lock 00002"
      }
    }
  , fablock_locker_3 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fablock/main.py --host localhost --fablock 00000 --lock 00003"
      }
    }
  , fablock_locker_4 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fablock/main.py --host localhost --fablock 00000 --lock 00004"
      }
    }
  , fablock_locker_5 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fablock/main.py --host localhost --fablock 00000 --lock 00005"
      }
    }
  , fablock_locker_6 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fablock/main.py --host localhost --fablock 00000 --lock 00006"
      }
    }
  , fablock_lboxx_0 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fablock/main.py --host localhost --fablock 00001 --lock 00000"
      }
    }
  , fablock_lboxx_1 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fablock/main.py --host localhost --fablock 00001 --lock 00001"
      }
    }
  , fablock_lboxx_2 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fablock/main.py --host localhost --fablock 00001 --lock 00002"
      }
    }
  , fablock_lboxx_3 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fablock/main.py --host localhost --fablock 00001 --lock 00003"
      }
    }
  , fablock_lboxx_4 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fablock/main.py --host localhost --fablock 00001 --lock 00004"
      }
    }
  , fabreader_0 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fabreader/main.py --host localhost --fabreader 00000"
      }
    }
  , fabreader_1 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fabreader/main.py --host localhost --fabreader 00001"
      }
    }
  , fabreader_2 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fabreader/main.py --host localhost --fabreader 00002"
      }
    }
  , fabreader_3 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fabreader/main.py --host localhost --fabreader 00003"
      }
    }
  , fabreader_4 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fabreader/main.py --host localhost --fabreader 00004"
      }
    }
  , fabpel_0 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fabpel/main.py --host localhost --fabpel 00000"
      }
    }
  , fabpel_1 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fabpel/main.py --host localhost --fabpel 00001"
      }
    }
  , fabpel_2 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fabpel/main.py --host localhost --fabpel 00002"
      }
    }
  , fabpel_3 =
    { module = "Process"
    , params =
      { cmd = "python"
      , args =
          "tfom23-demo/actors/fabpel/main.py --host localhost --fabpel 00003"
      }
    }
  }
, actor_connections =
  [ { machine = "LBoxx_0", actor = "fablock_lboxx_0" }
  , { machine = "LBoxx_1", actor = "fablock_lboxx_1" }
  , { machine = "LBoxx_2", actor = "fablock_lboxx_2" }
  , { machine = "LBoxx_3", actor = "fablock_lboxx_3" }
  , { machine = "LBoxx_4", actor = "fablock_lboxx_4" }
  , { machine = "EuroBox_0", actor = "fablock_locker_0" }
  , { machine = "EuroBox_1", actor = "fablock_locker_1" }
  , { machine = "Drawer_0", actor = "fablock_locker_2" }
  , { machine = "Drawer_1", actor = "fablock_locker_3" }
  , { machine = "Drawer_2", actor = "fablock_locker_4" }
  , { machine = "Drawer_3", actor = "fablock_locker_5" }
  , { machine = "Door_0", actor = "fablock_locker_6" }
  , { machine = "Printer_0", actor = "shellyplug-s-C8C9A3B942DB" }
  , { machine = "Printer_1", actor = "shellyplug-s-3CE90ED72481" }
  , { machine = "Lasercutter_0", actor = "shellyplug-s-C8C9A3B943D7" }
  , { machine = "CNC_0", actor = "shellyplug-s-C8C9A3B8E88A" }
  , { machine = "Printer_0", actor = "fabreader_1" }
  , { machine = "Printer_1", actor = "fabreader_2" }
  , { machine = "Lasercutter_0", actor = "fabreader_3" }
  , { machine = "CNC_0", actor = "fabreader_4" }
  , { machine = "Printer_0", actor = "fabpel_0" }
  , { machine = "Printer_1", actor = "fabpel_1" }
  , { machine = "Lasercutter_0", actor = "fabpel_2" }
  , { machine = "CNC_0", actor = "fabpel_3" }
  ]
, initiators = {=}
, init_connections = [] : List { machine : Text, initiator : Text }
}
```

</details>

# Server - Raspberry Pi Image flashen / FabAccess Wander-Setup

## Lokaler Demo Server mit Raspberry Pi 3 B+, Fritz!Box 4040 und Tasmota Nous A1T Schaltsteckdosen

Für die JHV des VOW zum 23.11.2024 wurde ein praktisches Demo-Setup angelegt (ein Raspberry Pi, ein Router, ein paar echte Aktoren und ein virtueller Script-Aktor). Dieses Setup wird hier geteilt und seitdem regelmäßig weiterbearbeitet. Es kann inspiziert, heruntergeladen und sogar für die eigene Werkstatt temporär [ausgeliehen](#bkmrk-ausleihen---fabacces) werden.

<p class="callout warning">Da das Erstellen, Komprimieren und Hochladen von Images aufwendig ist und nur in einem sauberen Zustand Sinn macht, hinkt dieses Setup in der Regel den aktuellen Wochen um einige Wochen bis Monate hinterher!</p>

### Wie sieht das Setup aus?

Das Setup basiert auf der Dokumentation [Server - Anleitung zum selber kompilieren](https://docs.fab-access.org/books/fabaccess-installation/page/server-anleitung-zum-selber-kompilieren "Server - Anleitung zum selber kompilieren")

### Raspberry Pi Image Klon erzeugen  


<p class="callout info">Dieser Schritt ist nur zu Informationszwecken abgebildet. Für den Nutzer des Demo Servers wird er nicht benötigt!</p>

Hierzu wurde das SD-Karten Image vom Pi zunächst in eine Datei gedumped:

```bash
DT=$(date '+%Y%m%d')
sudo dd if=/dev/sda of=~/${DT}-fabinfra.img bs=1M status=progress
```

Das Image verkleinern wir dann mit [PiShrink](https://github.com/Drewsif/PiShrink) so, dass es auch auf schmalere SD-Karten passt (Unser Setup hat eine 64 GB SD, aber so lässt es sich auch auf z.B: 32 GB große Karten installieren). Wir installieren PiShrink zunächst:

```bash
sudo apt update && sudo apt install -y wget parted gzip pigz xz-utils udev e2fsprogs
wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh
chmod +x pishrink.sh
sudo mv pishrink.sh /usr/local/bin
```

Dann verkleinern wir das Image:

```bash
sudo pishrink.sh ~/${DT}-fabinfra.img
```

Im Anschluss verkleinern wir das Image nochmals, indem wir es packen. Damit können wir teilweise 20 GB große Images in 5 GB große \*.gz Files komprimieren.

```bash
gzip --best --verbose ~/${DT}-fabinfra.img > ~/${DT}-fabinfra.img.gz
```

### Raspberry Pi Image flashen

Du hast das Image heruntergeladen und möchtest es auf deinen Raspberry Pi 3 B+ installieren? Dafür benötigst du eine wenigsten 32 GB große MicroSD Karte und ein Flashing Tool deiner Wahl.

Wir empfehlen [Balena Etcher](https://etcher.balena.io/). Der Flash-Vorgang ist hier sehr simpel: Image auswählen, Zieldatenträger auswählen, dann Flash! drücken und ein paar Minuten warten. Danach die SD-Karte unmounten und in den Raspberry Pi stecken und boooten. Fertig!

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/WBo6gRcqYpSENtuH-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/WBo6gRcqYpSENtuH-grafik.png)

### Fritz!Box 4040 Einstellungen

Wer eine Fritz!Box 4040 oder eine andere Fritz!Box mit Firmware 8.0.0 oder höher hat, kann die Einstellungen vom Demo-Setup simpel bei seiner eigenen Fritz!Box importieren und testen. Dazu loggen wir uns in die Fritz!Box ein und manövrieren zu `System` → `Sicherung` → `Wiederherstellen`:

<p class="callout info">Das Passwort findet sich in der Auflistung [Übersicht Geräte, Dienste und Credentials](#bkmrk-%C3%9Cbersicht-ger%C3%A4te--un).</p>

.

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/zqPeTPeh5omL2SJH-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/zqPeTPeh5omL2SJH-grafik.png)

### Übersicht Geräte, Dienste und Credentials

**Fritz!Box 4040**

- Hostname: `fabinfra101`
- IPv4-Adresse: `192.168.188.1`
- Web Interface(s): [https://fabinfra101.fritz.box](https://fabinfra101.fritz.box)  
    
    - Benutzer: `fabmin`
    - Passswort: `QDa7YCPB68hYP58rNR89`
- Wifi SSIDs 
    - `fabinfra101_2400` und `fabinfra101_5000`
    - Passwort: `desfire.2019!`
- Für Sicherung/Wiederherstellung der Grundkonfiguration (Sicherungsexport): `fabinfra101`
- Firmware 8.0.0

**Raspberry Pi 3 B+**

- Hostname: `fabaccess`
- IPv4-Adressen: 
    - LAN: `192.168.188.31`
    - Wifi: `192.168.188.34`
- SSH-Zugang 
    - Benutzer: `fabinfra-root`
    - Passswort: `vulca`
- FabAccess Server (BFFH) läuft auf Port `59661`
- Grafana 
    - [http://192.168.188.31:3000](http://192.168.188.31:3000)
    - Admin Benutzer: 
        - Benutzer: `admin`
        - Passwort: `FABfana%2024-`
    - Viewer Benutzer: 
        - Benutzer: `viewer`
        - Passwort: `viewer`
- Prometheus 
    - [http://192.168.188.31:9090](http://192.168.188.31:9090)
    - Basic Auth Benutzer: 
        - Benutzer: `admin`
        - Passwort: `prometheus`
- Mosquitto MQTT Server 
    - Adresse: `192.168.188.31:1883`
    - Benutzer: `fabinfra101`
    - Passwort: `fablocal`

**Aktoren**

In unserem Demo-Setup sind 6 Nous A1T Schaltsteckdosen mit Tasmota Firmware vorkonfiguriert. Außerdem findet sich ein Sound Aktor zur Wiedergabe einer mp3 per Audioklinke (3,5mm) wieder.

- Schaltsteckdosen Nous A1T mit Tasmota Firmware 14.3.0
- Hostname: `tasmota_1` bis `tasmota_6`
- IP-Adresse: `192.168.188.41` bis `192.168.188.46`
- Web-Interface: [http://192.168.188.41](http://192.168.188.41) bis [http://192.168.188.46](http://192.168.188.46)
- Web Benutzer (überall gleich): 
    - Benutzer: `admin`
    - Passwort: `fabinfra101`


**Ressourcenliste**

[maschinenliste.csv](https://downloads.fab-access.org/rpi3bplus-demo-setup/maschinenliste.csv) (erstellt für und genutzt mit [FabAccess Config Generator](https://docs.fab-access.org/books/fabaccess-konfiguration/page/einfache-konfiguration-mit-dem-fabaccess-config-generator "Einfache Konfiguration mit dem FabAccess Config Generator")).

### Downloads

- Raspberry Pi 3 B+ SD-Card Image Dump (\*.gz Format)
- Fritz!Box 4040 Konfigurationsbackup (Firmware 8.0.0)
- Anleitungsdokumente
- Ressourcenliste (als ODS für PDF/CSV Export und Import in FabAccess Config Generator)
- URL: [https://downloads.fab-access.org/?dir=rpi3bplus-demo-setup](https://downloads.fab-access.org/?dir=rpi3bplus-demo-setup)

<details id="bkmrk-anleitungsdokumente-"><summary>Anleitungsdokumente anzeigen</summary>

<iframe height="450vh" id="bkmrk--3" src="https://docs.fab-access.org/pdfjs/web/viewer.html?file=https%3A%2F%2Fdownloads.fab-access.org%2Frpi3bplus-demo-setup%2FDemo%2520Server%2520Ausdrucke.pdf" title="PDF viwer" width="100%"></iframe>

</details>## Ausleihen - FabAccess Wander-Setup  


Wer FabAccess als Demo ausprobieren will, kann sich die vorkonfigurierte Demo-Hardware ausleihen und damit herumtesten - als "FabAccess Wander-Setup" sozusagen. Hierzu tretet in Kontakt mit [Mario Voigt](https://offene-werkstaetten.org/users/profile/2520). Er ist Maintainer des Setups und der Hardware. Er kümmert sich um

- Leihvertrag (mit Kaution/Pfand für die Hardware)
- Zurücksetzen der Konfiguration
- Versand der Hardware

Die Inhaltsliste des Wander-Setups umfasst:

- 1x Fritz!Box 4040 mit Firmware 8.0.0, Netzteil
- 1x Raspberry Pi 3 B+ mit 64 GB SD-Karte und Netzteil
- 1x Ethernet-Kabel
- 3x Steckdosenleiste 3-fach
- 6x Nous A1T Schaltsteckdosen inklusive [Safebox](https://docs.fab-access.org/books/schalten-und-messen-von-230-v/page/steckerschutz-und-sicherheitsplomben "Steckerschutz und Sicherheitsplomben")
- eine Hand voll FabAccess Sticker
- [Anleitungsdokumente](https://downloads.fab-access.org/rpi3bplus-demo-setup/Demo%20Server%20Ausdrucke.pdf) als Ausdruck
- Alles funktional vorkonfiguriert!
- **Kaution: Gesamtwert der Hardware liegt bei ca. 150 €**

Noch benötigt von euch:

- Zeit zum Testen
- ein paar Geräte, die in die Tasmota Schaltsteckdosen angesteckt werden können
- Endgeräte mit vorinstalliertem [Client](https://docs.fab-access.org/books/fabaccess-installation/page/downloads-demo "Downloads / Demo")

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/8iJhi92GeLdSLsQD-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/8iJhi92GeLdSLsQD-grafik.png)

# Client (alle Plattformen) - Anleitung zum selber kompilieren

Dieser Guide stellt Grundlagen dar, die es braucht, um das Borepin-Projekt auf verschiedenen Betriebssystemen auszuchecken und erfolgreich zu kompilieren. Alle weiteren Details zum Umgang bedürfen Grundkenntnissen der Programmier- und Entwicklungstätigkeit mit C#, UWP, MAUI/Xamarin, Prism und Co.

## Unter Windows

Für die Kompilierung des FabAccess Clients Borepin benötigen wir verschiedene Komponenten:

### Installation von Mono GTKSharp  


<p class="callout warning">Mono wird nicht mehr weiterentwickelt. Wir nutzen das letzte Release 2.12.45 vom 14.11.2022</p>

- Releases: [https://github.com/mono/gtk-sharp/releases/](https://github.com/mono/gtk-sharp/releases/)
- Direkter Downloadlink: [https://github.com/mono/gtk-sharp/releases/download/2.12.45/gtk-sharp-2.12.45.msi](https://github.com/mono/gtk-sharp/releases/download/2.12.45/gtk-sharp-2.12.45.msi)

### Installation von Cap'n Proto  


#### Variante 1

Downloads: [https://capnproto.org](https://capnproto.org/install.html#installation-windows)

Nach dem Entpacken muss das Verzeichnis mit den Executables per in Umgebungsvariable `%PATH%` eingebunden werden, zum Beispiel `C:\Program Files (x86)\capnproto-c++-win32-1.1.0\capnproto-tools-win32-1.1.0`:

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/pEJmZLJfhslfh6m9-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/pEJmZLJfhslfh6m9-grafik.png)

#### Variante 2

Installation mit [Chocolatey](https://chocolatey.org/install). Chocolatey selbst kann zum Beispiel über die Windows Shell (`<a href="https://docs.chocolatey.org/en-us/choco/setup/#install-with-cmdexe">cmd.exe</a>`) oder PowerShell ([`powershell.exe`](https://docs.chocolatey.org/en-us/choco/setup/#install-with-powershell.exe)) installiert werden, oder auch über das praktische Update-Utility [UniGetUI](https://github.com/marticliment/UniGetUI) (wird automatisch mitinstalliert).

```kotlin
choco install capnproto
```

<details id="bkmrk-ausgabe-von-chocolat"><summary>Ausgabe von chocolatey</summary>

```powershell
PS C:\Users\thuja> choco install capnproto
Chocolatey v2.2.2
Directory 'C:\Users\thuja\AppData\Local\UniGetUI\Chocolatey\lib' does not exist.
Installing the following packages:
capnproto
By installing, you accept licenses for the packages.
Progress: Downloading capnproto 1.0.2... 100%

capnproto v1.0.2 [Approved]
capnproto package files install completed. Performing other installation steps.
The package capnproto wants to run 'chocolateyinstall.ps1'.
Note: If you don't run this script, the installation will fail.
Note: To confirm automatically next time, use '-y' or consider:
choco feature enable -n allowGlobalConfirmation
Do you want to run the script?([Y]es/[A]ll - yes to all/[N]o/[P]rint): y

Downloading capnproto
  from 'https://capnproto.org/capnproto-c++-win32-1.0.2.zip'
Progress: 100% - Completed download of C:\Users\thuja\AppData\Local\Temp\chocolatey\capnproto\1.0.2\capnproto-c++-win32-1.0.2.zip (4.41 MB).
Download of capnproto-c++-win32-1.0.2.zip (4.41 MB) completed.
Hashes match.
Extracting C:\Users\thuja\AppData\Local\Temp\chocolatey\capnproto\1.0.2\capnproto-c++-win32-1.0.2.zip to C:\Users\thuja\AppData\Local\UniGetUI\Chocolatey\lib\capnproto\tools...
C:\Users\thuja\AppData\Local\UniGetUI\Chocolatey\lib\capnproto\tools
 ShimGen has successfully created a shim for capnp.exe
 ShimGen has successfully created a shim for capnpc-c++.exe
 ShimGen has successfully created a shim for capnpc-capnp.exe
 The install of capnproto was successful.
  Software installed to 'C:\Users\thuja\AppData\Local\UniGetUI\Chocolatey\lib\capnproto\tools'

Chocolatey installed 1/1 packages.
 See the log for details (C:\Users\thuja\AppData\Local\UniGetUI\Chocolatey\logs\chocolatey.log).
```

</details>### Installation von Microsoft Visual Studio 2022 Community Edition

Das Setup wurde zuletzt mit Version `17.12.3` getestet.

- [Download](https://visualstudio.microsoft.com/de/downloads/) des Installers (ältere Versionen benötigen eine aktive Subscription - das ist nicht empfehlenswert)
- Folgende Pakete werden außerdem benötigt. Die folgende Konfigurationsdatei `.vsconfig` kann im Setup `VisualStudioSetup.exe` geladen werden:

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/X4cNUkLOd7inMdja-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/X4cNUkLOd7inMdja-grafik.png)

```json
{
  "version": "1.0",
  "components": [
    "Microsoft.VisualStudio.Component.CoreEditor",
    "Microsoft.VisualStudio.Workload.CoreEditor",
    "Microsoft.Net.Component.4.8.SDK",
    "Microsoft.Net.Component.4.7.2.TargetingPack",
    "Microsoft.Net.ComponentGroup.DevelopmentPrerequisites",
    "Microsoft.VisualStudio.Component.TypeScript.TSServer",
    "Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions",
    "Microsoft.VisualStudio.Component.JavaScript.TypeScript",
    "Microsoft.VisualStudio.Component.JavaScript.Diagnostics",
    "Microsoft.VisualStudio.Component.Roslyn.Compiler",
    "Microsoft.Component.MSBuild",
    "Microsoft.VisualStudio.Component.Roslyn.LanguageServices",
    "Microsoft.VisualStudio.Component.TextTemplating",
    "Microsoft.VisualStudio.Component.NuGet",
    "Microsoft.VisualStudio.Component.SQL.CLR",
    "Microsoft.Component.ClickOnce",
    "Microsoft.VisualStudio.Component.ManagedDesktop.Core",
    "Microsoft.NetCore.Component.Runtime.9.0",
    "Microsoft.NetCore.Component.Runtime.8.0",
    "Microsoft.NetCore.Component.SDK",
    "Microsoft.VisualStudio.Component.FSharp",
    "Microsoft.ComponentGroup.ClickOnce.Publish",
    "Microsoft.NetCore.Component.DevelopmentTools",
    "Microsoft.VisualStudio.Component.AppInsights.Tools",
    "Microsoft.Net.Component.4.8.TargetingPack",
    "Microsoft.Net.ComponentGroup.4.8.DeveloperTools",
    "Microsoft.VisualStudio.Component.DiagnosticTools",
    "Microsoft.VisualStudio.Component.EntityFramework",
    "Microsoft.VisualStudio.Component.Debugger.JustInTime",
    "Component.Microsoft.VisualStudio.LiveShare.2022",
    "Microsoft.VisualStudio.Component.IntelliCode",
    "Component.VisualStudio.GitHub.Copilot",
    "Microsoft.NetCore.Component.Runtime.6.0",
    "microsoft.net.runtime.mono.tooling",
    "microsoft.net.runtime.mono.tooling.net8",
    "Microsoft.VisualStudio.Component.Windows11SDK.22621",
    "maui.core",
    "maui.blazor",
    "microsoft.net.runtime.android.net8",
    "microsoft.net.runtime.android.aot.net8",
    "microsoft.net.runtime.android",
    "microsoft.net.runtime.android.aot",
    "android",
    "Component.OpenJDK",
    "Microsoft.VisualStudio.Component.MonoDebugger",
    "Microsoft.VisualStudio.Component.Merq",
    "Microsoft.VisualStudio.ComponentGroup.Maui.Android",
    "runtimes.ios",
    "microsoft.net.runtime.ios",
    "runtimes.ios.net8",
    "microsoft.net.runtime.ios.net8",
    "ios",
    "Component.Xamarin.RemotedSimulator",
    "Microsoft.VisualStudio.ComponentGroup.Maui.iOS",
    "runtimes.maccatalyst",
    "microsoft.net.runtime.maccatalyst",
    "runtimes.maccatalyst.net8",
    "microsoft.net.runtime.maccatalyst.net8",
    "maccatalyst",
    "Microsoft.VisualStudio.ComponentGroup.Maui.MacCatalyst",
    "maui.windows",
    "Microsoft.VisualStudio.ComponentGroup.MSIX.Packaging",
    "Microsoft.VisualStudio.ComponentGroup.Maui.Windows",
    "Microsoft.VisualStudio.ComponentGroup.Maui.Blazor",
    "Microsoft.VisualStudio.ComponentGroup.WebToolsExtensions.TemplateEngine",
    "Microsoft.VisualStudio.ComponentGroup.Maui.Shared",
    "Microsoft.VisualStudio.ComponentGroup.Maui.All",
    "Component.Android.SDK.MAUI",
    "Component.Xamarin",
    "Microsoft.VisualStudio.Workload.NetCrossPlat",
    "Microsoft.VisualStudio.Component.ManagedDesktop.Prerequisites",
    "Microsoft.VisualStudio.Component.DotNetModelBuilder",
    "Microsoft.VisualStudio.ComponentGroup.WindowsAppSDK.Cs",
    "Microsoft.ComponentGroup.Blend",
    "Microsoft.VisualStudio.Workload.ManagedDesktop",
    "Microsoft.VisualStudio.Component.Windows10SDK.19041",
    "Microsoft.Component.NetFX.Native",
    "Microsoft.VisualStudio.Component.Graphics",
    "Microsoft.VisualStudio.ComponentGroup.UWP.Xamarin",
    "Microsoft.VisualStudio.ComponentGroup.UWP.Support",
    "Microsoft.VisualStudio.Component.WindowsAppSdkSupport.CSharp",
    "Microsoft.VisualStudio.ComponentGroup.WindowsAppDevelopment.Prerequisites",
    "Microsoft.VisualStudio.ComponentGroup.UWP.NetCoreAndStandard",
    "Microsoft.VisualStudio.Workload.Universal",
    "Microsoft.NetCore.Component.Runtime.3.1",
    "Microsoft.NetCore.Component.Runtime.7.0"
  ],
  "extensions": []
}
```

Bzw. in Screenshots sieht das so aus:

[![5.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/6brrFTDABAF5bW3Z-5.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/6brrFTDABAF5bW3Z-5.png) [![4.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/S85jj7mUTaZQkBC1-4.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/S85jj7mUTaZQkBC1-4.png) [![3.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/kWhioFvJGRg5tn3b-3.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/kWhioFvJGRg5tn3b-3.png) [![2.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/9pnCtqxrA9IE3hgW-2.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/9pnCtqxrA9IE3hgW-2.png) [![1.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/rbY6ldcF1tuSfmT4-1.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/rbY6ldcF1tuSfmT4-1.png)

<p class="callout danger">**Achtung**: Die installierte Visual Studio Umgebung ist ca. 25-35 Gigabyte groß und die Installation dauert u.U. über eine Stunde!</p>

### Installation von Multilingual App Toolkit v4.1 (VS 2022+) für Visual Studio  


Zum Internationalisieren von Borepin können wir das Multilingual App Toolkit nachinstallieren: [https://marketplace.visualstudio.com/items?itemName=dts-publisher.mat2022](https://marketplace.visualstudio.com/items?itemName=dts-publisher.mat2022)

[![Bildschirmfoto_20241229_175848.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/wipVHH26NyKybFwY-bildschirmfoto-20241229-175848.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/wipVHH26NyKybFwY-bildschirmfoto-20241229-175848.png)

### Borepin Projekt mit Git klonen

An einem geeigneten Ort das Projekt auschecken.

```bash
git clone https://gitlab.com/fabinfra/fabaccess/borepin.git --recurse-submodules
git checkout main
```

### Projekt kompilieren  


Wir öffnen die Datei `Borepin.sln` im Hauptordner des Projektes. Beim ersten Start von Visual Studio werden u.U. verschiedene Dependencies nachgeladen. Das kann ein Weilchen dauern.

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/8seh7FZ5F9I0dlj8-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/8seh7FZ5F9I0dlj8-grafik.png)

Zielarchitektur (z.B. x86, x64, arm) und Ausgabetype (Debug, Release) können in der oberen Leiste ausgewählt werden:

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/HpFUdTOJIbwXxmUt-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/HpFUdTOJIbwXxmUt-grafik.png)

Über den kleinen grünen Play-Button können wir das Projekt schlussendlich compilen. Dieser Vorgang dauert u.U. ca. 5-10 Minuten. Zeit für eine kurze Kaffeepause ☕.

Das fertige Kompilat für [UWP](https://docs.fab-access.org/books/awesome-fabinfra/page/glossar-begrifflichkeiten-und-abkurzungen#bkmrk-uwp-%28universal-windo "Glossar (Begrifflichkeiten und Abkürzungen)") wird dann beispielsweise in `\Borepin\Borepin.UWP\bin\x86\Debug\` abgelegt. Dieses ist **nicht** standlone ausführbar. Das heißt, dass wir dafür Visual Studio benötigen. Für eine distributierbare (veröffentlichte) Version als \*.appx-Format siehe Kapitel [App veröffentlichen (Standalone Anwendung lokal installieren via "Sideload")](#bkmrk-app-ver%C3%B6ffentlichen-).

<p class="callout info">Bei etwaigen Kompilierproblemen wird ein Systemneustart empfohlen, falls die obigen Abhängigkeiten erstmalig installiert wurden.</p>

### App veröffentlichen (Standalone Anwendung lokal installieren via "Sideload")

Zum Publishen von Borepin wählen wir rechts im Projektstrukturbaum `Borepin.UWP` aus und klicken rechts auf `Veröffentlichen`→ `App-Pakete erstellen ...`. Dabei erstellen wir ein App-Paket vom Typ `Querladen` (Sideload) und klicken uns mit den Standardwerten durch. Nachdem wir den Button `Erstellen` klicken geht der Prozess los. Dieser dauert je nach Hardwareressourcen 10 - 15 Minuten. Zeit für noch eine gute Kaffeepause ☕.

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/1cieJQ3q5W6KHSo5-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/1cieJQ3q5W6KHSo5-grafik.png) [![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/e4NJvKMSA0UQqXjs-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/e4NJvKMSA0UQqXjs-grafik.png) [![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/qsBnvNLKW8x1vanK-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/qsBnvNLKW8x1vanK-grafik.png) [![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/CaFXbTEwMLeMbJzz-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/CaFXbTEwMLeMbJzz-grafik.png)

Das fertige App-Paket befindet sich dann unter `\Borepin\Borepin.UWP\AppPackages\Borepin.UWP_1.0.0.0_Test\`.

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2025-02/scaled-1680-/P7Mha1Sp6yQKN2jf-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2025-02/P7Mha1Sp6yQKN2jf-grafik.png)

Dieser Ordner hält für die Installation folgende für uns relevanten Dateien bereit, die wir ausführen müssen (PowerShell). Als zusätzliche kleine Hürde muss dafür jedoch noch eine Policy **einmalig** ausgehebelt werden (siehe [https:/go.microsoft.com/fwlink/?LinkID=135170](https://docs.fab-access.org/https:/go.microsoft.com/fwlink/?LinkID=135170)).

Wir starten eine als Administrator privilegierte Shell und führen im Verzeichnis des App-Pakets aus:

```
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope CurrentUser
```

Dann können wir das Paket installieren:

```
.\Add-AppDevPackage.ps1
.\Install.ps1
```

Letztendlich finden wir die installierte Testversion dann im Startmenü:

[![Bildschirmfoto_20241229_172325.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/DrCImi35Nw6h7Kdi-bildschirmfoto-20241229-172325.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/DrCImi35Nw6h7Kdi-bildschirmfoto-20241229-172325.png) [![Bildschirmfoto_20241229_172416.png](https://docs.fab-access.org/uploads/images/gallery/2024-12/scaled-1680-/hbyyBd6BZLjeXcWe-bildschirmfoto-20241229-172416.png)](https://docs.fab-access.org/uploads/images/gallery/2024-12/hbyyBd6BZLjeXcWe-bildschirmfoto-20241229-172416.png)

## macOS / iOS

Der Kompilierprozess ist ähnlich zu Windows, da wir auch für macOS Visual Studio installieren können. Allerdings wurde Visual Studio zum 31.08.2024 von Microsoft [offiziell abgekündigt](https://learn.microsoft.com/en-us/visualstudio/releases/2022/what-happened-to-vs-for-mac). Es wird nur noch [Visual Studio Code](https://code.visualstudio.com/docs/csharp/get-started) (kurz: *VS Code)* unterstützt.

### Installation von Cap'n Proto

```bash
brew install capnproto
```

<p class="callout warning">Nach dem Installieren muss u.U. die capnp Binary per Symlink in `/usr/local/bin` oder in `$PATH` eingebettet werden.</p>

Weitere Details für macOS / iOS sind aus Mangel an Support derzeit nicht vorhanden. Wir freuen uns über entsprechende Zuarbeiten.

## Linux GTK

Auf Linux benötigen wir das große Paket für [Mono](https://www.mono-project.com/download/stable/#download-lin). Mono ist eine alternative, quelloffene Implementierung von Microsofts .NET Framework. Sie ermöglicht die Entwicklung von plattformunabhängiger Software auf den Standards der Common Language Infrastructure und der Programmiersprache C#.

Wir arbeiten hier nicht mit einer IDE, sondern direkt von Kommandozeile. Wer eine IDE testen möchte, der kann [MonoDevelop](https://www.monodevelop.com/download/) oder [JetBrains Rider](https://www.jetbrains.com/rider/) ausprobieren.

### Ubuntu 24 LTS

Auf Ubuntu 24 LTS gehen wir wie folgt vor:

```559222
# Mono Repository hinzufügen
sudo apt install ca-certificates gnupg
sudo gpg --homedir /tmp --no-default-keyring --keyring /usr/share/keyrings/mono-official-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
echo "deb [signed-by=/usr/share/keyrings/mono-official-archive-keyring.gpg] https://download.mono-project.com/repo/ubuntu stable-focal main" | sudo tee /etc/apt/sources.list.d/mono-official-stable.list
sudo apt update

# Mono und weitere Pakete installieren
sudo apt install mono-complete gtk-sharp2 libcanberra-gtk-module nuget capnproto git
```

```bash
nuget update -self
```

Projekt klonen

```bash
cd ~/
git clone https://gitlab.com/fabinfra/fabaccess/borepin.git --recurse-submodules
cd borepin/
```

Unbenötigte Projekte entladen/entfernen. Wir benötigen in unserem Fall nur Borepin.GTK

```108222
# Entfernen, was wir nicht brauchen
rm -rf ./Borepin/Borepin.Android/
rm -rf ./Borepin/Borepin.UWP/
rm -rf ./Borepin/Borepin.iOS/
rm -rf ./Borepin/Borepin.macOS/
rm -rf ./Borepin_Test/
rm -rf ./FabAccessAPI_Test/

# diese Einträge entfernen wir außerdem in:
vim Borepin.sln

nuget restore
```

Projekt kompilieren

```550768
msbuild /restore
msbuild -p:Configuration=Debug -t:Borepin_GTK
```

Borepin starten

```bash
cd ~/client/Borepin/Borepin.GTK/bin/Debug/

# mit "mono" vorangestellt
mono ./Borepin.GTK.exe

# oder direkt
./Borepin.GTK.exe
```

<p class="callout danger">**Das konnte aktuell nicht erfolgreich durchgeführt werden! Der StackTrace:**</p>

```bash
(Borepin.GTK:4704): Gtk-WARNING **: 01:31:17.439: Im Modulpfad »adwaita« konnte keine Themen-Engine gefunden werden,
Exception in Gtk# callback delegate
  Note: Applications can use GLib.ExceptionManager.UnhandledException to handle the exception.
System.NullReferenceException: Object reference not set to an instance of an object
  at Xamarin.Forms.Platform.GTK.Platform.GetRenderer (Xamarin.Forms.VisualElement element) [0x00000] in <db5c3415edd24a4aa8ae86f8bebc9a57>:0 
  at Xamarin.Forms.Platform.GTK.FormsWindow.OnConfigureEvent (Gdk.EventConfigure evnt) [0x00033] in <db5c3415edd24a4aa8ae86f8bebc9a57>:0 
  at Gtk.Widget.configureevent_cb (System.IntPtr widget, System.IntPtr evnt) [0x00014] in <7aab76e87bce48a4b45cf7fa613cb70c>:0 
  at GLib.ExceptionManager.RaiseUnhandledException (System.Exception e, System.Boolean is_terminal) [0x00000] in <ed39f21b9e9343dcbd442a17ad356a9f>:0 
  at Gtk.Widget.configureevent_cb (System.IntPtr widget, System.IntPtr evnt) [0x00000] in <7aab76e87bce48a4b45cf7fa613cb70c>:0 
  at Gtk.Application.gtk_main () [0x00000] in <7aab76e87bce48a4b45cf7fa613cb70c>:0 
  at Gtk.Application.Run () [0x00000] in <7aab76e87bce48a4b45cf7fa613cb70c>:0 
  at Borepin.GTK.MainClass.Main (System.String[] args) [0x00000] in <674198d89d1447e7b051f706516309ae>:0 
```

Das Ausführen mit [Wine](https://www.winehq.org/), winetricks und dotnet45 ist leider ebenso nicht erfolgreich.

```bash
sudo apt install wine winetricks
winetricks dotnet45

#Borepin starten
wine ~/client/Borepin/Borepin.GTK/bin/Debug/Borepin.GTK.exe
```

### ArchLinux

```bash
pacman -S mono mono-msbuild gtk-sharp-2 nuget capnproto
```

## Android  


Diese Anleitung beschreibt, wie ein Cross-Compile für Android auf einem Windows-Betriebssystem gelingt.

Mögliche IDEs sind JetBrains Rider oder Microsoft Visual Studio. Wir verwenden in dieser Dokumentation Visual Studio 2022 (mit .dotNET 7 und Xamarin). Siehe [Installation von Microsoft Visual Studio 2022 Community Edition](#bkmrk-installation-von-mic). Für JetBrains Rider wird das Plugin [https://github.com/Flying--Dutchman/RiderXamarinAndroid](https://github.com/Flying--Dutchman/RiderXamarinAndroid) benötigt.

### Schritte (verkürzt)

- Borepin Projekt mit Git klonen
- capnproto Executable in %PATH% einfügen
- nuget via chocolatey installieren
- [Android Studio](https://developer.android.com/studio?hl=de) installieren 
    - [Android SDK für Android 11](https://developer.android.com/about/versions/11/setup-sdk?hl=de)
        - Klicken Sie auf Tools → SDK-Manager → Paketdetails anzeigen
        - Maximieren Sie auf dem Tab SDK-Plattformen den Bereich Android 11.0 („R“) und wählen Sie das Paket Android SDK-Plattform 30 aus
        - Maximieren Sie auf dem Tab SDK-Tools den Bereich Android SDK Build-Tools 34 und wählen Sie die neueste `30.x.x`-Version aus.
        - Klicken Sie auf Übernehmen → OK, um die ausgewählten Pakete herunterzuladen und zu installieren
    - [Android NDK](https://developer.android.com/ndk/downloads?hl=de)
- Java 17 ([Microsoft OpenJDK 17](https://learn.microsoft.com/de-de/java/openjdk/download)) installieren
- In Visual Studio 
    - Tools → Options → Xamarin/Android Settings → die passende, soeben installierte Java Version und ggf. SDKs auswählen
    - Entladen Sie die Projekte Borepin.iOS, Borepin.UWP und Borepin.macOS, um Fehler zu vermeiden, die Ihren Build abbrechen
- Projekt Borepin.Android auswählen und kompilieren

## Testing

Dafür nutzen wir [NUnit](https://nunit.org). NUnit ist ein Unit-Testing-Framework für alle .Net-Sprachen. Ursprünglich von JUnit portiert, wurde es mit vielen neuen Funktionen und Unterstützung für eine breite Palette von .NET-Plattformen komplett neu geschrieben.

# Client für Android - HowTo: F-Droid Repository einbinden

Wer FabAccess nicht über den Google PlayStore installieren möchte, kann stattdessen F-Droid benutzen.

F-Droid ist ein alternativer Store Ersatz für den Google PlayStore auf Android. Damit lassen sich viele Apps auch ohne Google Account installieren. Allerdings muss dafür zunächst der F-Droid Store installiert werden und im Anschluss bedarf es dem Einbinden einer externen Paketquelle (die von FabAccess).

Download des F-Droid Paketmanagers (Vorraussetzung): [https://f-droid.org/de](https://f-droid.org/de)

<details id="bkmrk-1.-quelle-hinzuf%C3%BCgen"><summary>1. Quelle hinzufügen</summary>

Wir öffnen im gestarteten F-Droid `Einstellungen` → `Paketquellen (Zusätzliche Paketquellen hinzufügen)` → `+`

[![fdroid1.png](https://docs.fab-access.org/uploads/images/gallery/2024-10/scaled-1680-/GHhKLx0cv6petFSi-fdroid1.png)](https://docs.fab-access.org/uploads/images/gallery/2024-10/GHhKLx0cv6petFSi-fdroid1.png)

Wir fügen den Link der Paketquelle ein: [https://fdroid.fab-access.org/fdroid/repo](https://fdroid.fab-access.org/fdroid/repo)

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2025-03/scaled-1680-/4rN5h7pfinDKM7wR-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2025-03/4rN5h7pfinDKM7wR-grafik.png)

[![fdroid2.png](https://docs.fab-access.org/uploads/images/gallery/2024-10/scaled-1680-/9HCu4qR15NWPKcwi-fdroid2.png)](https://docs.fab-access.org/uploads/images/gallery/2024-10/9HCu4qR15NWPKcwi-fdroid2.png)[![fdroid3.png](https://docs.fab-access.org/uploads/images/gallery/2024-10/scaled-1680-/C3O8IfodiGwywtwF-fdroid3.png)](https://docs.fab-access.org/uploads/images/gallery/2024-10/C3O8IfodiGwywtwF-fdroid3.png)

</details><details id="bkmrk-nach-fabaccess-suche"><summary>2. Nach FabAccess suchen und App installieren</summary>

Nach Einbinden und Aktualisieren sollte die Suche erfolgreich sein, wenn nach "fabaccess" gesucht wird:

[![fdroid5.png](https://docs.fab-access.org/uploads/images/gallery/2024-10/scaled-1680-/NRRGMBPzUlswnh1l-fdroid5.png)](https://docs.fab-access.org/uploads/images/gallery/2024-10/NRRGMBPzUlswnh1l-fdroid5.png)[![fdroid6.png](https://docs.fab-access.org/uploads/images/gallery/2024-10/scaled-1680-/OYhxXPIXOLTBBmAO-fdroid6.png)](https://docs.fab-access.org/uploads/images/gallery/2024-10/OYhxXPIXOLTBBmAO-fdroid6.png)

</details>

# Client für Linux - mit Waydroid installieren

Waydroid ist ein unter [GNU GPL v3](https://github.com/waydroid/waydroid/blob/main/LICENSE) lizensierter und einer von vielen gängigen Emulatoren für Android auf Linux-Systemen. Wir nutzen es, um **FabAccess** für Linux verfügbar zu machen (alternativ zum [GTK Mono Client Build](https://docs.fab-access.org/books/fabaccess-installation/page/client-alle-plattformen-anleitung-zum-selber-kompilieren "Client (alle Plattformen) - Anleitung zum selber kompilieren")). Waydroid verwendet einen [LXC](https://linuxcontainers.org/)-Unterbau (Container, ähnlich Docker), um zu spawnen. Wir berufen uns grundlegend auf die offizielle Dokumentation unter [https://docs.waydro.id/usage/install-on-desktops](https://docs.waydro.id/usage/install-on-desktops).

## Intro

Es gibt zu viele Linux-Distros, um auf jede einzugehen, was die Installation angeht. Auf dieser Seite finden sich Details zum Setup auf Kubuntu (analog: Debian, Ubuntu) und Fedora (analog: CentOS).

Diese Dokumentation beruht auf folgenden Beispielsystemen:

- OS: Kubuntu 24.04 und Fedora 40, jeweils mit aktiviertem Wayland
- Waydroid 1.5.0 mit LineageOS 18.1 (Android 11)

## Erfordernisse (Requirements)

Die benötigten Systemeigenschaften sind in [https://wiki.archlinux.org/title/Waydroid#Wayland\_session\_manager](https://wiki.archlinux.org/title/Waydroid#Wayland_session_manager) beschrieben.

- CPU/Architektur: [https://developer.android.com/ndk/guides/abis?hl=de#sa](https://developer.android.com/ndk/guides/abis?hl=de#sa)
- GPU: Intel oder AMD; **nicht** **Nvidia**
- Display Session: Wayland; **nicht X11**
- ca. 1 GB Speicherplatz (für die Images und libhoudini)
- ca. 400-500MB RAM

<p class="callout info">Es wurde berichtet, dass Waydroid auf auch Raspberry Pi's laufen kann!</p>

### One-Liner: Setup als fertiges Bash Script

Folgende einzelne Zeile installiert das aktuellste FabAccess Borepin Release automatisch und vollständig auf Linux-Systemen:

```bash
curl -L -s https://y.fab-access.org/waydroid | bash
```

Wer dem Kurzlink [https://y.fab-access.org/waydroid](https://y.fab-access.org/waydroid) nicht traut, der kann folgende voll ausgeschriebene Zeile verwenden:

```bash
curl -s https://gitlab.com/fabinfra/fabaccess/borepin/-/raw/main/waydroid-installer.sh | bash
```

### Das grundlegende Setup  


Wer das Setup manuell durchführen möchte, kann auch alle nachfolgenden Schritte verfolgen.

Kubuntu:

```bash
sudo apt update && sudo apt upgrade
sudo apt install curl ca-certificates -y
curl -s https://repo.waydro.id | sudo bash
sudo apt install waydroid -y

# Die installierte Waydroid Version checken
dpkg -l | grep waydroid

#Init ausführen (Images installieren)
# Folgendes Images werden dabei automatisch von https://sourceforge.net/projects/waydroid/files/images/system/lineage/waydroid_x86_64/ geladen:
# - LineageOS 18.1 (20241102 VANILLA) - das Image ist ca. 800 MB groß
# - LineageOS 18.1 (20241102 MAINLINE) - das Image ist ca. 180 MB groß
sudo waydroid init
```

Fedora

```bash
sudo dnf update
curl -s https://repo.waydro.id | sudo bash
sudo dnf install waydroid -y

# Die installierte Waydroid Version checken
dnf list installed | grep waydroid

#Init ausführen (Images installieren)
# Folgendes Images werden dabei automatisch von https://sourceforge.net/projects/waydroid/files/images/system/lineage/waydroid_x86_64/ geladen:
# - LineageOS 18.1 (20241102 VANILLA) - das Image ist ca. 800 MB groß
# - LineageOS 18.1 (20241102 MAINLINE) - das Image ist ca. 180 MB groß
sudo waydroid init --system_channel https://ota.waydro.id/system --vendor_channel https://ota.waydro.id/vendor --rom_type lineage --system_type VANILLA
```

### Fehlerbehebung (Fedora)

Falls das bisherige Setup mit Fehlern scheitert, müssen ggf. die SELinux Regeln für `systemd` und `waydroid` angepasst werden:

```bash
ausearch -c 'systemctl' --raw | audit2allow -M my-systemctl
semodule -X 300 -i my-systemctl.pp

ausearch -c 'waydroid' --raw | audit2allow -M my-waydroid
semodule -X 300 -i my-waydroid.pp
```

Temporär - d.h. nur Testweise - kann auch mit `<a href="https://www.tecmint.com/disable-selinux-in-centos-rhel-fedora/">setentforce 0</a>` gearbeitet werden.

Etwaige Anpassungen sind außerdem an der Config von Nöten, falls "Failed to load config for waydroid" auftritt (siehe auch Issue [493](https://github.com/waydroid/waydroid/issues/493) und [652](https://github.com/waydroid/waydroid/issues/652)):

```bash
sudo vim /var/lib/waydroid/lxc/waydroid/config
```

Auskommentieren:

```bash
#lxc.apparmor.profile = unconfined
```

## Service und Logs

Waydroid wird automatisch als Service installiert und auch gestartet. Wir können den Service starten, stoppen und neustarten, und darüberhinaus Logs auslesen:

```bash
sudo systemctl status waydroid-container.service
sudo systemctl start waydroid-container.service
sudo systemctl stop waydroid-container.service
sudo systemctl restart waydroid-container.service

# Journal und Log File:
sudo journalctl -f -u waydroid-container.service
sudo less /var/lib/waydroid/waydroid.log

#oder kurz:
waydroid log

#oder über LXc:
sudo lxc-info -P /var/lib/waydroid/lxc -n waydroid -sH
```

## Python pip und venv installieren

Kubuntu:

```bash
sudo apt install python3-pip python3-venv
```

Fedora:

```bash
sudo dnf install python3-pip python3-venv
```

## Zwischenablage (Clipboard) reparieren

Bei der Installation klappt u.U. die geteilte Zwischenablage nicht. In diesem Fall benötigt es die folgenden Pakete.

Kubuntu:

```bash
sudo dnf install wl-clipboard
```

Fedora:

```bash
sudo apt install wl-clipboard
```

und dann:

```bash
sudo pip install pyclip --break-system-packages #unsauberer Trick. Hat jemand eine bessere Lösung?
```

### Session starten

```bash
# als normaler Nutzer
waydroid session start

# oder im Hintergrund:
nohup waydroid session start &
```

## Optionen konfigurieren  


Wir stellen an ein paar Schrauben!

<p class="callout info">Für das Ausführen muss eine Waydroid Session bereits laufen!</p>

#### Multi-Window Option setzen

Aktiviert/deaktiviert die Fensterintegration mit dem Desktop

```bash
waydroid prop set persist.waydroid.multi_windows true
```

#### Auflösung des Fensters anpassen  


Standardmäßig wird die Session im Vollbildmodus gestartet. Auf einem großen Monitor ist das ggf. screcklich. Das lässt sich optional setzen. Siehe [https://github.com/waydroid/waydroid/issues/700](https://github.com/waydroid/waydroid/issues/700)

```bash
# Zum Zurücksetzen der Standardeinstellungen folgendes ausführen:
waydroid prop set persist.waydroid.width ""
waydroid prop set persist.waydroid.height ""

# Höhe aus Breite berechnen per Verhältnis (z.B. 16:9):
#width = 900 / 16 * 9 =~ 506
waydroid prop set persist.waydroid.height 900
waydroid prop set persist.waydroid.width 506
```

## Netzwerk-Traffic zwischen Gast und Host erlauben

Falls nach der Installation Anwendungen in Waydroid keine Internetverbindung haben, fehlt möglicherweise eine Konfiguration in der Firewall und/oder in einem Waydroid-Script. Siehe auch [https://github.com/waydroid/waydroid/issues/143](https://github.com/waydroid/waydroid/issues/143)

### Fix in Waydroid Script

```bash
sudo sed -i -E 's/=.\$\(command -v (nft|ip6?tables-legacy).*/=/g' /usr/lib/waydroid/data/scripts/waydroid-net.sh
sudo systemctl restart waydroid-container.service
```

## ARM-Builds auf x86-Systemen erlauben (libhoudini) und mehr  


Normalerweise wird Waydroid vermutlich eher auf einem x86-System installiert werden. Android Applications (APKs) sind aber häufig nur für arm7/arm8 kompiliert. Dafür gibt es einen Workaround namens **libhoudini.** Dafür nutzen wir folgendes Script aus dem Projekt [https://github.com/casualsnek/waydroid\_script](https://github.com/casualsnek/waydroid_script). Wir legen uns eine virtuelle Umgebung (venv) für das Projekt an und installieren die Requirements.

```bash
# als normaler Nutzer
cd ~
git clone https://github.com/casualsnek/waydroid_script
cd waydroid_script/

python3 -m venv venv
venv/bin/pip install --upgrade pip
venv/bin/pip install -r requirements.txt
```

Danach führen wir aus und wählen **libhoudini** aus:

```bash
sudo venv/bin/python3 main.py
```

[![image.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/RZAwlomhv75m9MRF-image.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/RZAwlomhv75m9MRF-image.png)

[![image.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/TtoeTbStGpKrLlTs-image.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/TtoeTbStGpKrLlTs-image.png)

Mit der Leertaste können Pakete ab- oder zugewählt werden:

[![image.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/IjllzIoVsix6UYxB-image.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/IjllzIoVsix6UYxB-image.png)

Danach startet die Installation. libhoudini ist ca. 100 MB groß.

Wir können das Menü auch überspringen und einen vollständigen CLI-Befehl eingeben:

```bash
sudo venv/bin/python3 main.py --android-version 11 install libhoudini
```

## FabAccess Client (Borepin) installieren

Wir laden den Client als APK-Datei direkt herunter:

```bash
# als normaler Nutzer
cd ~
wget https://gitlab.com/api/v4/projects/20862588/packages/generic/borepin/v0.3.11/org.fab_infra.fabaccess-Signed.apk
waydroid app install org.fab_infra.fabaccess-Signed.apk

# wir prüfen, ob das geklappt hat:
waydroid app list | grep fabaccess

# der Output sollte sein:
packageName: org.fab_infra.fabaccess
```

Siehe auch [Downloads / Demo](https://docs.fab-access.org/books/fabaccess-installation/page/downloads-demo#bkmrk-borepin-%28mobile-app%29)

## Waydroid Client anzeigen und benutzen  


Nachdem der Container gestartet ist und die Session läuft, können wir das User Interface anzeigen:

```bash
# als normaler Nutzer
waydroid show-full-ui
```

Die Standardoberfläche bei/nach dem Start:

[![image.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/8OxDYVeaoW6aFzL4-image.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/8OxDYVeaoW6aFzL4-image.png)

Und letztlich Borepin in Waydroid starten:

<p class="callout info">Der Kaltstart von Borepin bzw. Waydroid kann ca. 30-60 Sekunden dauern.</p>

[![image.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/VLWZsqBCBt38qdIK-image.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/VLWZsqBCBt38qdIK-image.png)

## Waydroid in einem Fenster anzeigen

Unter Wayland hat das Client-Fenster leider keine Drag&amp;Drop-Funktion. Wir können es in einen Rahmen einsperren, in dem wir das Tool "cage" verwenden

Kubuntu:

```bash
sudo apt install cage
```

Fedora:

```bash
sudo dnf install cage
```

 und dann Waydroid ins Fenster zwingen:

```bash
cage waydroid show-full-ui
```

Dadurch erhalten wir folgende Ansicht:

[![image.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/ujS69Ur8i9FB7Yzc-image.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/ujS69Ur8i9FB7Yzc-image.png)

## FabAccess Borepin aus dem Startmenü heraus starten

Waydroid wird standardmäßig in das Menü eingebunden:

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/ZauZmdOM8ev7CykW-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/ZauZmdOM8ev7CykW-grafik.png)

Im Menü-Editor kann dieser Eintrag auch angesehen werden:

[![grafik.png](https://docs.fab-access.org/uploads/images/gallery/2024-11/scaled-1680-/89OcIKtNVe1z37ep-grafik.png)](https://docs.fab-access.org/uploads/images/gallery/2024-11/89OcIKtNVe1z37ep-grafik.png)

## FabAccess Borepin per Kommandozeile starten

Das geht auch:

```matlab
waydroid app launch org.fab_infra.fabaccess
```

oder mit Cage:

```matlab
cage waydroid app launch org.fab_infra.fabaccess
```

## Waydroid Upgrade

Waydroid bekommt regelmäßig Updates. Wir können mit folgendem Befehl aktualisieren:

```bash
sudo waydroid upgrade
```

Das im Hintergrund befindliche Base-Image für das Betriebssystem macht sich auch visuell bemerkbar und kann direkt per `Download` aktualisiert werden:

[![Bildschirmfoto_20250106_173317.png](https://docs.fab-access.org/uploads/images/gallery/2025-01/scaled-1680-/lnj7bIQB6M6RZWCY-bildschirmfoto-20250106-173317.png)](https://docs.fab-access.org/uploads/images/gallery/2025-01/lnj7bIQB6M6RZWCY-bildschirmfoto-20250106-173317.png)

## Drag &amp; Drop Fenster

Durch Gedrückthalten der `Super`-Taste (in der Regel die Taste zwischen linkem `Ctrl` und `Alt`) und Anklicken einer beliebigigen Stelle des Wayland-Fensters kann dieses an die gewünschte Stelle verschoben werden.