Von Code Sentinel, Technical Project Manager bei Java Fleet Systems Consulting

Kurze Zusammenfassung – Das Wichtigste in 30 Sekunden
Wir richten eine komplette lokale Dev-Umgebung als Container ein (Windows, macOS, Linux):
- Docker installieren und prüfen,
- PostgreSQL als Container starten (persistente Volumes),
- CloudBeaver (webbasierter DBeaver) als Container nutzen – keine Desktop-Installation nötig,
- Verbindung testen und typische Stolperfallen vermeiden.
Dazu bekommst du präzise Analogien zu Images, Containern und Volumes, damit das Konzept sitzt. 🛡️
Moin! Code Sentinel hier – Zeit für den Realitäts-Check 🛡️
Wer Container erst „später“ lernt, zahlt später mit Downtime und Frust. Wir starten jetzt – sauber, reproduzierbar, teamfähig.
1) Docker installieren (Windows, macOS, Linux)
Ziel: Docker Engine lauffähig + non-root (wo sinnvoll) + schneller Sanity-Check.
Windows 10/11 (Docker Desktop)
- Docker Desktop installieren (Standard-Setup).
- Bei der ersten Ausführung WSL 2 aktivieren (falls angeboten).
- Terminal öffnen (PowerShell oder CMD) und prüfen:
docker version docker run --rm hello-world→ Du solltest die „Hello from Docker!“ Nachricht sehen.
macOS (Docker Desktop)
- Docker Desktop für macOS installieren.
- Terminal:docker version docker run –rm hello-world
Linux (Ubuntu/Debian exemplarisch)
- Paketquellen vorbereiten und Docker Engine installieren (vereinfacht):sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg –dearmor -o /etc/apt/keyrings/docker.gpg echo „deb [arch=$(dpkg –print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable“ | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- Optional: User zur docker-Gruppe hinzufügen (ohne sudo arbeiten):sudo usermod -aG docker $USER # abmelden/anmelden oder: newgrp docker
- Sanity-Check:docker run –rm hello-world
2) Wichtige Docker Grundbegriffe
- Image = Blaupause (Read-only Template)
Denk an ein fertig vorinstalliertes OS-Abbild für genau eine App.
Analogie: Eine Backmischung (Image) ergibt immer identische Muffins – gleiche Zutaten, gleicher Ablauf. - Container = laufende Instanz eines Images
Ein Prozess mit Dateisystem, isoliert vom Host.
Analogie: Der gebackene Muffin – du kannst ihn essen (benutzen), zerstören (löschen) und neu backen (neu starten). - Volume = externer, persistenter Speicher
Unabhängig vom Lebenszyklus des Containers.
Analogie: Eine Frischhaltebox außerhalb des Ofens. Du kannst den Muffin austauschen, die Box (Daten) bleibt.
Merksatz: Image baut, Container läuft, Volume behält.
3) Unsere Referenz-Dev-Umgebung: PostgreSQL + CloudBeaver (DBeaver im Browser)
Warum CloudBeaver?
- DBeaver als Desktop-App ist super – aber CloudBeaver läuft als Container mit Web-GUI.
- Vorteil: Keine OS-spezifische Installation. Ein Compose-File reicht für alle drei Betriebssysteme.
Zielbild
- postgres (Datenbank) mit persistenten Volumes
cloudbeaver(Web-DBeaver) auf Port 8978- Gemeinsames Docker-Netzwerk
Projektstruktur (lokal)
dev-db/ ├─ docker-compose.yml ├─ .env └─ data/ # wird automatisch gefüllt (Volume-Mount)
.env (Beispielwerte – bei Bedarf anpassen)
POSTGRES_USER=devuser POSTGRES_PASSWORD=devpass POSTGRES_DB=devdb POSTGRES_PORT=5432 CLOUDBEAVER_PORT=8978
docker-compose.yml
services:
db:
image: postgres:16
container_name: dev-postgres
restart: unless-stopped
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
ports:
- "${POSTGRES_PORT}:5432"
volumes:
- ./data/db:/var/lib/postgresql/data
- ./data/init:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 10
networks:
- devnet
cloudbeaver:
image: dbeaver/cloudbeaver:latest
container_name: dev-cloudbeaver
restart: unless-stopped
ports:
- "${CLOUDBEAVER_PORT}:8978"
depends_on:
db:
condition: service_healthy
volumes:
- ./data/cloudbeaver:/opt/cloudbeaver/workspace
environment:
CB_SERVER_PORT: 8978
networks:
- devnet
networks:
devnet:
driver: bridge
Warum
./data/init?
Hier kannst du SQL-Skripte ablegen (z. B. 001_schema.sql, 002_sample_data.sql). Beim ersten Start führt Postgres sie automatisch aus.
4) Starten, prüfen, verbinden
4.1 Start
# im Ordner dev-db/ docker compose up -d docker compose ps
Erwartung:
- dev-postgres healthy
- dev-cloudbeaver running
4.2 CloudBeaver öffnen
- Browser: http://localhost:8978
- Ersteinrichtung (Wizard) → „New Connection“ → PostgreSQL wählen
Connection Settings (Beispiel):
- Host: db (Container-zu-Container) oder localhost (vom Host)
- Port:
5432(oder.env-Wert) - Database: ${POSTGRES_DB}
- Username: ${POSTGRES_USER}
- Password: ${POSTGRES_PASSWORD}
Tipp: Nutze
dbals Hostname in anderen Containern und localhost vom Host-Browser/Tools.
4.3 Erste Abfragen
Erzeuge ein Schema & Tabelle per CloudBeaver SQL Editor:
CREATE SCHEMA IF NOT EXISTS app;
CREATE TABLE IF NOT EXISTS app.users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT NOW()
);
INSERT INTO app.users (username) VALUES ('nova'), ('elyndra'), ('cassian'), ('sentinel');
SELECT * FROM app.users;
4.4 Logs & Debugging
docker compose logs -f db docker compose logs -f cloudbeaver
Beende:
docker compose down # oder inkl. Volumes löschen (Achtung: Daten weg!) docker compose down -v
5) Docker ohne Compose (nur Postgres, „Quick & Dirty“)
docker run -d --name dev-postgres -e POSTGRES_USER=devuser -e POSTGRES_PASSWORD=devpass -e POSTGRES_DB=devdb -p 5432:5432 -v $(pwd)/data/db:/var/lib/postgresql/data postgres:16
Für Windows PowerShell ersetze
$(pwd)durch${PWD}.
Warum trotzdem Compose?
- Services, Netzwerke und Volumes declarativ – „Development Environments as Code“.
6) Typische Stolperfallen & Sentinel-Fixes
- Port schon belegt (5432/8978):
Finde Prozess, ändere Port in.env, neu starten. - Daten „verschwinden“:
Prüfe, ob Volumes korrekt gemountet sind (docker inspect →Mounts). Ohne Mount → Daten weg nachdown -v. - „Falscher Hostname“ in CloudBeaver:
Vom Host aus: localhost. Von Container zu Container: Dienstname (db). - Langsamer Start auf Windows/macOS:
Docker Desktop Ressourcen prüfen (CPU/RAM) und ggf. erhöhen. - Berechtigungen (Linux):
Volume Ordner gehört root → sudo chown -R $USER:$USER data.
7) Für Java-Teams: Konfiguration versionieren
- dev-db/docker-compose.yml + .env.example ins Repo legen.
.envlokal kopieren, Passwörter nicht committen.- Optional:
init-Skripte für Schemas & Testdaten bereitstellen. - Benefit: Onboarding in 5 Minuten statt stundenlanges Setup.
8) FAQ – Häufige Fragen
F1: Warum CloudBeaver statt DBeaver Desktop?
A: Für Teams ist ein webbasierter Client im Container unschlagbar: keine Install-Varianz, identische Version, sofort einsatzbereit.
F2: Kann ich beides nutzen?
A: Ja. Viele nutzen CloudBeaver im Team und DBeaver Desktop für persönliche Workflows.
F3: Wie sichere ich meine Daten?
A: Das Volume ./data/db ist deine Wahrheit. Ergänze docker compose down ohne -v für persistente Daten. Backup: Ordner archivieren.
F4: Wie kontaktiere ich Postgres aus meiner Java-App im Container?
A: Verwende db:5432 als Host im Compose-Netz. Von außerhalb: localhost:5432.
F5: Wie lade ich initiale Daten?
A: Lege SQL-Dateien in ./data/init. Sie werden beim ersten Start ausgeführt (nicht bei jedem Restart).
9) Ausblick auf Teil 2 & 3
Teil 2: Docker Compose & Multi-Container Apps
- Services orchestrieren (App + DB + Redis)
- Netzwerke & Abhängigkeiten fein einstellen
- Dev Environments as Code – Profile & Overrides
Teil 3: Production Docker – Security, Monitoring & Deployment
- Multi-stage Builds (kleine, sichere Images)
- Security Best Practices (User, Caps, Rootless)
- Monitoring (Container-Logs, Healthchecks, Metriken)
Anhang: Schnelles Test-Schema (SQL)
CREATE SCHEMA IF NOT EXISTS demo;
CREATE TABLE IF NOT EXISTS demo.notes (
id SERIAL PRIMARY KEY,
title VARCHAR(100) NOT NULL,
body TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
INSERT INTO demo.notes (title, body) VALUES ('Hello Docker', 'It works!');
SELECT count(*) FROM demo.notes;
Tags: #Docker #PostgreSQL #DBeaver #CloudBeaver #JavaDevelopment #DevOpsBasics

