Jails statt Container: Warum FreeBSD-Jails für Isolation ausreichen — und Docker überflüssig machen können

Docker ist überall. Jedes Tutorial, jeder Workshop, jeder Stack-Overflow-Thread — alles dreht sich um Container. Und ehrlich: Das hat Gründe. Docker hat die Bereitstellung von Software radikal vereinfacht. Aber hier ist die unbequeme Frage, die sich kaum jemand stellt: Was macht Docker eigentlich, das ein Betriebssystem nicht schon kann?

Die Antwort, die ich im Lauf der Jahre gefunden habe, lautet: Erstaunlich wenig — wenn das Betriebssystem FreeBSD heißt.

Dieser Artikel ist mein Versuch, die Diskussion über Container-Isolation neu aufzurollen — nicht als Docker-Bashing, sondern als ehrlicher technischer Vergleich zwischen zwei Philosophien, die das gleiche Problem auf grundverschiedene Weise lösen.

Was ist ein Jail?

Ein FreeBSD-Jail ist, auf den Punkt gebracht, ein chroot mit Netzwerk. Und das ist nicht abwertend gemeint — es ist die präzise Beschreibung.

Wenn du unter Linux chroot /mein/verzeichnis ausführst, hast du einen Prozess, der ein anderes Dateisystem-Root sieht. Aber er teilt sich den Kernel, die Netzwerk-Interfaces, die Prozess-Tabelle, die User-IDs — alles. Ein chroot isoliert das Dateisystem, aber sonst nichts. Deswegen heisst es auch nicht umsonst chroot — change root, nicht isolate.

Ein Jail geht weiter. Viel weiter. Ein Jail-Prozess bekommt:

  • Ein eigenes Dateisystem-Root (wie chroot)
  • Ein eigenes Netzwerk-Interface (eigene IP, eigener Hostname)
  • Eine eigene Prozess-Tabelle (Prozesse im Jail sehen nur andere Prozesse im Jail)
  • Eigene User-IDs (root im Jail ist nicht root auf dem Host)
  • Eigene Netzwerk-Stacks (eigene Ports, eigene Firewall-Regeln möglich)

Und das alles ohne einen Hypervisor. Ohne Virtualisierung. Ohne Emulation. Der Kernel läuft weiter — ein einziger Kernel, der die Isolation direkt bereitstellt, und das als Design.

So sieht das in der Praxis aus:

jail -c path=/jails/webapp host.hostname=webapp.example.com \
  ip4.addr=192.168.1.10 command=/bin/sh

Das war’s. Kein Dockerfile. Kein Build-Kontext. Keine Registry. Ein Befehl, und du hast einen isolierten Prozess, der in seinem eigenen Teil des Systems läuft.

Jails existieren seit dem Jahr 2000. Sie waren da, als Linux noch über chroot stolperte und Container ein Konzept war, das man in Vorlesungen über Betriebssysteme erwähnte. FreeBSD hat das Problem der Prozessisolation vor über 25 Jahren im Kernel gelöst — und die Lösung ist bis heute stabil, sicher und geradezu banal einfach.

Docker-Anatomie: Der Zoo

Lass uns einen Schritt zurücktreten und anschauen, was Docker eigentlich ist. Nicht die Marketing-Version. Die echte Architektur.

Docker besteht aus:

  • dockerd — Ein Daemon, der im Hintergrund läuft und alle Container verwaltet. Er hat Root-Rechte. Er lauscht auf einem Socket. Er ist ein Single Point of Failure und ein Single Point of Compromise.
  • Docker Registry — Docker Hub (oder eine private Registry), wo Images gespeichert werden. Du pullst Images, du pushst Images. Du hängst an der Verfügbarkeit einer externen Infrastruktur.
  • Image Layers — Jedes Image besteht aus Schichten. Jede Schicht ist ein diff über der vorherigen. Das macht Images transportabel, aber es erzeugt einen ganzen Stack von Overlay-Dateisystemen, der zur Laufzeit übereinander gelegt wird.
  • Dockerfile — Ein eigenes Build-Format mit eigener Syntax. FROM, RUN, COPY, ENTRYPOINT. Ein Mini-Package-Manager-Ökosystem in Textform.
  • Eigener Package-Managerapk in Alpine, apt in Debian-Images, oft gemischt. Docker hat keinen eigenen Package-Manager, aber es zwingt dich, den der Base-Distribution zu nutzen — innerhalb eines Build-Contexts, der isoliert vom Rest deines Systems ist.
  • Docker Compose — Weil ein Container selten allein kommt. Du brauchst ein YAML-File, um mehrere Container zu orchestrieren. Compose ist de facto ein eigenes Tool mit eigener Syntax und eigenen Konventionen.
  • Swarm / Kubernetes — Weil Compose nicht für Produktion reicht. Swarm ist praktisch tot. Kubernetes ist… Kubernetes. Ein eigenes Ökosystem mit eigenem Vokabular, eigenen Konzepten, eigener Komplexität.

Das ist ein ganzer Zoo. Und ich meine das nicht nur umgangssprachlich. Docker hat sich von einem Tool zur Prozessisolation zu einer Plattform entwickelt, die ein eigenes Betriebssystem innerhalb deines Betriebssystems aufbaut. Eigene Networking-Lösung. Eigene Storage-Treiber. Eigene Build-Pipeline. Eigene Orchestrierung.

Wenn du Docker einsetzt, betreibst du ein Schichtenmodell:

Hardware → Host-OS → Docker-Daemon → Container-Runtime → Overlay-FS → Container

Jede Schicht hat ihre eigenen Fehlerquellen, ihre eigenen Konfigurationsmöglichkeiten, ihre eigenen Bugs. Und jede Schicht nimmt dir Kontrolle ab und gibt dir Abstraktion. Ob das ein fairer Trade ist, hängt davon ab, was du brauchst. Aber es ist ein Trade — und den sollte man mit offenen Augen machen.

Jail-Anatomie: Das, was übrig bleibt, wenn man alles weglässt

Jetzt der Kontrast. Ein FreeBSD-Jail besteht aus:

  • Kernel-Isolation — Der FreeBSD-Kernel bietet Isolation direkt an. Kein Daemon dazwischen. Keine Runtime. Der Kernel ist die Runtime.
  • Netzwerk-Isolation — Jedes Jail bekommt sein eigenes IP-Interface. Kein NAT nötig (aber möglich). Kein Bridge-Netzwerk, das du erst verstehen musst. Einfach eine IP, und der Traffic kommt an.
  • Dateisystem-Isolation — Das Jail-Root ist ein Verzeichnis. Alles darunter gehört zum Jail. Alles außerhalb existiert für Prozesse im Jail nicht.

Und das war’s. Kein Daemon. Keine Registry. Keine Layer. Kein Build-System. Keine YAML-Datei mit 40 Zeilen, um drei Services zu starten.

Die Verwaltung sieht so aus:

# Jail starten
jail -c path=/jails/webapp host.hostname=webapp ip4.addr=192.168.1.10 \
  command=/sbin/init

# Jail stoppen
jail -r webapp

# Jail-Konfiguration (persistent)
# /etc/jail.conf:
webapp {
    path = /jails/webapp;
    ip4.addr = 192.168.1.10;
    host.hostname = webapp.example.com;
    mount.devfs;
    exec.start = "/bin/sh /etc/rc";
    exec.stop = "/bin/sh /etc/rc.shutdown";
}

Das ist die komplette Konfiguration. Kein YAML. Keine Environment-Variablen, die durch drei Dateien gereicht werden. Keine Networks, die du erst definieren musst. Die Konfiguration ist lesbar, greifbar, debuggbar.

Wenn etwas schiefgeht, greifst du auf die Standard-FreeBSD-Tools zurück. ps, top, sockstat, dmesg — alles funktioniert wie gewohnt, weil es ein echtes System ist, kein Container-Abstraktionslayer.

Die ZFS-Verbindung: Instant-Cloning

Hier wird es spannend. FreeBSD und ZFS sind ein Traumpaar — und Jails profitieren davon massiv.

Stell dir vor, du willst eine neue Instanz deiner Web-Anwendung aufsetzen. Mit Docker: Image pullen, Container starten. Mit Jail und ZFS geht etwas viel Eleganters:

# Snapshot des Basis-Jails erstellen
zfs snapshot zroot/jails/base@clean

# Klonen — dauert Sekundenbruchteile, dank Copy-on-Write
zfs clone zroot/jails/base@clean zroot/jails/webapp2

# Jail konfigurieren und starten
# (Eintrag in /etc/jail.conf)
jail -c webapp2

Das war’s. Der Clone ist da. Sofort. Kein Download. Kein Layer-Aufbau. Kein Caching. ZFS nutzt Copy-on-Write, also belegt der Clone initially keinen zusätzlichen Speicherplatz. Erst wenn sich Dateien zwischen Clone und Original unterscheiden, wird Platz belegt.

Und das Beste: Du kannst das automatisieren. Ein kleines Skript, das einen ZFS-Snapshot nimmt, klont, die Jail-Konfiguration anpasst, und fertig. Kein CI/CD-Pipeline nötig, die ein Docker-Image baut und pusht. Du kannst es natürlich trotzdem tun — aber du musst nicht.

pkgbase: Sauberes Base-System-Management

FreeBSD bietet seit einiger Zeit pkgbase — Pakete für das Base-System. Das bedeutet, du kannst das FreeBSD-Base-System innerhalb eines Jails wie jedes andere Paket aktualisieren:

pkg install FreeBSD-base-default
pkg upgrade FreeBSD-base-default

Statt freebsd-update in jedem Jail laufen zu lassen oder das Base-System manuell zu bauen, kannst du Versionierte, reproduzierbare Base-System-Pakete nutzen. In Kombination mit ZFS-Snapshots bedeutet das: Du kannst ein Jail auf eine bestimmte Base-Version zurückrollen, ohne dass irgendwelche Overlay-Layer involviert sind.

Das ist reproduzierbar. Das ist transparent. Das ist genau das, was Docker mit seinen Layer-Caching verspricht, aber tatsächlich nur mühsam nachbaut.

Praktischer Vergleich: Eine Web-Anwendung deployen

Lass uns das konkret machen. Wir wollen eine typische Web-Anwendung deployen: Nginx als Reverse Proxy, eine App (sagen wir: eine Go-Binary), und PostgreSQL als Datenbank.

Mit Docker

  1. Dockerfile schreiben — Basis-Image wählen, Abhängigkeiten installieren, Binary hineinkopieren. 15-30 Zeilen.
  2. docker-compose.yml schreiben — Drei Services definieren. Netzwerk konfigurieren. Volumes für persistente Daten. Environment-Variablen. 40-60 Zeilen.
  3. Image bauendocker build -t meineapp .. Dauer: 30 Sekunden bis 10 Minuten, je nach Caching und Komplexität.
  4. Image pushen — Auf eine Registry, damit der Server es pullen kann. docker push meineapp:latest.
  5. Auf dem Server pullendocker pull meineapp:latest.
  6. Startendocker-compose up -d.
  7. Prüfendocker ps, docker logs, docker exec -it ...

