Schritt 2 der Server-Serie

Docker verstehen
& einrichten

Was Docker ist, warum es dein Server-Leben revolutioniert – und wie du es in wenigen Minuten zum Laufen bringst. Kein Vorwissen nötig.

Los geht's
Kapitel 1

Was ist Docker – und warum brauchst du es?

Stell dir vor, du möchtest eine neue App auf deinem Server installieren. Normalerweise musst du herausfinden, welche Hilfsprogramme sie braucht, welche Versionen kompatibel sind und ob das andere Software auf deinem Server stört. Mit Docker entfällt das komplett.

Die Umzugskarton-Analogie

Stell dir vor, du ziehst um. Normalerweise nimmst du deine Kaffeemaschine mit – aber in der neuen Wohnung fehlt der passende Stecker. Docker löst das: Es packt die Kaffeemaschine zusammen mit dem passenden Stecker, der Steckdose und der Bedienungsanleitung in einen einzigen Karton. Dieser Karton funktioniert auf jedem Server – garantiert.

OHNE DOCKER n8n Node 14 ??? Datenbank MySQL 5 ??? Webserver Python 2 ??? Konflikte · Abhängigkeiten · Chaos MIT DOCKER CONTAINER n8n Node 18 ✓ CONTAINER Datenbank MySQL 8 ✓ CONTAINER Webserver Python 3 ✓ CONTAINER Backup Isoliert ✓ Isoliert · Sauber · Kontrolliert

Das Container-Schiff-Prinzip

Früher wurde jede Ware anders verpackt – Fässer, Säcke, Kisten. Das Be- und Entladen von Schiffen war chaotisch. Der Standard-Container hat das revolutioniert: gleiche Grösse, gleicher Anschluss, überall kompatibel. Docker hat dasselbe für Software gemacht. Jede App läuft in einem standardisierten Container – auf jedem Server, in jeder Cloud.

Die vier Begriffe, die du kennen musst

Docker hat eine eigene Sprache. Diese vier Begriffe begegnen dir überall – einmal verstanden, macht der Rest sofort Sinn.

IMAGE Image Die Blaupause CONTAINER A ● Läuft Läuft CONTAINER B ● Läuft Läuft CONTAINER C ⏹ Gestoppt Pausiert 1× IMAGE → BELIEBIG VIELE CONTAINER Volume Persistente Daten

Image

Die Blaupause – unveränderlich, wie eine ISO-Datei. Einmal bauen, überall starten.

Container

Die laufende Instanz eines Images – wie ein eingeschalteter Computer.

Volume

Persistenter Speicher – Daten bleiben erhalten, auch wenn der Container stoppt.

Compose

Dirigent für mehrere Container – definiert wer mit wem spricht.

VIRTUELLE MASCHINE DOCKER CONTAINER Hardware (Server) Host-Betriebssystem Hypervisor Gast-OS ~1 GB RAM Gast-OS ~1 GB RAM App A App B Schwer · Langsam · Viel RAM Hardware (Server) Host-Betriebssystem Docker Engine CONTAINER App A ~50 MB CONTAINER App B ~30 MB CONTAINER App C ~80 MB Leicht · Schnell · Effizient

Der entscheidende Unterschied: Eine virtuelle Maschine bringt ihr eigenes komplettes Betriebssystem mit – das kostet 1–2 GB RAM pro App, bevor die App überhaupt startet. Ein Docker-Container teilt sich das Betriebssystem des Servers und startet in Sekunden statt Minuten.

Kapitel 3

Docker installieren

Es gibt zwei Wege, Docker zu installieren. Wir nehmen den offiziellen Weg über Dockers eigenes Repository – der ist aktueller, sicherer und wird immer automatisch upgedated.

Warum nicht einfach apt install docker.io?

Das würde eine ältere, von Ubuntu gepflegte Version installieren – wie wenn du ein Produkt vom No-Name-Regal nimmst statt direkt beim Hersteller zu kaufen. Über Dockers eigenes Repository bekommst du immer die aktuellste, offizielle Version mit automatischen Updates.

Vorbereitung: Falls auf dem Server bereits ältere oder inoffizielle Docker-Pakete vorhanden sind, sollten sie zuerst entfernt werden. Das verhindert Konflikte mit der offiziellen Docker-Installation.

Alte Docker-Pakete entfernen
sudo apt-get update
sudo apt-get remove -y docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc

Schritt 1 – Den offiziellen Docker-GPG-Schlüssel hinzufügen

Ein GPG-Schlüssel ist wie ein Echtheitszertifikat – er beweist, dass die Software wirklich von Docker stammt und nicht verändert wurde.

