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'sStell 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.
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.
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.
Docker hat eine eigene Sprache. Diese vier Begriffe begegnen dir überall – einmal verstanden, macht der Rest sofort Sinn.
Die Blaupause – unveränderlich, wie eine ISO-Datei. Einmal bauen, überall starten.
Die laufende Instanz eines Images – wie ein eingeschalteter Computer.
Persistenter Speicher – Daten bleiben erhalten, auch wenn der Container stoppt.
Dirigent für mehrere Container – definiert wer mit wem spricht.
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.
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.
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.
sudo apt-get update sudo apt-get remove -y docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc
Ein GPG-Schlüssel ist wie ein Echtheitszertifikat – er beweist, dass die Software wirklich von Docker stammt und nicht verändert wurde.
# 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
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
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.
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).
Docker ist installiert. Jetzt prüfen wir, ob alles funktioniert – und lernst dabei die wichtigsten Befehle kennen.
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.
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.
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.
Einzelne Container starten ist gut. Aber die meisten echten Anwendungen brauchen mehrere Container, die miteinander kommunizieren. Hier kommt Docker Compose ins Spiel.
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).
Das ist die empfohlene Art, n8n auf deinem Server zu installieren. Erstelle zuerst einen Ordner und dann eine Compose-Datei:
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.
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).
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.
Diese Befehle brauchst du immer wieder. Speichere sie dir ab oder schreibe sie kurz auf – in einer Woche kennst du sie auswendig.
| Befehl | Was er tut |
|---|---|
| docker compose up -d | Alle Services starten |
| docker compose down | Alle Services stoppen |
| docker compose restart | Alle neu starten |
| docker start [name] | Einzelnen starten |
| docker stop [name] | Einzelnen stoppen |
| Befehl | Was er tut |
|---|---|
| docker ps | Laufende Container |
| docker ps -a | Alle Container |
| docker logs [name] | Log eines Containers |
| docker logs -f [name] | Log live verfolgen |
| docker stats | CPU & RAM live |
| Befehl | Was er tut |
|---|---|
| docker pull [image] | Image herunterladen |
| docker images | Lokale Images anzeigen |
| docker compose pull | Alle Images updaten |
| docker compose up -d | Nach Update starten |
| docker image prune -f | Alte Images löschen |
| Befehl | Was er tut |
|---|---|
| docker exec -it [name] sh | Terminal öffnen (sh, da viele Container kein bash haben) |
| docker inspect [name] | Details anzeigen |
| docker volume ls | Volumes auflisten |
| docker network ls | Netzwerke anzeigen |
| docker system prune | Aufrä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.