Fehlerquellen:

  • Image-Layer-Caching führt zu veralteten Abhängigkeiten
  • Der Docker-Daemon muss laufen
  • Netzwerk zwischen Containern ist ein Bridge-Netzwerk mit eigenen Eigenheiten
  • Volumes werden vergessen oder falsch gemountet
  • Environment-Variablen müssen durchgereicht werden
  • Image-Grösse bläht auf, weil jeder Layer seinen eigenen Overhead hat

Mit FreeBSD-Jails

  1. ZFS-Dataset für das Jail erstellenzfs create zroot/jails/webapp
  2. Base-System installierenpkgbase oder bsdinstall oder aus einem Snapshot klonen.
  3. Jail konfigurieren — Eintrag in /etc/jail.conf. 10 Zeilen.
  4. Pakete installieren — Im Jail: pkg install nginx postgresql16-server. Oder du installierst deine Go-Binary direkt per scp oder pkg install.
  5. Services konfigurieren — Standard FreeBSD-Konfiguration. /etc/rc.conf im Jail, Nginx-Konfig, PostgreSQL-Konfig.
  6. Jail startenservice jail start webapp
  7. Prüfenjls, jexec webapp ps aux, Standard-Logs unter /var/log

Fehlerquellen:

  • Konfigurationsfehler (wie überall)
  • Aber: Kein Daemon, der abstürzen kann
  • Kein Overlay-Filesystem, das korrumpiert
  • Keine Layer, die sich unerwartet verhalten
  • Netzwerk ist echtes Netzwerk — was du konfigurierst, ist was du bekommst

Der Unterschied ist nicht nur die Anzahl der Schritte. Es ist die Art der Komplexität. Bei Docker ist die Komplexität in der Toolchain. Bei Jails ist die Komplexität im System — aber das System ist transparent, dokumentiert, und verhält sich wie erwartet, weil es ein echtes Betriebssystem ist, kein Abstraktionslayer.

Security: Isolation per Design vs. Isolation nachgerüstet

Dies ist der Punkt, der mich am meisten bewegt.

FreeBSD-Jails existieren seit dem Jahr 2000. Sie wurden von Anfang an als Isolationsmechanismus designt. Die Sicherheitsgarantien sind Teil des Kernel-Designs:

  • Ein Prozess in einem Jail kann nicht auf Prozesse ausserhalb zugreifen.
  • Ein Prozess in einem Jail kann nicht Kernel-Module laden.
  • Ein Prozess in einem Jail kann nicht Netzwerk-Interfaces ausser seinem eigenen sehen.
  • root in einem Jail ist nicht root auf dem Host.

Diese Garantien sind nicht optional. Sie sind nicht ein Config-Flag, das du setzen kannst — oder vergessen kannst. Sie sind die Default-Annahme des Systems.

Docker? Docker lief jahrelang mit Containern, die als root liefen. Die Standard-Konfiguration gab Containern volle Root-Rechte auf dem Host. User-Namespaces wurden erst 2016 eingeführt — und waren jahrelang experimentell. Seccomp-Profile kamen hinzu, aber die Standard-Profile waren lasch und komplexe Profile waren schwer zu schreiben. Capability-Dropping existiert, aber die meisten Container liefen (und laufen) mit zu vielen Capabilities.

Die Geschichte von Container-Security unter Linux ist eine Geschichte von Nachbesserungen. Jedes Jahr kamen neue Mechanismen hinzu: Namespaces, cgroups, Seccomp, AppArmor, SELinux, User-Namespaces, Rootless-Mode. Jeder einzelne Mechanismus ist sinnvoll. Aber zusammen ergeben sie ein Patchwork, das tiefes Expertenwissen erfordert, um es korrekt zu konfigurieren.

FreeBSD-Jails? Da gibt es nichts nachzurüsten. Die Isolation war 2000 da. Sie ist 2026 immer noch da. Und sie hat sich bewährt — in Produktion, in Hosting-Umgebungen, in Firmen, die seit Jahrzehnten Jails betreiben.

25 Jahre getestete Kernel-Isolation vs. ein Patchwork aus nachgerüsteten Linux-Mechanismen.

Ein konkretes Beispiel

Stell dir vor, ein Angreifer bekommt Shell-Zugriff in deinem Container.

Im Docker-Container (ohne User-Namespaces):

  • Der Angreifer ist root.
  • Er kann alle Prozesse im Container sehen.
  • Er kann Netzwerk-Verbindungen des Hosts potenziell sehen (je nach Konfiguration).
  • Er kann Capabilities ausnutzen, die der Container hat.
  • Escalation zum Host ist historisch wiederholt gelungen.

Im Jail:

  • Der Angreifer sieht nur Prozesse im Jail.
  • Er sieht nur das Netzwerk-Interface des Jails.
  • Selbst als root im Jail kann er nicht auf den Host zugreifen.
  • Escalation erfordert einen Kernel-Bug — und FreeBSD hat eine exzellente Security-Historie.

Der Unterschied ist architektonisch, nicht konfiguratorisch.

Performance: Direkter Zugriff vs. Layer-Stack

Performance ist nicht das wichtigste Argument für Jails — aber es ist ein schönes Nebenargument.

Ein Docker-Container läuft auf einem Overlay-Filesystem. Das bedeutet: Jeder Schreibzugriff geht durch einen Layer-Stack. OverlayFS (oder AUFS, oder Btrfs, oder Device Mapper — je nachdem, was du konfiguriert hast) muss bei jedem Dateizugriff prüfen, in welchem Layer die Datei liegt. Das kostet Zeit. Bei vielen kleinen Schreibzugriffen (Datenbanken, Logs) spürst du das.

Ein Jail läuft auf einem echten Dateisystem. ZFS, UFS — was immer du nutzt. Kein Overlay. Keine Layer-Auflösung. Direkter Zugriff. Punkt.

Dann der Daemon: Docker hat dockerd. Ein Prozess, der im Hintergrund läuft, Ressourcen verbraucht, und ein Angriffsziel ist. Jails haben keinen Daemon. Der Kernel macht die Isolation. Kein Prozess, der sterben kann. Kein Prozess, den du überwachen musst.

Und Layer-Caching? Docker macht viel Aufwand darum, Layer zwischen Images wiederzuverwenden. Das ist clever, aber es ist ein Workaround für ein Problem, das gar nicht existieren müsste. Mit ZFS und pkgbase hast du Copy-on-Write und geteilte Datasets. Gleicher Effekt, weniger Komplexität.

Die Zahlen sprechen für sich, auch wenn der Unterschied bei einfachen Workloads marginal ist:

MetrikDockerJail
Startup-Zeit0.5-3s0.1-0.5s
Dateisystem-OverheadOverlay-LayerNativ (ZFS/UFS)
Daemon-OverheadJa (dockerd)Nein
Netzwerk-OverheadBridge/NATNativ (direkt oder NAT)
Memory-OverheadContainer-RuntimeNur Kernel

Bei hunderten von Jails/Containern macht das einen messbaren Unterschied. Bei ein paar dutzend ist es vernachlässigbar — aber es ist trotzdem ein Unterschied, der auf architektonischer Eleganz beruht, nicht auf Micro-Optimierung.

Wann Docker Sinn macht — und wann Jails die bessere Wahl sind

Ich bin kein Dogmatiker. Docker hat seinen Platz. Lass uns ehrlich sein:

Docker ist die bessere Wahl, wenn:

  • Du Microservices deployst, die von Dritten kommen. Wenn jemand ein Docker-Image bereitstellt, ist es einfacher, das zu nutzen, als es in ein Jail zu portieren.
  • Du in einem Team arbeitest, das Docker kennt. Das ist vielleicht das wichtigste Argument. Docker ist die Lingua franca der DevOps-Welt. Neue Kollegen kennen Docker. Jails müssen sie erst lernen.
  • Du Kubernetes brauchst. K8s ist das Standard-Orchestrierungstool. Es funktioniert mit Docker (oder containerd). Es gibt kein Äquivalent für Jails — und das wird es wahrscheinlich auch nie geben.
  • Du Cloud-native arbeitest. AWS, GCP, Azure — sie alle bieten native Docker-Unterstützung. FreeBSD-Jails auf AWS? Machbar, aber du bist auf dich gestellt.
  • Du schnelle Prototypen brauchst. docker run -it ubuntu bash ist schneller als ein Jail aufzusetzen — es sei denn, du hast einen ZFS-Snapshot bereit.

Jails sind die bessere Wahl, wenn:

  • Du dein eigenes Hosting betreibst. Eigener Server, eigenes Rechenzentrum, eigene Infrastruktur. Hier hast du die volle Kontrolle und kannst Jails optimal nutzen.
  • Du langfristige Stabilität willst. FreeBSD und Jails sind seit Jahrzehnten stabil. Keine Breaking Changes im Isolations-Modell. Kein Daemon, der updated werden muss.
  • Du Security ernst nimmst. Kernel-level Isolation statt nachgerüsteter Linux-Mechanismen. Kein Daemon mit Root-Rechten.
  • Du Einfachheit schätzt. Weniger Moving Parts. Weniger, was kaputtgehen kann. Standard-Betriebssystem-Werkzeuge statt eines ganzen Ökosystems.
  • Du ZFS nutzt. Die Kombination aus Jails und ZFS ist mächtiger als Docker je sein kann — Instant-Cloning, Snapshots, Replication, Deduplizierung. Alles nativ, alles integriert.
  • Du Vollständige Kontrolle willst. Über das Betriebssystem, über die Isolation, über die Netzwerk-Konfiguration. Jails geben dir die volle Macht des Betriebssystems, nicht die Teilmenge, die Docker freigibt.

Die ehrliche Wahrheit ist: Die meisten kleinen bis mittleren Deployments brauchen kein Kubernetes. Sie brauchen kein Docker-Ökosystem. Sie brauchen Isolation, Reproduzierbarkeit und Einfachheit. Und genau das bieten Jails.

Die Philosophie: FreeBSD vertraut dem Admin, Docker vertraut dem Workflow

Hier wird es philosophisch — und das ist der Kern meines Arguments.

Docker vertraut dem Workflow. Docker sagt: „Wir machen es einfach, Container zu bauen, zu „verschiffen“ und zu orchestrieren. Du musst nicht verstehen, wie das Betriebssystem funktioniert. Du musst verstehen, wie Docker funktioniert.“ Und das funktioniert — solange du in Dockers Workflow bleibst. Wenn du etwas ausserhalb des Workflows brauchst, wird es kompliziert. Eigene Netzwerk-Konfiguration? Da gibt es ein Plugin. Eigene Storage-Lösung? Da gibt es einen Volume-Treiber. Eigenes Orchestrierung? Da gibt es… naja, Kubernetes.

FreeBSD vertraut dem Admin. FreeBSD sagt: „Hier ist ein mächtiges Betriebssystem mit 30 Jahren Erfahrung. Hier sind die Werkzeuge. Du weisst, was du tust. Mach dein Ding.“ Jails sind ein Werkzeug im Werkzeugkasten, nicht das gesamte Werkzeugkasten-Inventar. Du kannst sie mit ZFS kombinieren, mit pf konfigurieren, mit Ansible automatisieren, mit devfs feinabstimmen. Alles ist kombinierbar, weil alles Teil desselben Betriebssystems ist.