Im Terminal eingeben
# Paketliste aktualisieren
sudo apt-get update

# Nötige Hilfsprogramme installieren
sudo apt-get install -y ca-certificates curl

# Sicheren Ordner für den Schlüssel anlegen
sudo install -m 0755 -d /etc/apt/keyrings

# Docker's GPG-Schlüssel herunterladen
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

Schritt 2 – Docker's Repository hinzufügen

Jetzt sagen wir unserem Server, wo er Docker-Updates herunterladen soll. Dieser Befehl erkennt deine Ubuntu-Version automatisch.

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Paketliste aktualisieren
sudo apt-get update

Schritt 3 – Docker installieren

Jetzt kommt die eigentliche Installation. Dieser eine Befehl installiert Docker Engine, die CLI, Docker Compose und alle nötigen Plugins in einem Zug.

sudo apt-get install -y \
  docker-ce \
  docker-ce-cli \
  containerd.io \
  docker-buildx-plugin \
  docker-compose-plugin

Was bedeutet das alles? docker-ce ist die Docker Engine, docker-ce-cli das Terminal-Tool, containerd.io der Container-Manager, und docker-compose-plugin das Tool für mehrere Container.

Schritt 4 – Deinen Benutzer zur Docker-Gruppe hinzufügen

Damit du Docker-Befehle ohne sudo verwenden kannst, musst du deinen Benutzer einmalig zur Docker-Gruppe hinzufügen. Danach musst du dich einmal aus- und wieder einloggen.

sudo usermod -aG docker ${USER}

# Gruppenrechte sofort neu laden (nur für aktuelle Session)
newgrp docker

# Docker und Docker Compose testen
docker --version
docker compose version

Hinweis zu newgrp: newgrp docker aktiviert die Gruppe nur für die aktuelle Terminal-Sitzung. Damit die Änderung dauerhaft gilt – auch nach dem nächsten Login – musst du dich einmal komplett aus- und wieder einloggen (SSH-Verbindung schliessen und neu öffnen).

Erster Test – Docker zum Leben erwecken

Docker ist installiert. Jetzt prüfen wir, ob alles funktioniert – und lernst dabei die wichtigsten Befehle kennen.

Hello World starten

Das ist der klassische erste Test. Docker lädt automatisch ein winziges Test-Image herunter und startet es:

docker run hello-world
docker info

Wenn du eine Willkommensmeldung siehst, die mit «Hello from Docker!» beginnt – herzlichen Glückwunsch, Docker läuft. Der Befehl docker info zeigt dir zusätzlich Details zur Installation, zu laufenden Containern, Plugins, Speicherpfaden und zur verwendeten Docker-Version.

Was passiert im Hintergrund?

Der Befehl docker run macht drei Dinge auf einmal: Er sucht das Image lokal, lädt es von Docker Hub herunter wenn es nicht vorhanden ist, und startet sofort einen Container daraus. Das geht in Sekunden.

Laufende Container anzeigen

Mit diesem Befehl siehst du alle gerade aktiven Container – wie der Task-Manager deines Servers:

docker ps            # Nur laufende Container
docker ps -a          # Alle Container (auch gestoppte)

Tipp: Der hello-world Container stoppt automatisch nach dem Start. Das ist normal – er hat seine Aufgabe erledigt und braucht nicht mehr zu laufen.

Kapitel 5

Docker Compose – der Dirigent

Einzelne Container starten ist gut. Aber die meisten echten Anwendungen brauchen mehrere Container, die miteinander kommunizieren. Hier kommt Docker Compose ins Spiel.

Das Orchester-Prinzip

Stell dir vor, jede App ist ein Musiker. n8n ist die Geige, die Datenbank das Cello, der Reverse-Proxy die Trompete. Ohne Dirigenten spielen alle für sich. Docker Compose ist der Dirigent: Er definiert, wer wann spielt, wer auf wen wartet und wie alle zusammen klingen sollen – alles in einer einzigen Notiz (YAML-Datei).

docker-compose.yml startet DOCKER NETZWERK n8n Automation Port 5678 postgres Datenbank Port 5432 traefik Reverse Proxy Port 80 / 443 VOLUME Daten persistent

n8n mit Docker Compose installieren

Das ist die empfohlene Art, n8n auf deinem Server zu installieren. Erstelle zuerst einen Ordner und dann eine Compose-Datei:

Ordner anlegen & Datei erstellen
mkdir ~/n8n && cd ~/n8n
nano docker-compose.yml

Füge diesen Inhalt in die Datei ein (Strg+X, dann Y, dann Enter zum Speichern):