Das ist ein fundamentaler Unterschied in der Design-Philosophie:

  • Docker abstrahiert das Betriebssystem weg. Der Container ist die Einheit. Das Betriebssystem darunter ist ein Implementierungsdetail.
  • FreeBSD gibt dir das Betriebssystem als Plattform. Der Jail ist ein Feature des Betriebssystems, kein Ersatz dafür.

Beide Ansätze haben ihre Berechtigung.

Wenn du ein Linux-Admin bist, der Docker nutzt, kennst du das Gefühl: „Warum funktioniert dieser Container lokal, aber nicht in Produktion?“ Overlay-Filesystem-Unterschiede. Netzwerk-Konfiguration. Environment-Variablen. Volume-Mounts. Jede Schicht kann ein Problem sein.

Mit Jails? Wenn es im Jail funktioniert, funktioniert es. Weil das Jail ein echtes Betriebssystem ist. Keine Überraschungen.

Die Sache mit dem Ökosystem

Ein Argument, das oft gegen Jails vorgebracht wird: „Docker hat ein riesiges Ökosystem. Jails haben das nicht.“

Stimmt. Docker Hub hat Millionen von Images. Für Jails gibt es keine zentrale Registry.

Aber lass uns ehrlich sein: Wie viele dieser Millionen Images nutzt du wirklich? Und wie viele davon sind veraltet, unsicher, oder einfach schlechte Basis-Images?

In der Praxis brauchst du eine Handvoll gut gepflegter Basis-Images. Und die kannst du dir mit Jails leicht selbst bauen. Ein ZFS-Snapshot eines sauberen FreeBSD-Base-Systems, und du hast dein eigenes „Image“ — reproduzierbar, versioniert, effizient.

Ausserdem: Die Abhängigkeit von Docker Hub ist ein Risiko. Images verschwinden. Tags werden überschrieben. Die Registry kann ausfallen. Mit einem eigenen ZFS-basierten Jail-Setup bist du unabhängig.

Und was Automatisierung angeht: Tools wie Ansible, Salt, oder einfache Shell-Skripte arbeiten mit Jails genauso gut wie mit Docker. Vielleicht nicht so elegant wie ein docker-compose up, aber dafür transparent und nachvollziehbar.

Der praktische Betrieb: Jails im Alltag

Lass mich einen typischen Arbeitsablauf beschreiben, wie ich ihn auf meinen Servern nutze:

Neuen Service aufsetzen

# 1. ZFS-Dataset für das Jail erstellen
zfs create zroot/jails/myservice

# 2. Von einem sauberen Base-Snapshot klonen
zfs clone zroot/jails/base@clean zroot/jails/myservice

# 3. Jail-Konfiguration hinzufügen
cat >> /etc/jail.conf << 'EOF'
myservice {
    path = /jails/myservice;
    ip4.addr = 192.168.1.20;
    host.hostname = myservice.example.com;
    mount.devfs;
    exec.start = "/bin/sh /etc/rc";
    exec.stop = "/bin/sh /etc/rc.shutdown";
}
EOF

# 4. Jail starten
service jail start myservice

# 5. Pakete installieren
jexec myservice pkg install nginx

# 6. Konfigurieren und loslegen
jexec myservice sysrc nginx_enable=YES

Das dauert — mit einem guten Base-Snapshot — unter einer Minute. Und ich habe die volle Kontrolle über jeden Schritt.

Update eines Jails

# Snapshot vor dem Update (zur Sicherheit)
zfs snapshot zroot/jails/myservice@pre-update

# Update durchführen
jexec myservice pkg upgrade

# Wenn etwas schiefgeht: Rollback
zfs rollback zroot/jails/myservice@pre-update

Kein Image-Rebuild. Kein Cache-Invalidation. Snapshot, Update, fertig. Oder Rollback, wenn nötig.

Migration auf einen anderen Server

# ZFS-Dataset senden (inkrementell möglich!)
zfs send zroot/jails/myservice@latest | ssh newserver zfs recv zroot/jails/myservice

Ein Befehl. Das gesamte Jail — Dateisystem, Konfiguration, alles — wird auf den neuen Server übertragen. Inkrementelle Updates? zfs send -i mit Snapshots. Effizient, schnell, zuverlässig.

Vergleiche das mit docker save und docker load. Oder mit einer Registry. Oder mit docker-compose und Environment-Variablen, die du manuell übertragen musst. ZFS send/recv ist eleganter, weil es auf Dateisystem-Ebene arbeitet — und weil es von einem Werkzeug stammt, das seit 2005 in Produktion ist.

Was Docker besser macht (und warum das okay ist)

Ich will fair sein. Docker hat Dinge, die Jails nicht bieten:

  1. Portabilität. Ein Docker-Image läuft auf jedem Linux-System mit Docker. Ein Jail läuft nur auf FreeBSD. Wenn du heterogene Infrastruktur hast, ist Docker die bessere Wahl.
  2. Ökosystem. Docker Hub, Docker Compose, Docker Swarm, Kubernetes — das Ökosystem ist riesig und gut dokumentiert. Für Jails gibt es Bastille und pot, aber sie sind kein K8s.
  3. Entwickler-Workflow. docker build und docker push sind etabliert. CI/CD-Pipelines unterstützen Docker nativ. Jails erfordern mehr manuelle Arbeit in der Pipeline.
  4. Cloud-Integration. Jeder Cloud-Provider bietet native Container-Support. FreeBSD-Jails musst du selbst betreiben.

Aber — und das ist wichtig — diese Vorteile sind Ökosystem-Vorteile, keine technischen Vorteile. Docker ist populärer, nicht besser isoliert. Docker hat mehr Werkzeuge, nicht sicherere Isolation. Docker ist bequemer, nicht performanter.

Wenn du dich für Docker entscheidest, tust du das wegen des Ökosystems, nicht wegen der Technologie. Und das ist eine legitime Entscheidung — solange du dir bewusst bist, dass es eine Entscheidung für Bequemlichkeit und gegen Einfachheit ist.

Die Philosophie (nochmal, tiefer)

Ich möchte nochmal auf die Philosophie zurückkommen, weil sie mich nicht loslässt.

Die Container-Bewegung hat einen wichtigen Punkt gebracht: Prozesse sollten isoliert sein. Das ist richtig. Das ist gut. Das ist etwas, das FreeBSD seit dem Jahr 2000 weiss.

Aber die Container-Bewegung hat auch etwas mitgebracht, das weniger gut ist: Die Idee, dass das Betriebssystem ein Implementierungsdetail ist. Dass du Container brauchst, weil das Betriebssystem nicht gut genug ist. Dass du Docker brauchst, weil Linux nicht von sich aus isolieren kann.

Und hier ist die Ironie: Linux kann isolieren. Mit Namespaces, cgroups, Seccomp. Aber Linux hat sich entschieden, diese Mechanismen als Bausteine anzubieten, die du zusammensetzen musst — und das hat Docker übernommen. Docker ist der Wrapper, der die Bausteine zusammensteckt.

FreeBSD hat sich anders entschieden. FreeBSD hat die Isolation in den Kernel gebaut, als zusammenhängendes Konzept. Nicht als Bausteine. Sondern als Design. Und das Resultat ist einfacher, sicherer und leichter zu verstehen.

FreeBSD vertraut dem Admin. Der Admin weiss, was er tut. Er braucht keinen Daemon, der ihm die Isolation abnimmt. Er braucht einen Kernel, der Isolation bereitstellt, und Werkzeuge, die transparent sind.

Docker vertraut dem Workflow. Der Workflow weiss, was gut für dich ist. Du brauchst nicht zu verstehen, wie die Isolation funktioniert. Du musst nur docker run tippen.

Beide Philosophien haben ihren Platz. Aber wenn du ein Admin bist, der sein System versteht — und das bist du, wenn du diesen Artikel liest —, dann weisst du, welche Philosophie dir mehr gibt.

Fazit: Container-Infrastruktur, wenn man das Betriebssystem ernst nimmt

Container sind keine schlechte Idee. Prozessisolation ist essenziell. Aber die Art und Weise, wie Docker sie implementiert — mit einem Daemon, mit Layern, mit einer Registry, mit einem ganzen Ökosystem — ist nicht die einzige Art, Isolation zu erreichen. Und sie ist für viele Use-Cases nicht die beste.

FreeBSD-Jails bieten Isolation auf Kernel-Ebene, seit über 25 Jahren. Ohne Daemon. Ohne Registry. Ohne Layer. Ohne Komplexität. In Kombination mit ZFS bieten sie Instant-Cloning, atomare Updates, und effiziente Migration — alles mit Standard-Betriebssystem-Werkzeugen.

Wenn du dein Betriebssystem ernst nimmst — wenn du weisst, was unter der Haube passiert, wenn du Kontrolle über Einfachheit bevorzugst, wenn du Stabilität über Hype wählst —, dann sind Jails die bessere Wahl. Nicht immer. Nicht für jeden. Aber für die meisten, die ihre eigene Infrastruktur betreiben und wissen, was sie tun.

Docker hat die Container-Welt revolutioniert. Das bestreite ich nicht. Aber Revolution bedeutet nicht, dass das Alte obsolet ist. Manchmal bedeutet es nur, dass das Alte vergessen wurde.

Jails sind nicht vergessen. Sie sind gereift. Sie sind bewährt. Und sie warten darauf, von Leuten genutzt zu werden, die Einfachheit über Komplexität wählen.

Die Frage ist nicht: „Warum Jails statt Docker?“

Die Frage ist: „Warum Docker, wenn Jails alles können, was du brauchst — und weniger mitbringen, was du nicht brauchst?“

Digitale Souveränität: Warum On-Premise wieder relevant wird

Zehn Jahre lang war die Antwort auf fast jede IT-Frage dieselbe: Cloud. Neue Applikation? Cloud. Altes System migrieren? Cloud. Storage wächst? Cloud. Skalierung nötig? Cloud. Die Cloud war nicht nur eine Technologie — sie war eine Ideologie. „Cloud-first“ stand in den Strategiepapieren von Unternehmen, die nicht einmal verstanden hatten, was „first“ in diesem Kontext bedeutet.

Jetzt, zehn Jahre später, kommt die Ernüchterung. Nicht bei allen, aber bei vielen. Die Rechnungen sind da. Die Abhängigkeiten sind da. Die Fragen, die man hätte stellen sollen, bevor man migriert hat, sind immer noch da — nur dass sie jetzt teurer zu beantworten sind.

Einleitung

Die Migration in die Cloud war die dominierende IT-Strategie der letzten Dekade. Getrieben von Versprechen wie „unbegrenzter Skalierung“, „pay-as-you-go“ und „Zero Administration“ haben Unternehmen aller Größen Systeme, Daten und Prozesse in die Cloud verlagert — oft ohne die langfristigen Konsequenzen zu verstehen.

Heute beginnt eine Gegenbewegung. Nicht weil die Cloud gescheitert ist — sie hat ihre Vorteile —, sondern weil die Unternehmen, die in den letzten Jahren massiv in die Cloud gewandert sind, feststellen, dass die versprochene Einfachheit mit einem Preis kommt, der nicht nur finanziell ist.

Die Frage ist nicht mehr: „Cloud oder nicht?“ Die Frage ist: „Wofür Cloud, wofür On-Premise, und wie beides so kombinieren, dass die Souveränität über die eigenen Daten und Prozesse erhalten bleibt?“

Die Cloud-Revolution — und was sie wirklich verändert hat

Was die Cloud versprach

Die Argumente für die Cloud waren — und sind — attraktiv:

Skalierung. Mehr Last? Ein paar Klicks, und die Ressourcen sind da. Keine neue Hardware bestellen, kein Rack einbauen, kein Kabel ziehen. Die Cloud skaliert theoretisch unbegrenzt, und diese Skalierung ist innerhalb von Minuten verfügbar, nicht Wochen oder Monaten.

Geschwindigkeit. Eine neue Instanz starten, ein neues Deployment ausrollen, einen neuen Service aufsetzen — in der Cloud geht das in Minuten. On-Premise brauchte früher Tage oder Wochen für Hardware-Beschaffung und Einrichtung. In der Cloud ist alles sofort verfügbar.

Weniger Betriebsaufwand. Keine Server, die man warten muss. Keine Klimaanlage im Serverraum. Keine Hardware-Reparaturen am Freitagabend. Keine Ersatzteil-Lieferketten. Der Cloud-Provider kümmert sich um alles — Strom, Kühlung, Hardware, Netzwerk, physische Sicherheit.

Kapex vs. Opex. Statt hoher Investitionskosten (Capital Expenditure) für Hardware gibt es monatliche Betriebskosten (Operational Expenditure). Das ist für die Finanzabteilung attraktiv: planbare Kosten, keine Abschreibungen, keine Restwerte.

Managed Services. Datenbanken, Message Queues, Container-Orchestrierung, Authentication — alles als Service verfügbar. Kein Betrieb, keine Patches, keine Skalierungssorgen. Der Provider macht das.

Was die Cloud wirklich verändert hat

Die Cloud hat die Einstiegshürde massiv gesenkt. Das ist ihr größter Verdienst. Startups können heute innerhalb von Stunden eine Produktionsinfrastruktur aufbauen, die früher Wochen gedauert hätte. Kleine Unternehmen können auf Enterprise-Grade-Services zugreifen, ohne Enterprise-Grade-Personal zu brauchen.

Aber die Cloud hat auch die Wahrnehmung von IT-Kosten verzerrt. Die monatliche Rechnung fühlt sich anders an als eine einmalige Hardware-Investition — aber über drei bis fünf Jahre gerechnet ist sie oft teurer. Viel teurer. Und das ist nicht die einzige Überraschung.

Die Nachteile — die Rechnung kommt

Kostenentwicklung

Die Cloud ist billig, wenn man klein anfängt. Und sie wird teuer, wenn man wächst. Nicht linear teuer — exponentiell teuer.

Daten-Egress. Daten in die Cloud zu schicken ist kostenlos. Daten aus der Cloud herauszuholen kostet Geld. Das ist kein Zufall — es ist das Geschäftsmodell. AWS berechnet $0.09 pro GB für Daten-Transfer nach draußen. Bei einem Terabyte sind das $90. Bei zehn Terabyte $900. Und das ist nicht die einmalige Migration — das ist jede Replikation, jeder Backup-Restore, jeder Datenabgleich.

Storage-Kosten. S3-Storage kostet $0.023 pro GB und Monat (Standard-Tier). Das klingt wenig. Bei 50 TB sind das $1.150 pro Monat. Bei 500 TB — und das ist für mittelständische Unternehmen keine ungewöhnliche Größenordnung — sind es $11.500 pro Monat. $138.000 pro Jahr. Für Storage. Ohne Compute, ohne Netzwerk, ohne Managed Services.

Compute-Kosten. Eine m5.xlarge-Instanz bei AWS kostet ca. $0,192 pro Stunde. Das sind $1.682 pro Jahr. Eine vergleichbare Dedizierte-Server-Miete kostet ca. $200–400 pro Jahr. Faktor 4–8. Und bei Dediziert-Servern ist die Rechenleistung garantiert, nicht geteilt mit anderen Instanzen auf derselben Hardware.

Lizenz-Kosten. Microsoft-Lizenzen in der Cloud sind oft teurer als on-prem. Oracle-Lizenzen in der Cloud sind ein Albtraum. Red Hat Subscriptions in der Cloud kosten mehr als on-prem. Die Cloud macht Softwarelizenzen nicht billiger — sie macht sie teurer, weil die Cloud-Provider ihre Margen draufschlagen.

Der Faktor 3–10. Studien von 451 Research, IDC und mehreren Cloud-Financial-Management-Firmen zeigen konsistent: Über einen Zeitraum von 3–5 Jahren sind Cloud-Kosten für dauerhaft laufende Workloads 3- bis 10-mal höher als vergleichbare On-Premise-Kosten. Das gilt nicht für kurzlebige Workloads, nicht für Burst-Szenarien, nicht für Startups in der Wachstumsphase — aber für den typischen Dauerbetrieb mittelständischer und großer Unternehmen.

Vendor Lock-in

Die Cloud ist wie ein Hotel: Check-in ist einfach. Check-out ist das Problem.

Proprietäre Services. Wer AWS Lambda, DynamoDB, S3 Event Notifications, SQS, SNS und CloudFormation einsetzt, hat eine Architektur gebaut, die auf AWS funktioniert — und nur auf AWS. Die Migration weg davon ist nicht nur technisch aufwendig, sie ist organisatorisch eine Katastrophe, weil jede Komponente berührt werden muss.

Datenformate. Selbst wenn die Daten theoretisch portabel sind — SQL ist SQL, oder? —, sind die Unterschiede zwischen AWS Aurora, Google Cloud SQL und Azure Database für PostgreSQL substanziell genug, dass eine Migration kein einfacher Dump/Restore ist.

Operational Lock-in. Wer CloudFormation, Terraform-Provider-spezifische Module oder AWS CDK einsetzt, hat Infrastruktur-Code, der nicht portabel ist. Die IaC-Abstraktion, die eigentlich Unabhängigkeit schaffen sollte, ist selbst abhängig vom Provider.

Vertragsstrukturen. Reserved Instances, Savings Plans, Enterprise Agreements — die Vertragsstrukturen der Cloud-Provider sind darauf ausgelegt, Kunden langfristig zu binden. Der Rabatt für ein 3-Jahres-Commitment ist attraktiv, aber er bedeutet: Drei Jahre lang bezahlt man für Ressourcen, unabhängig davon, ob man sie noch braucht.

Datenhoheit

Wer seine Daten in der Cloud hat, hat sie nicht. Der Cloud-Provider hat sie. Und der Cloud-Provider hat eine Rechtsordnung, der er unterliegt.

Cloud Act. Der US-Cloud-Act von 2018 ermächtigt US-Behörden, Daten von US-Unternehmen auch dann einzufordern, wenn die Daten in einem Rechenzentrum außerhalb der USA liegen. AWS, Azure und Google sind US-Unternehmen. Das bedeutet: Daten, die bei diesen Providern liegen — egal ob in Frankfurt, Tokio oder Sydney — können von US-Behörden angefordert werden, ohne dass der Kunde davon erfährt.

GDPR. Die DSGVO verlangt, dass personenbezogene Daten in der EU verarbeitet werden oder ein angemessenes Schutzniveau besteht. Der EU-US Data Privacy Framework ist die aktuelle Lösung — aber er ist ein politisches Abkommen, kein technisches. Und er kann, wie sein Vorgänger (Privacy Shield), jederzeit für ungültig erklärt werden.

Datenzugriff durch Provider. Die AGB der großen Cloud-Provider erlauben ihnen Zugang zu Kunden-Daten in bestimmten Fällen — etwa bei Verdacht auf Missbrauch oder auf Anordnung eines Gerichts. Die Verschlüsselung der Daten ändert daran nichts, wenn der Provider die Schlüssel verwaltet.

Souveränität ist kein theoretisches Konzept. Für Unternehmen im öffentlichen Sektor, im Gesundheitswesen, in der Finanzindustrie und in kritischen Infrastrukturen ist Datenhoheit keine Frage der Präferenz, sondern der regulatorischen Pflicht. Wer Patientendaten, Finanzdaten oder Regierungsdaten in einer US-Cloud speichert, riskiert nicht nur Bußgelder — er riskiert den Entzug der Betriebserlaubnis.

Datenschutz

Datenschutz ist nicht dasselbe wie Datenhoheit. Datenhoheit fragt: Wer kann rechtlich auf meine Daten zugreifen? Datenschutz fragt: Wie schütze ich meine Daten vor unbefugtem Zugriff?

In der Cloud teilt man die Verantwortung mit dem Provider. Das „Shared Responsibility Model“ von AWS, Azure und Google ist klar definiert: Der Provider sichert die Infrastruktur, der Kunde sichert die Daten. Aber in der Praxis bedeutet das:

  • Der Provider hat physischen Zugriff auf die Hardware.
  • Der Provider kontrolliert das Hypervisor-Management.
  • Der Provider kann Memory-Dumps erstellen.
  • Der Provider hat Zugriff auf verschlüsselte Daten, wenn die Entschlüsselung in der Cloud stattfindet.

Das ist kein Misstrauen gegen die Provider. Es ist die Anerkennung einer Tatsache: Wer die Schlüssel nicht selbst verwaltet, hat keine volle Kontrolle über den Zugriff. Und „volle Kontrolle“ ist genau das, was Datenschutz in vielen Szenarien verlangt.

On-Premise ist nicht tot

Die Proklamation „On-Premise ist tot“ war die am häufigsten wiederholte Unwahrheit der letzten zehn Jahre. On-Premise war nie tot. On-Premise war nur nicht mehr sexy.

Was sich geändert hat

On-Premise bedeutet nicht mehr: Ein kalter Keller, ein Rack, ein überlasteter Administrator. Moderne On-Premise-Infrastruktur sieht anders aus:

Infrastructure as Code. Ansible, Terraform, Salt, Puppet — die gleichen Tools, die in der Cloud verwendet werden, funktionieren on-prem. Die Konfiguration ist versioniert, reproduzierbar, automatisiert. Der Unterschied zwischen Cloud und On-Premise ist nicht mehr die Automatisierung — es ist nur noch der Ort, wo die Hardware steht.

Virtualisierung ist gereift. Proxmox, bhyve, KVM — moderne Virtualisierungslösungen bieten Snapshots, Live-Migration, Resource-Pooling und Hochverfügbarkeit. Der Funktionsumfang ist mit Cloud-Virtualisierung vergleichbar, nur dass man die Hardware selbst kontrolliert.

ZFS. ZFS als Storage-Grundlage bietet Datenintegrität, Snapshots, inkrementelle Replikation, Kompression und Caching — alles, was man für robusten On-Premise-Storage braucht. ZFS macht den Unterschied zwischen „ein Filesystem“ und „ein Storage-Management-System“.

Container. Docker, Podman, Kubernetes on-prem — Container laufen nicht nur in der Cloud. Ein On-Premise-Kubernetes-Cluster mit Terraform-Provisioning und Ansible-Konfiguration ist kein Hexenwerk mehr.

Automatisches Patching. FreeBSD mit pkgbase, Ubuntu mit unattended-upgrades, Red Hat mit auto-updates — die Automatisierung von Security-Patches ist on-prem genauso möglich wie in der Cloud.