Achtung – YAML ist empfindlich: In einer YAML-Datei bestimmen Einrückungen die Struktur – ähnlich wie Absätze in einem Vertrag. Verwende zum Einrücken ausschliesslich Leerzeichen (je 2 pro Ebene), niemals die Tab-Taste. Ein einziger Tab bringt die ganze Datei zum Absturz. Am einfachsten: kopiere den folgenden Text komplett und füge ihn mit Rechtsklick → Einfügen (oder Strg+Shift+V im Terminal) direkt in nano ein.

docker-compose.yml
services:
  n8n:
    image: docker.n8n.io/n8nio/n8n
    container_name: n8n
    restart: always
    ports:
      - "5678:5678"
    environment:
      - N8N_HOST=deine-domain.ch
      - N8N_PORT=5678
      - N8N_PROTOCOL=https
      - WEBHOOK_URL=https://deine-domain.ch/
      - NODE_ENV=production
      - GENERIC_TIMEZONE=Europe/Zurich
      - TZ=Europe/Zurich

      # PostgreSQL aktivieren
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_PORT=5432
      - DB_POSTGRESDB_DATABASE=n8n
      - DB_POSTGRESDB_USER=n8n
      - DB_POSTGRESDB_PASSWORD=sicheres-passwort-hier
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      postgres:
        condition: service_healthy

  postgres:
    image: postgres:15
    container_name: n8n_postgres
    restart: always
    environment:
      - POSTGRES_USER=n8n
      - POSTGRES_PASSWORD=sicheres-passwort-hier
      - POSTGRES_DB=n8n
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U n8n"]
      interval: 5s
      timeout: 5s
      retries: 5

volumes:
  n8n_data:
  postgres_data:

Wichtig: Die PostgreSQL-Variablen sorgen dafür, dass n8n wirklich PostgreSQL verwendet. Ohne diese Angaben würde n8n trotz laufendem PostgreSQL-Container standardmässig seine lokale SQLite-Datenbank im Volume nutzen.

Port-Erklärung: 5678:5678 bedeutet: Links steht der Port auf dem Server, rechts der Port im Container. Docker leitet also Anfragen an Port 5678 des Servers an Port 5678 im n8n-Container weiter.

🔒 Sicherheit – Passwörter nie im Klartext: In Produktivumgebungen solltest du das Passwort nicht direkt in die docker-compose.yml schreiben. Erstelle stattdessen eine .env-Datei im selben Ordner mit POSTGRES_PASSWORD=dein-passwort und referenziere sie im Compose mit ${POSTGRES_PASSWORD}. Die .env-Datei dann nie ins Git committen.

Firewall-Hinweis: Wenn du die UFW-Firewall aktiviert hast (wie in der Server-Anleitung empfohlen), musst du Port 5678 freigeben – oder besser: du schaltest n8n hinter einen Reverse Proxy (Traefik oder Nginx) und gibst nur Port 80/443 frei. So ist n8n nie direkt exponiert: sudo ufw allow 5678 (nur für Tests, nicht für Produktion).

Starten
docker compose up -d     # -d = im Hintergrund starten

Was bedeutet -d? «detached» – der Container läuft im Hintergrund weiter, auch wenn du das Terminal schliesst. Ohne -d würde er stoppen, sobald du die Verbindung trennst.

Dein Docker-Spickzettel

Diese Befehle brauchst du immer wieder. Speichere sie dir ab oder schreibe sie kurz auf – in einer Woche kennst du sie auswendig.

Container starten & stoppen

BefehlWas er tut
docker compose up -dAlle Services starten
docker compose downAlle Services stoppen
docker compose restartAlle neu starten
docker start [name]Einzelnen starten
docker stop [name]Einzelnen stoppen

Status & Logs prüfen

BefehlWas er tut
docker psLaufende Container
docker ps -aAlle Container
docker logs [name]Log eines Containers
docker logs -f [name]Log live verfolgen
docker statsCPU & RAM live

Images & Updates

BefehlWas er tut
docker pull [image]Image herunterladen
docker imagesLokale Images anzeigen
docker compose pullAlle Images updaten
docker compose up -dNach Update starten
docker image prune -fAlte Images löschen

In Container springen

BefehlWas er tut
docker exec -it [name] shTerminal öffnen (sh, da viele Container kein bash haben)
docker inspect [name]Details anzeigen
docker volume lsVolumes auflisten
docker network lsNetzwerke anzeigen
docker system pruneAufräumen

Update-Routine (einmal pro Monat): docker compose pull && docker compose up -d && docker image prune -f — damit bleiben alle Container aktuell und der Server bleibt aufgeräumt.