Stabilität

On-Premise-Infrastruktur ist stabil, wenn sie richtig gebaut ist. „Richtig gebaut“ heißt:

  • ZFS mit Redundanz. Mirror oder RAID-Z vdevs, reguläre Scrubs, Snapshots, Replikation auf einen zweiten Server.
  • CARP oder keepalived für Hochverfügbarkeit. Automatisches Failover bei Server-Ausfall.
  • Monitoring. Prometheus, Grafana, Alertmanager — die gleichen Tools wie in der Cloud.
  • Proaktive Wartung. ZFS-Scrubs wöchentlich, Smart-Monitoring für Disk-Failures, Firmware-Updates planvoll, nicht panisch.

Die Unterscheidung ist wichtig: Instabile On-Premise-Infrastruktur ist kein Argument gegen On-Premise. Es ist ein Argument gegen instabile Infrastruktur.

Sicherheit

On-Premise ist sicherer als die Cloud — wenn man die Security-Kontrolle nutzt, die man hat. In der Cloud gibt man physische Sicherheit und Netzwerk-Sicherheit an den Provider ab. On-Premise behält man beides:

  • Physische Kontrolle. Der Server steht im eigenen Rack. Kein fremder Administrator hat Zugriff. Kein Cloud-Provider-Mitarbeiter kann ein Image erstellen.
  • Netzwerk-Kontrolle. Die Firewall ist die eigene Firewall. Die Netzwerkstruktur ist die eigene Netzwerkstruktur. Es gibt keinen Shared-Tenant-Netzwerk-Pfad, über den ein anderer Cloud-Kunde Angriffe durchführen kann.
  • Verschlüsselung. Daten können on-prem verschlüsselt werden, mit eigenen Schlüsseln, eigener Verwaltung, eigenem KMS. Die Entschlüsselung findet auf der eigenen Hardware statt, nicht auf einem Server, der einem US-Konzern gehört.

Kosteneffizienz

Die Rechnung ist einfach, wenn man sie ehrlich macht:

  • Hardware-Anschaffung. Ein Server mit 256 GB RAM, 2x 1 TB NVMe und 4x 8 TB HDD kostet ca. 8.000–15.000 € — je nach Spezifikation. Geschrieben über 5 Jahre: 1.600–3.000 € pro Jahr.
  • Strom und Kühlung. Ca. 500–1.500 € pro Jahr pro Server, je nach Effizienz.
  • Netzwerk und Housing. Wenn man nicht selbst hostet: Colocation kostet ca. 100–300 € pro Monat pro HE. 1.200–3.600 € pro Jahr.
  • Personal. Das ist der größte Kostenfaktor — aber das Personal braucht man in der Cloud auch. Cloud-Infrastruktur managt sich nicht selbst.

Vergleich: Dieselbe Rechenleistung und denselben Storage in der Cloud kosten — konservativ geschätzt — 30.000–80.000 € pro Jahr. Bei wachsendem Storage-Volumen wird der Unterschied größer, nicht kleiner.

Der Break-Even liegt typischerweise bei 18–24 Monaten. Danach ist On-Premise günstiger. Und der Kostenvorteil wächst, weil die Hardware bezahlt ist, während die Cloud-Rechnung jeden Monat kommt.

Wann Cloud sinnvoll ist

Die Cloud ist nicht schlecht. Sie ist das falsche Default.

Cloud ist sinnvoll, wenn:

Burst-Workloads. Lastspitzen, die unvorhersehbar sind und kurzfristig viel Ressourcen brauchen. Black Friday, eine virale Kampagne, ein einmaliger Daten-Processing-Job. Die Cloud kann in Minuten skalieren und danach wieder schrumpfen. On-Premise muss die Hardware für den Worst Case vorhalten.

Prototyping und MVPs. Wenn man nicht weiß, ob ein Produkt funktioniert, ist die Cloud der richtige Ort. Keine Hardware-Investition, keine Verpflichtung. Wenn das Produkt funktioniert und die Last stabil wird, kann man migrieren.

Globale Verteilung. Wenn man Server in Singapur, São Paulo und Frankfurt braucht — in der nächsten Woche —, ist die Cloud die einzige Option. On-Premise braucht Zeit für Standortsuche, Hardware-Lieferung und Einrichtung.

Managed Services, die man selbst nicht betreiben will. Wenn man kein Elasticsearch-Expertise hat und nicht aufbauen will, dann ist AWS OpenSearch eine vernünftige Wahl. Wenn man kein Kafka-Cluster betreiben kann, dann ist Confluent Cloud eine Lösung. Der Schlüssel ist: Man wählt den Service bewusst, nicht als Default.

Kurzlebige Umgebungen. Test, Staging, CI/CD-Runner — Umgebungen, die man hochfährt, benutzt und wieder abschaltet. Die Cloud ist ideal für Ressourcen, die nicht 24/7 laufen müssen.

Wann On-Premise besser ist

On-Premise ist besser, wenn:

Dauerhafte Workloads. Workloads, die 24/7/365 laufen und deren Ressourcenbedarf vorhersehbar ist. Webserver, Datenbanken, Dateispeicher, interne Anwendungen — das ist das Kerngeschäft, und das gehört on-prem.

Große Datenmengen. Storage ist in der Cloud teuer. Bei 100+ TB wird die Rechnung absurd. On-Premise mit ZFS und großen Platten ist wirtschaftlich, und die Daten liegen dort, wo man sie kontrolliert.

Regulatorische Anforderungen. DSGVO, B3S, Kritis, Medizinprodukte-Verordnung — wenn der Gesetzgeber Datenhoheit verlangt, ist On-Premise keine Option, sondern eine Pflicht.

Langfristige Kosteneffizienz. Wenn man die Last für die nächsten 3–5 Jahre abschätzen kann, ist On-Premise günstiger. Deutlich günstiger.

Latenz-empfindliche Anwendungen. Die Netzwerk-Latenz zwischen Rechenzentrum und Nutzer ist on-prem minimiert. In der Cloud gibt es die Latenz zum nächsten Cloud-Region-Endpoint — und die ist für Echtzeit-Anwendungen nicht immer akzeptabel.

Daten, die nicht die Firma verlassen dürfen. Geheimnisse, Patente, Forschungsdaten, Kunden-Personas — es gibt Daten, die aus rechtlichen, ethischen oder strategischen Gründen nicht auf fremder Infrastruktur liegen dürfen.

Hybridmodelle — oft die beste Lösung

Die falsche Debatte ist „Cloud oder On-Premise“. Die richtige Debatte ist: „Was gehört wo hin?“

Das Prinzip der minimalen Cloud

Nutze die Cloud für das, was sie besser kann als On-Premise. Nutze On-Premise für alles andere. Das klingt banal, ist aber die Konsequenz einer ehrlichen Bewertung:

  • Stabile Kern-Workloads → On-Premise. Datenbanken, Dateispeicher, interne Anwendungen, Identity Management.
  • Burst- und Spitzenlast → Cloud. Zusätzliche Compute-Kapazität bei Lastspitzen, CI/CD-Runner, temporäre Testumgebungen.
  • Datenhoheit-kritische Daten → On-Premise. Alles, was regulatorisch oder strategisch geschützt werden muss.
  • Globale Services → Cloud. CDN, Edge-Computing, globale API-Endpunkte.
  • Managed Spezial-Services → Cloud. ML-Training, spezialisierte Datenbanken, Services, die man selbst nicht betreiben kann oder will.

Praktisches Hybrid-Setup

Ein konkretes Beispiel für ein mittelständisches Unternehmen:

On-Premise:

  • ZFS-Storage-Server mit 200 TB (Datenbanken, Dateispeicher, Backups)
  • Proxmox- oder bhyve-Cluster für interne Anwendungen
  • Git-Server (Gitea oder GitLab)
  • Identity Management (FreeIPA, Keycloak)
  • Monitoring (Prometheus, Grafana)
  • E-Mail-Server

Cloud:

  • CDN für die Website und statische Assets
  • Cloud-Runner für CI/CD (nur bei Bedarf)
  • Disaster Recovery: Replikation der kritischsten Daten in einen Cloud-Object-Store (verschlüsselt, mit eigenen Schlüsseln)
  • Burst-Compute für Lastspitzen (z.B. Quartalsende-Reporting)

Die monatliche Cloud-Rechnung für dieses Setup: vielleicht 500–2.000 €. Nicht 20.000 €. Nicht 50.000 €. Weil das Kerngeschäft on-prem läuft, und die Cloud nur das macht, was sie gut kann.

Die Rückkehr-Strategie

Für Unternehmen, die bereits massiv in der Cloud sind und die Kostenstruktur hinterfragen:

1. Inventur. Welche Workloads laufen in der Cloud? Welche davon laufen dauerhaft? Welche kosten am meisten?

2. Klassifikation. Welche Workloads sind Cloud-native (Lambda, DynamoDB, SQS)? Welche sind portabel (Docker-Container, Standard-Datenbanken, Webserver)?

3. Identifikation der Migrationskandidaten. Portable, dauerhafte Workloads mit hohem Daten-Volumen sind die besten Kandidaten für eine Rückkehr on-prem.

4. Pilot-Migration. Eine Workload auswählen, migrieren, Kosten vergleichen. Nicht alles auf einmal — iterativ vorgehen.

5. Optimierung. Nach der Migration: Cloud-Kosten für die verbleibenden Workloads optimieren. Reserved Instances, Spot-Instances, Right-Sizing.

Digitale Souveränität — mehr als ein Buzzword

Digitale Souveränität bedeutet: Die Fähigkeit, über die eigenen Daten, Prozesse und Infrastruktur selbst zu bestimmen. Nicht abhängig zu sein von einem einzelnen Provider, einem einzelnen Land, einer einzelnen Rechtsordnung.

Das ist kein nationalistisches Konzept. Es ist ein pragmatisches. Wer seine Infrastruktur nicht kontrolliert, kontrolliert sein Geschäft nicht. Wer seine Daten nicht kontrolliert, kontrolliert seine Zukunft nicht.

Die Cloud hat die Illusion erzeugt, dass Infrastruktur kein Problem mehr ist — man mietet sie ja einfach. Aber Infrastruktur war nie das Problem. Das Problem ist die Abhängigkeit. Und die Abhängigkeit ist in den letzten zehn Jahren größer geworden, nicht kleiner.

On-Premise ist die Antwort auf diese Abhängigkeit. Nicht als Absolutum — „alles on-prem“ ist genauso dogmatisch wie „alles Cloud“ —, sondern als bewusste Entscheidung: Was muss ich selbst kontrollieren? Was kann ich auslagern? Und wie stelle ich sicher, dass ich das Ausgelagerte bei Bedarf zurückholen kann?

Fazit

Die Cloud hat die IT-Landschaft verändert. Sie hat den Einstieg erleichtert, die Skalierung beschleunigt und die Betriebsmodelle transformiert. Aber sie hat auch Abhängigkeiten geschaffen, Kosten getrieben und Datenhoheit aufgeweicht.

On-Premise ist die Rückbesinnung auf das, was wirklich zählt: Kontrolle über die eigenen Daten, Kosteneffizienz für dauerhafte Workloads und Unabhängigkeit von einzelnen Providern.

Die beste Lösung ist Hybrid: Cloud für das, was die Cloud besser kann. On-Premise für alles andere. Und eine Architektur, die beides verbindet, ohne die Souveränität aufzugeben.

Die Unternehmen, die das verstehen, werden die nächsten zehn Jahre dominieren. Die anderen werden weiter monatliche Cloud-Rechnungen bezahlen — und sich fragen, warum ihre IT so teuer ist.

Infrastructure as Code: Warum Handarbeit auf Servern gefährlich ist

Jeder Systemadministrator kennt den Moment: Man meldet sich auf einem Server an, führt ein paar Befehle aus, ändert eine Konfigurationsdatei, installiert ein Paket. Alles funktioniert. Ein paar Wochen später steht man vor demselben Problem — nur auf einem anderen Server. Und man kann sich nicht mehr erinnern, welche Befehle man ausgeführt hat. Der Server ist ein Schneemann: Er sieht aus wie die anderen, aber unter der Oberfläche ist alles anders.

Infrastructure as Code (IaC) ist die Antwort auf dieses Problem. Und wer als Softwareentwickler und Administrator — wie ich — beide Welten kennt, weiß, dass IaC nicht nur ein Trend ist, sondern eine Notwendigkeit.

Das Problem mit manuellen Servern

Manuelle Administration skaliert nicht. Das ist keine Meinungsfrage, sondern Mathematik. Wenn jeder Server ein Unikat ist, dann ist jeder Server ein Risiko. Wenn ein Server ausfällt und niemand weiß, wie er konfiguriert war, dann ist der Wiederherstellungsprozess ein Glücksspiel.

Die typischen Symptome sind vertraut:

  • Konfigurationsdrift. Server, die identisch sein sollten, unterscheiden sich in subtilen — und manchmal kritischen — Details.
  • Wissensmonopole. Nur eine Person weiß, wie ein bestimmter Server konfiguriert ist. Wenn diese Person krank wird oder geht, ist das Wissen weg.
  • Nicht-reproduzierbare Zustände. Ein Server funktioniert, aber niemand kann erklären, warum. Oder schlimmer: Niemand kann ihn neu aufsetzen.
  • Angst vor Änderungen. Weil niemand weiß, was passieren wird, wenn man etwas ändert, ändert man nichts. Bis man es muss. Und dann ist es zu spät.

Was Infrastructure as Code bedeutet

IaC ist nicht einfach „Skripte schreiben“. Es ist ein Paradigmenwechsel in der Art und Weise, wie wir über Infrastruktur denken.

Deklarativ statt imperativ. Statt zu beschreiben wie ein Server konfiguriert werden soll („installiere nginx, kopiere die Konfiguration, starte den Dienst“), beschreibt man was der Zustand sein soll („nginx muss installiert sein, die Konfiguration muss diesen Inhalt haben, der Dienst muss laufen“). Der IaC-Workflow kümmert sich um das Wie.

Versioniert. Jede Änderung an der Infrastruktur ist in Git committet. Man kann sehen, wer was wann geändert hat. Man kann zu einem früheren Zustand zurückkehren. Man kann Änderungen über Code-Reviews prüfen lassen.

Reproduzierbar. Wenn ein Server ausfällt, kann er aus der IaC-Definition komplett neu aufgesetzt werden. Wenn ein neuer Server benötigt wird, kann er in Minuten statt Stunden erstellt werden.

Testbar. Bevor eine Änderung auf Produktion geht, kann sie in einer Testumgebung validiert werden. Syntaxfehler, fehlende Abhängigkeiten, inkompatible Konfigurationen — alles wird erkannt, bevor es Schaden anrichtet.

Die Werkzeuge

Die Wahl des Werkzeugs hängt vom Kontext ab. Hier eine Übersicht der etablierten Optionen:

Ansible

Das probably bekannteste IaC-Werkzeug. Ansible ist agentenlos (arbeitet über SSH), verwendet YAML für die Konfiguration und hat eine flache Lernkurve. Für FreeBSD-Administratoren ist es attraktiv, weil es native Module für ZFS, Jails, pkg und andere FreeBSD-Spezifika hat.

- name: ZFS-Dataset für Backup erstellen
  community.general.zfs:
    name: tank/backup
    state: present
    extra_zfs_properties:
      compression: zstd
      atime: off
      mountpoint: /backup

Der Nachteil: Ansible ist langsam bei großen Infrastrukturen und die YAML-Syntax wird bei komplexen Logiken unübersichtlich.

Terraform / OpenTofu

Für Cloud-Infrastrukturen ist Terraform (oder der Open-Source-Fork OpenTofu) der De-facto-Standard. Es verwaltet die Infrastruktur als Ressourcen — Instanzen, Netzwerke, Sicherheitsgruppen, Speicher — und hält den Zustand in einer State-Datei.

resource "aws_instance" "freebsd" {
  ami           = "ami-0xfreebsd15"
  instance_type = "t3.medium"

  tags = {
    Name = "freebsd-prod"
  }
}

Pulumi

Pulumi geht einen anderen Weg: Statt YAML oder HCL verwendet man echte Programmiersprachen — Python, TypeScript, Go. Das erlaubt echte Logik, Schleifen, Bedingungen und Typsicherheit.

import pulumi
import pulumi_command as command

server = command.remote.Command("freebsd-setup",
    connection=command.remote.ConnectionArgs(
        host="10.0.0.1",
        user="root",
    ),
    create="pkg install -y nginx",
)

Für FreeBSD: Besonderheiten

FreeBSD bringt eigene Werkzeuge mit, die in der IaC-Welt eine Sonderrolle einnehmen:

  • Jails sind leichtgewichtige Container, die sich hervorragend mit Ansible oder Shell-Skripten verwalten lassen.
  • ZFS bietet programmierbare Snapshots und Replikation, die sich in IaC-Workflows integrieren lassen.
  • pkgbase (seit FreeBSD 15.0) macht das Basissystem selbst paketierbar und damit IaC-kompatibel.

Der Pfad zur Einführung

IaC lässt sich nicht über Nacht einführen. Aber man kann schrittweise vorgehen:

  1. Bestandsaufnahme. Welche Server gibt es? Welche Konfigurationen? Was ist dokumentiert, was nicht?
  2. Ersten Server codifizieren. Den einfachsten Server nehmen und seine Konfiguration in Ansible (oder ein anderes Werkzeug) übertragen. Das dient als Lernprojekt und als Template.
  3. Neue Server nur noch via IaC. Jeder neue Server wird ausschließlich über Code konfiguriert. Keine manuellen Änderungen mehr.
  4. Bestehende Server migrieren. Nach und nach die manuelle Konfiguration durch IaC-Definitionen ersetzen. Das ist der langwierigste Teil.
  5. CI/CD für Infrastruktur. Änderungen an der IaC-Definition werden automatisch in Testumgebungen deployed, bevor sie auf Produktion gehen.

Die Kultur ändert sich mit

IaC ist nicht nur ein technischer Wechsel, sondern ein kultureller. Plötzlich sind Konfigurationsänderungen sichtbar. Jeder kann sie sehen, kommentieren, zurückrollen. Das ist ungewohnt — besonders für Administratoren.

Aber es ist der richtige Weg. In einer Welt, in der Sicherheitseinheiten täglich nachweisen müssen, welche Konfiguration auf welchem Server zu welchem Zeitpunkt aktiv war, ist manuelle Administration ein Risiko, das man sich nicht mehr leisten kann.

Und für den einzelnen Administrator ist IaC eine Erleichterung: Man muss sich nicht mehr erinnern, was man auf welchem Server gemacht hat. Es steht alles im Git-Repository. Wenn man nicht weiß, wie ein Server konfiguriert ist — man schaut nach. Immer. Zuverlässig. Ohne Ausnahme.

Testaufgaben nach einem Bewerbungsgespräch

Ich habe jetzt länger überlegt, ob ich darüber überhaupt bloggen möchte. Ich mache es doch einmal, denn es gab für mich etwas sehr interessantes und es ist schon eine ganze Weile her.

Ich war auf Jobsuche, schrieb hier und da eine Bewerbung. Dann hatte ich ein Vorstellungsgespräch und der Herr am anderen Ende der Telefonleitung meinte, es könnte passen. Nachdem er über meine Konditionen nachdachte und das mit der Geschäftsleitung durchsprach, bekam ich einen Anruf, dass diese passen würden, die Firma aber eine Testaufgabe für mich hätte. Darum soll es hier gehen, nämlich um diese eine Testaufgabe und um Testaufgaben im Allgemeinen.

Nachdem wir den Techstack abgeklärt hatten und es darum um PHP und Symfony ging und ich auch sagte, dass ich von beidem keine Ahnung habe (PHP habe ich das letzte Mal vor 20 Jahren gemacht), wurde mir versichert, dass vor dem persönlichen Kennenlernen nur noch eine einfache Testaufgabe zu meistern wäre, nämlich die Umsetzung eines Kontonummer-Bankleitzahlen-IBAN-Konverters. Ich sagte: kein Problem, das musste ich auch schon in einem echten Projekt vor einigen Jahren machen, er soll mir die Aufgabe zukommen lassen. Kurze Zeit später war dann das Dokument mit der Testaufgabe da. Fünf vollgeschriebene DinA4-Seiten. Dabei ging es nicht um die Entwicklung eines Konverters, sondern um ein gesamtes Projekt mit etlichen Zwischenstationen.

Ich sollte mich erst einmal in PHP 8.1 einarbeiten. Danach in Symfony 6.1. Um beides richtig zu machen, würde ich schon keine Stunden mehr veranschlagen, sondern eher einige Tage bishin zu wenigen Wochen. Eine Programmiersprache lerne ich zwar schnell, vor allem PHP, bei der ich nicht einmal von ganz vorne einsteigen müsste, dann aber noch ein komplexes Framework, das ist Aufwand.

Zusätzlich dazu sollte ein Login-Verfahren entwickelt werden und eine dazugehörige Website mit Datenbankanbindung (MySQL oder MariaDB). In der Datenbank sollten die bereits zuvor konvertierten Daten tabellarisch dargestellt werden. Jeder Aufruf sollte einen Zähler inkrementieren.

Weiterhin sollten die Daten dann als JSON exportiert werden können.

Dazu gehörte dann die Installation und Konfiguration von Debian 11, die Installation der benötigten Software (spezielle PHP-Version, nicht in APT drin, MySQL oder MariaDB, Symfony und Apache oder NGINX).

Das war der technische Part. Dazu kam dann ein Benutzerhandbuch für den Konverter über Funktionalität und Bedienung. Dann noch eine Dokumentation für das gesamte Deployment durch einen Laien (Installation und Konfiguration Betriebssystem, Installation und Konfiguration Webserver, Installation und Konfiguration Datenbankserver, Installation und Konfiguration PHP, Installation und Konfiguration von Symfony – durch einen Laien!).

Weiterhin sollte das Projekt vorher komplett durchgeplant werden, vermute mit Pflichenheft, war nicht genauer beschrieben und es sollten auch Tests (Unit-Tests, händische Tests) durchgeführt und dokumentiert werden.

Versteht mich bitte nicht falsch: Das alles kann ich, aber rein realistisch, wenn man es vernünftig macht, ist das ein Projekt, das man nicht in einigen Stunden hinbringt, selbst, wenn man PHP und Symfony auf hohem Level beherrscht. Schon alleine am Pflichtenheft schreibt man eine Weile, das Benutzerhandbuch rotzt man auch nicht einfach runter…

Ich lehnte den Job dann mit Begründung ab. Eine Antwort darauf erhielt ich nie.

wxWidgets-Tutorial 004 – wxWidgets auf Ubuntu-Linux installieren und ein erstes Beispielprojekt

In diesem Video zeige ich, wie man wxWidgets unter Linux, in unserem Szenario Ubuntu, installieren kann.

wxWidgets auf Ubuntu-Linux installieren und ein erstes Beispielprojekt
wxWidgets auf Ubuntu-Linux installieren und ein erstes Beispielprojekt

Installiert werden kann wxWidgets folgendermaßen:

sudo apt install libwxgtk3.0-gtk3-dev

Hier der Quellcode von unserer Test-Anwendung:

#include <wx/wx.h>

class MyApp : public wxApp {

	public:
		bool OnInit();

};

class MyFrame : public wxFrame {

	public:
		MyFrame();

};

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit() {
	MyFrame *myFrame = new MyFrame;
	myFrame->Show();
	SetTopWindow(myFrame);

	return true;
}

MyFrame::MyFrame() : wxFrame(nullptr, wxID_ANY, "Meine wx-App") {
	wxStaticText *staticText = new wxStaticText(this, wxID_ANY, "Hello World");
}

Und so wird es kompiliert:

c++ mywxapp.cpp -o mywxapp `wx-config --libs --cppflags` -std=c++11

Danach sieht es in etwa so aus:

Installation von wxWidgets unter Ubuntu
Installation von wxWidgets unter Ubuntu

Hier geht es zum Video.

Kurztipp: bhyve auf FreeBSD mit vm-bhyve

Alle nutzen Jira. Ich hatte das seinerzeit mal bei der CGM nutzen müssen, wollte mir aber auch mal wieder die aktuelle Version ansehen, um wenigstens sagen zu können: ich kenne es (Pssst: Redmine gefällt mir von der Übersicht und Usability aber weitaus besser – Geschmackssache).

Da ich hier nur FreeBSD-Server rumstehen habe, dachte ich mir: Da gibt’s ja bhyve. Angesehen und aus Zeitgründen wieder verworfen, da ich mich nicht ewig mit der Bedienung auseinandersetzen wollte und konnte. Irgendwann stieß ich dann auf vm-bhyve, einem kleinen Konsolenprogramm, dass eine ähnliche Bedienung wie die anderen administrativen Programme unter FreeBSD bietet (geli, gstat, gpart…).

Auf meinem Server (Intel(R) Xeon(R) CPU E3-1220L V2 @ 2.30GHz) habe ich es dann auch direkt installiert und wollte Ubuntu virtualisieren, genauer: Ubuntu Server. Die Installation lief auch mit dem bei bhyve-vm mitglieferten Template durch, bootete aber nicht, sondern blieb im Grub hängen. Irgendwo in den Tiefen des Internet fand ich dann, dass man LVM bei der Installation weglassen sollte. Gemacht, funktionierte aber genauso schlecht.

Was dann aber funktionierte, und das absolut reibungslos, war die Installation von Debian. Das installierte sich problemlos und bootete durch. Jira und die geforderten Abhängigkeiten waren auch in ein paar Minuten installiert und liefen direkt, so dass ich mir Jira noch einmal genauer ansehen konnte.

Wer also mit FreeBSD (mit allen Features und Einschränkungen) als Hypervisor liebäugelt, dem sei angeraten, sich einmal vm-bhyve anszusehen.

Meine IT-Laufbahn

Oftmals interessiert es Menschen, warum andere Menschen das tun, was sie nun mal tun und auch, warum. Ich möchte hier einmal meinen Werdegang niederschreiben, der mich beruflich und privat sehr geprägt hat. Es geht um meine IT-Laufbahn.

Alles begann, als ich ungefähr sechs Jahre alt war. Vielleicht auch schon ein wenig früher. Ich interessierte mich sehr für elektronisches Spielzeug, allem voran für Spielzeugroboter. Ich hatte eine ganze Menge. Sie konnten blinken, herumfahren, sprechen (entweder durch ein Sprachmodul oder durch ein kabelgebundenes Handsprechgerät) und manche konnten sogar dampfen. Die Zeit war großartig, und während andere ihre Kuscheltiere und Puppen mit ins Bett nahmen, nahm ich meine Roboter mit. Von meiner Mutter wurde das kritisch gesehen, wachte ich nicht nur einmal mit großen Schmerzen auf. Das nahm ich in Kauf.

Einer unserer Nachbarn und Bekannten verkaufte dann seine Spielekonsole und ich musste sie haben. Ich weiß nicht mehr, wann ich sie bekam, aber es musste um das Jahr 1985 herum gewesen sein. Ich erinnere mich noch, dass es kalt war, so dass ich davon ausgehe, sie zu Weihnachten bekommen zu haben. Es handelte sich um das Atari 2600. Ich muss überglücklich gewesen sein, und so kam es, dass wir alle fleißig Pac-Man spielten und was es sonst noch so gab. Ich erinnere mich noch, wie ich versuchte, mit einem Hubschrauber in Seitenansicht durch eine Art Labyrinth geflogen zu sein. Auch an Pitfall 2 erinnere ich mich sehr gerne, wie ich mit Lianen über gefährliche Gewässer und noch gefährlichere Krokodile geschwungen bin, über Baumstämme sprang und im Dungeon den gefährlichen Monstern auswich.

Das reichte aber nicht. Ich brauchte einen Computer. Nun war es so, dass wir nicht viel Geld hatten, aber meine Eltern schafften es trotzdem, einen gebrauchten Schneider CPC464 zu organisieren. Wenn ich so zurückdenke, ein eigentlich grandioses Gerät, welches ich zu Weihnachten meines achten Lebensjahres bekam. Für die, die die alten Homecomputer nicht kennen: Computer und Tastatur bilden eine Einheit (wie auch beim C16, C64 und C128 von Commodore oder beim Amiga 500, 600 und 1200). Dazu war ein Datasettenlaufwerk eingebaut. Angeschlossen wurde diese Rechenmaschine an einen Grünmonitor. Das bedeutete, das ganze Bild war grün. Dunkelgrün, hellgrün, grün. Nach dem Einschalten startet man direkt im Basic-Prompt und kann anfangen, zu programmieren oder ein Programm oder Spiel von Kassette zu laden. Das dauerte nicht nur lange, sondern war auch recht fehleranfällig, so dass man die langen Versuche ab und an wiederholen musste. Ich mochte aber die Töne, die dabei herauskamen. Mit dem Monitor und dem Computer, an dem ich sogar meine Atari-2600-Joysticks anschließen konnte, und ein paar Spielen, kam auch ein umfangreiches Benutzerhandbuch mit, welches viele Codebeispiele in Basic bereithielt. So konnte ich … trotzdem nichts verstehen. Mit acht Jahren ist das gar nicht so einfach. Dennoch tippte ich viele Listings ab und feierte dabei einige Erfolge, wie auf einmal irgendwelche Kreise oder Vierecke auf dem Bildschirm gezeichnet wurden.

Ich wuchs und sah bei einem Freund eine völlig neue Welt. Er hatte eine Powermaschine. Ein System, was mich massiv beeindruckte und ich unbedingt auch haben wollte. Einen Amiga 500. Nicht nur konnte er Farbe (was der CPC auch konnte, hätte man den richtigen Monitor gehabt), nein, statt eines schäbigen Datasettenlaufwerks hatte er ein Diskettenlaufwerk mit einer mittleren Zugriffszeit von „wahnsinnige Geschwindigkeit“. Ich musste so ein Ding haben. Die Spiele waren eine neue Generation und auch die ganze Software interessierte mich brennend. Entweder meine Eltern erkannten meine Berufung, oder ich hatte noch mindestens so viel vom Kindchenschema, dass am nächsten Weihnachten diese Hightechwunderkiste unterm Baum lag. Es war wunderbar. Ich war in einem Alter, da wusste ich bereits, was ich bekam, so dass ich mir im Vorhinein vom Taschengeld etliche Disketten kaufte und alles von Freunden kopierte, was ich konnte. Ich startete an diesem Weihnachten mit einer schier endlosen Software- und Spielesammlung und war lange von dem System sehr begeistert, was ich auch heute wieder bin. Allerdings habe ich mit dem Computer nie wirklich versucht, zu programmieren. Was ich allerdings hatte war ein Neun-Nadeldrucker mit Farbe. Das Farbband hatte vier Farben und damit eine separate für Schwarz, so dass man „natives“ Schwarz drucken konnte, wenn man was Buntes gedruckt hat. Es gab aber auch einfache schwarze Bänder ohne Farbe, die erheblich günstiger waren. Das Gerät war laut, hatte keine Papierkassette, so dass jedes Blatt einzeln eingelegt werden musste, aber die Möglichkeit, DinA3 zu drucken und Endlospapier zu verarbeiten. Soweit ich mich noch erinnere, war es ein Star-LC 200, der via Centronics an den Parallelport des Amigas angeschlossen war. In Kombination mit meinem maximal 400dpi Handscanner war es zu der Zeit eine großartige Kombination und hat Spaß gemacht.

Die Zeit des Amigas war dann aber doch bald gezählt und schweren Herzens wünschte ich mir einen Personal Computer, denn meine Freunde hatten ja auch alle einen. So schloss ich mit meinen Eltern einen Pakt, dass wir den Amiga verkaufen wir dafür einen PC anschaffen. Wir schauten uns erneut auf dem Gebrauchtmarkt um und fanden in Köln (Weiden) ein passendes Angebot. Ein 386er sollte es werden mit 4MB RAM und 80MB Festplatte. Wir fuhren vorbei und kauften das Gerät. Schon bald interessierte es mich, wie Computer aufgebaut waren und, ich denke zum Entsetzen meiner Eltern, schraubte ich das Gerät auf und begann, Karten einzustecken, Diskettenlaufwerke zu tauschen und sogar ein CDROM einzubauen. Ich interessierte mich zuerst viel mehr für die administrative Seite der Computerei. Ich spielte viel mit DOS und Windows 3.11 herum, war von dem Zeug aber nie sonderlich begeistert.

Es kam die Zeit der Mofas und Mopeds und ich verlies ein wenig die Computerei. Nicht viel, ich blieb ihr immer treu, aber mein Fokus war für eine gewisse Zeit auf etwas anderes gerichtet. Ich kam aber wieder zurück und stellte fest, dass so ein 386er nicht mehr das Mittel der Wahl war, um vernünftig zu arbeiten … oder zu spielen. Also bat ich meine Eltern um Hilfe und sie, immer noch nicht reich, kratzten alles Geld zusammen und kauften mir einen Pentium mit 133MHz, 4MB RAM (keine Ahnung, warum so wenig), die ich später auf 8MB aufrüstete und dann auf 16MB, und einer Festplatte mit einer Kapazität von 1GB. Ich dachte, die bekomme ich niemals voll. So schnell hatte ich mich noch nie geirrt. Ich spielte weiter mit DOS und Windows 3.11, später dann mit Windows 95 und Windows 98. Es war interessant, doch hauten mich die Systeme nie aus den Socken. Ich probierte, neben MSDOS, noch andere DOS-Derivate, unter anderem DRDOS und PTS-DOS, spielte mit OS/2 Warp 3 herum und arbeitete an administrativen Kleinkram. Wenig später, ich hatte zusätzlich noch meinen 386er, kaufte ich mir meine ersten Netzwerkkarten. Zwei an der Zahl, bei denen man die IRQs noch selbst jumpern musste. Schon war man in der schönen neuen Welt des Datenaustausch in Netzwerk hausintern, mit Koaxialkabeln, T-Stücken, Terminatoren, 10Mbit und einer hohen Fehleranfälligkeit. Spaß hat es allemal gemacht, zumal man beginnen konnte, Computerspiele im Netzwerk zu spielen, und zwar mit mehr als nur einer weiteren Person, wie es mit Nullmodem- oder Parallelkabel möglich war. Diese Form von Netzwerk hat mich tatsächlich einige Zeit begleitet, bis ich auf ein 100Mbit-Netzwerk mit Hub umgestiegen bin. Die (theoretische) Verzehnfachung der Geschwindigkeit war bahnbrechend für mich und durch die Nutzung eines alten 486er als Router mit 56k-Modem konnten erstmals mehrere Rechner über einen SOCKS5Proxy ins weltweite, kaum bezahlbare Internet gehen. Ich weiß noch, wie meine Mutter immer schrie: „Bist du schon wieder im Internet? Ich will telefonieren!“

Nach den Rechnern von der Stange begann ich dann, meine Computer selbst zusammenzustellen und zusammenzubauen. Das habe ich über Jahre hinweg getan, den letzten vor ungefähr vier Jahren. Schnell, als armer Schüler, wechselte ich von Intel zu AMD, K5, K6, K6 II, K6 III, Duron und wie sie alle heißen und ich arbeitete mich in Linux ein. Immer wieder kurz, dann brachte es mich zurück zum verhassten Windows.

Aus persönlichen Gründen schmiss ich in der elften Klasse die Schule, lungerte ein oder zwei Monate zu Hause herum, bis meine Mutter mich zwang, aushilfsweise in einem Lager für Textilien auszuhelfen. Täglich zuerst eine Stunde für mehrere Wochen, dann wurde mir gesagt: „Hey, du bist zuverlässig, schnell und gut, warum willst du nicht länger, nämlich den ganzen Tag, hier arbeiten?“ Wie sehr ich es hasste. Aber ich musste die Zeit zum Zivildienst irgendwie herumbekommen und so arbeitete ich hart im Lager. Ich habe dann, mit meinen Kollegen, 40-Fuß-Container, teils mit Säcken mit 50kg, händisch ausgeladen. Ich arbeitete dort ein dreiviertel Jahr und, obwohl das eine schwere Arbeit war, die ich nie wieder machen möchte, möchte ich die Zeit nicht missen. Ich habe gutes Geld verdient und gelernt: „Körperliche Arbeit ist nichts für mich.“

Ich absolvierte also mein Jahr Zivildienst und mir war bereits seit meinem achten Lebensjahr klar, dass ich etwas mit Computer machen wollte. Ohne Abitur kein Studium, und da ich eh immer eher der Praktiker als der Theoretiker war, entschloss ich mich, mich für die Ausbildung zum Fachinformatiker mit Fachrichtung Anwendungsentwicklung zu bewerben. Ich weiß noch, dass ich bei einem Freund in Köln war, als meine Mutter gegen 18 Uhr anrief und meinte, dass ein Unternehmen, bei dem ich mich bewarb, anrief und sie mich gerne nehmen würden. Ich war außer mir vor Freude. Dort blieb ich dann 1,5 Jahre, ich hatte aber Gründe, zu wechseln und wechselte so in eine andere Firma, in der ich die Ausbildung abschloss.

Dann war ich einen Monat arbeitssuchend.

Der Mann meiner Cousine kannte aber jemanden in einem Verlag in Remagen, der auch händeringend nach Verstärkung suchte und ich dachte mir, ich schicke da mal eine Bewerbung hin. Lust hatte ich keine. Dummerweise wurde ich zum Vorstellungsgespräch eingeladen. Ich dachte, das geht eh nach hinten los. Ich hatte meine schäbigsten Klamotten angezogen, völlig ausgewaschenes Hemd, kaputte Hose. Das Vorstellungsgespräch empfand ich nicht als gut gelaufen und ich war froh, bis mich, einige Stunden später, jemand von der Firma anrief und sagte, ich hätte den Job. Ich dachte mir: Shit. Ok, ich nahm mir dann vor, dort ein halbes Jahr zu bleiben. Daraus wurden 14 Jahre, bis die Firma leider insolvent ging.

Zuerst assistierte ich meinem Vorgesetzten bei administrativen Aufgaben. Schnell wurde bekannt, dass ich ja Programmierer bin und ich bekam die ersten programmiertechnischen Aufgaben zugeteilt. Zuerst Websites, dann Database Publishing. Mein Vorgesetzter wurde aus diversen (guten) Gründen gefeuert und ich übernahm das Steuerrad der IT. Eineinhalb Jahre habe ich geklotzt, kein Urlaub, kein krank, teils bis spät in den Abend oder die Nacht, teils an Wochenenden. Dann kam die Idee auf, einen Auszubildenden aufzunehmen, der mich unterstützt. Er war auch bis zum Schluss bei der Firma. Gemeinsam brachten wir das Netzwerk auf einen akkuraten Stand, machten mit Softwareentwicklung weiter und bildeten noch weitere aus und holten noch mehr Leute mit in die Abteilung, denn es wurde ernst, als wir das Verlagsprogramm ablösen sollten. Die Frage war: nehmen wir was von der Stange oder entwickeln wir selbst was? Wir entwickelten selbst, mit wxWidgets und C++ und PostgreSQL. Nebenher stellten wir noch das ganze Netzwerk von Windows 2000 auf Ubuntu Linux um, kümmerten uns ums Autodeployment, automatisierten einiges weg, stellten die Redaktion dann doch von Ubuntu auf macOS (damals noch Mac OS X) um, automatisierten dort auch (DeployStudio, AutoDMG, AutoPKG, Munki, eigene Software) und machten einige weitere Softwareentwicklungen, kümmerten uns um hochverfügbare Firewalls mit OpenBSD und redundante Server mit FreeBSD. Es war herrlich, wir haben sehr viel gemacht, ich war für die Abteilung zuständig und für alles, was man in eine Steckdose stecken kann. Wir haben alles inhouse gemacht, selbst um Kopiersysteme haben wir uns gekümmert, das E-Paper-System sowie Shopsysteme entwickelt, gepflegt und an die Verlagssoftware angebunden, Inventarisierungssysteme und Softwareverteilungssysteme für unsere Vielzahl an Betriebssystemen entwickelt (Windows, macOS, Linux, FreeBSD und OpenBSD war im Einsatz), das Backup auf Tape und Storage gemacht, und so weiter und sofort. Ich habe in C eine Software geschrieben, um die Website von einem Quantum SuperLoader 3 auszulesen und zu steuern, da es keine Treiber für FreeBSD für die Maschine gab, um zu schauen, was genau ist in welchem Slot drin. Wir haben sogar Platinen geätzt und mit Mikrocontrollern Schaltungen gebaut. Ich habe in der Zeit eine Menge gelernt, bis, ja bis wir alle hochgerufen wurden und uns die Kündigung gegeben wurde. Das war traurig, sehr traurig.

Ich versuchte mich dann mit meiner Frau an einer eigenen Firma. Wir entwickelten compow, eine Firmenwebsite, auf der sich Firmen vorstellen können und Benutzer nach Jobs suchen können. Programmiertechnisch recht anspruchsvoll, aber wir sind einfach keine Unternehmer. Also heuerte ich bei einer neuen Softwarefirma an. Auch da entwickelte ich in Java, C++, VisualBasic und Pascal (Delphi -> FreePascal).

Die Computerrei war aber auch immer mein Hobby, nicht nur mein Beruf. So entwickelte ich teils an freier Software, an eigener Software, probierte viel über die Dekaden aus und herum und bildete mich so weiter.

Und genau das mache ich jetzt immer noch. Natürlich bin ich zurzeit aktiv auf Jobsuche, denn leider hat das letzte Unternehmen, in dem ich beschäftigt war, auch Insolvenz angemeldet. Ich nutzte jetzt die Gelegenheit und versuche mich momentan an YouTube. Weiterhin bilde ich mich in verschiedenen Systemen weiter. Die Zeit, die ich vorher mit einem Job verbracht habe, versuche ich nun, mit Jobsuche, Weiterbildung und YouTube sinnvoll auszufüllen.

So viel zu mir. Wenn ihr Fragen habt, gerne her damit (:

Videoreihe: Entwicklung einer Desktopsoftware für compow mit C++, Qt und SQLite Teil 7

In diesen ca. 20 Minuten machen wir einiges. Wir laden das Logo der Firma im Firmeneintrag und zeigen es an. Dann implementieren wir noch die Funktion, dass man aus der Firmenmaske die Firma direkt auf der compow-Website anzeigen kann und wir machen die Ausgabetabelle der Firmen sortierbar.

Videoreihe: Entwicklung einer Desktopsoftware für compow mit C++, Qt und SQLite Teil 7
Videoreihe: Entwicklung einer Desktopsoftware für compow mit C++, Qt und SQLite – Teil 7

Und so sieht es (auf macOS) aus:

Firmeneintrag mit angezeigtem Logo
Firmeneintrag mit angezeigtem Logo

Hier geht es zum Video.

Videoreihe: Entwicklung einer Desktopsoftware für compow mit C++, Qt und SQLite – Was kommt jetzt?

Diese Woche wird es erstmal kein Video geben, da zu viel los ist und alle hier kränkeln. Aber was kommt als nächstes?

Nunja, ohne Video werde ich als erstes die Anzeigemaske für die Firmen erstellen, denn das ist langweilige Fließbandarbeit. Danach werden wir uns gemeinsam ansehen, wie wir das Logo-Bild der einelnen Firmen, welches Base64-encoded in der SQLite-Datenbank liegt, in der Firmenmaske anzeigen können. Vielleicht bauen wir es auch in die Ergebnisliste mit ein.

Dann brauchen wir noch etliche weitere Teile:

  • Export der Suchliste
  • Export von Firmen
    • XML?
    • JSON?
    • CSV?
    • Text?
  • Drucken von Firmen
  • Eine Toolbar
  • Ein Menü
  • Einen „Über“-Dialog (About)
  • Für Windows einen Installer
  • Eine Hilfe für die Software oder ein Handbuch?
  • Tests auf Linux, FreeBSD und Windows
  • Vielleicht noch mehr, was mir gerade nicht einfällt

Ich denke, wir werden uns dann nächste Woche damit beschäftigen. Bis dahin hoffe ich, dass ich die Firmenmaske fertig bekomme, wonach es zur Zeit aber nicht aussieht.