Von Nova Trent, Junior Entwicklerin bei Java Fleet Systems
Kurze Zusammenfassung – Das Wichtigste in 30 Sekunden
Für dich als Junior-Entwickler: Diese Woche habe ich endlich verstanden, wofür Spring Profiles gut sind und bin in die Docker-Welt eingetaucht! Mit Code Sentinels Hilfe habe ich meine Task-API von H2 In-Memory auf MySQL Docker umgestellt – ohne lokale MySQL-Installation! Du lernst hier, wie du mit einem docker-compose up
eine komplette Entwicklungsumgebung startest und mit Spring Profiles zwischen verschiedenen Setups switchst. Ein Codebase, multiple Umgebungen – das ist Production-ready Development! Plus: Preview auf Code Sentinels kommende 7-teilige Docker-Serie.
Hi Leute! 👋 Nova hier!
Letzte Woche hatte ich meine Task-API mit H2 zum Laufen gebracht und war mega stolz! Aber dann meinte Code Sentinel beim Kaffee: „Nova, H2 ist super für den Anfang, aber in der echten Welt verwendest du keine In-Memory Datenbank. Zeit für MySQL!“
Meine erste Reaktion: „Oh nein, jetzt muss ich MySQL installieren und konfigurieren… Das wird Stunden dauern!“ 😰
Code Sentinel: „Entspann dich! Ich richte dir das Docker-Setup ein, und du lernst dabei Spring Profiles. Das wird viel cooler als du denkst!“ 😎
Spoiler: Er hatte recht! Und er arbeitet gerade an einer 7-teiligen Docker Serie – nach dem was ich heute gelernt habe, wird die EPIC! 🚀
Code Sentinel’s Docker Installation & Setup
Code Sentinel: „Nova, bevor wir loslegen, brauchen wir erstmal Docker auf deinem Windows-Rechner. Ich zeige dir das Schritt für Schritt!“
Schritt 1: Docker Desktop Installation (Windows)
Code Sentinel führt mich durch:
- Download: Docker Desktop für Windows
- Installer starten:
Docker Desktop Installer.exe
- WICHTIG: „Use WSL 2 instead of Hyper-V“ auswählen ✅
- Installation läuft… (dauert ~5 Minuten)
- Neustart erforderlich (ja, schon wieder! 🙄)
Code Sentinel: „WSL 2 ist wichtig – das ist Windows Subsystem für Linux. Macht Docker viel schneller und ressourcenschonender!“
Nach dem Neustart:
- Docker Desktop startet automatisch
- Whale-Icon in der Taskbar erscheint 🐳
- „Docker Desktop is starting…“ → „Docker Desktop is running“ ✅
Erste Verifikation:
# PowerShell oder CMD öffnen docker --version # Docker version 24.0.6, build ed223bc docker run hello-world
Output:
Hello from Docker! This message shows that your installation appears to be working correctly. ...
Ich: „WOW! Das war einfacher als gedacht! Kein stundenlanges Konfigurieren!“ 🎉
Code Sentinel: „Docker Desktop macht das meiste automatisch. Früher war Docker-Setup auf Windows eine Qual – heute ist es plug-and-play!“
Schritt 2: Docker Compose Basics erklärt
Code Sentinel: „Nova, bevor wir MySQL starten, musst du verstehen was Docker Compose ist:“
Ohne Compose (umständlich):
docker run --name mysql-dev -e MYSQL_ROOT_PASSWORD=root123 -e MYSQL_DATABASE=taskmanager -e MYSQL_USER=nova -e MYSQL_PASSWORD=nova123 -p 3306:3306 -v mysql_data:/var/lib/mysql -d mysql:8.0
Mit Compose (elegant):
docker-compose up -d
Code Sentinel: „Compose = Infrastructure as Code! Einmal definieren, überall verwenden!“
Code Sentinel zu mir: „Nova, ich zeige dir das Docker-Setup, aber du musst verstehen was passiert. Keine Black-Box-Magic!“
Schritt 3: Docker Compose File (Code Sentinel erklärt)
Code Sentinel erstellt: docker-compose.yml
version: '3.8' services: mysql: image: mysql:8.0 container_name: taskmanager-mysql environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: taskmanager MYSQL_USER: nova MYSQL_PASSWORD: nova123 ports: - "3306:3306" volumes: - mysql_data:/var/lib/mysql healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] timeout: 20s retries: 10 volumes: mysql_data:
Code Sentinel: „Das ist wie ein Rezept für deinen MySQL Container. Docker Compose liest das und baut dir automatisch die komplette Umgebung auf!“
Meine Frage: „Was ist volumes? Und warum healthcheck?“
Code Sentinel: „Volumes = deine Daten überleben Container-Neustarts! Healthcheck = Spring Boot wartet, bis MySQL wirklich bereit ist. Keine ‚Connection failed‘ Fehler mehr!“
Ich: „Aha! Also kein Rätselraten mehr, ob MySQL schon bereit ist!“
Schritt 4: Docker starten (ich führe aus, Code Sentinel überwacht)
# Container starten docker-compose up -d # Status checken docker-compose ps
Output:
NAME COMMAND SERVICE STATUS PORTS taskmanager-mysql "docker-entrypoint.s…" mysql Up 0.0.0.0:3306->3306/tcp
Code Sentinel: „Und das Beste: Wenn du docker-compose down machst, ist alles wieder weg. Kein ‚verschmutztes‘ System!“
docker run --name mysql-dev -e MYSQL_ROOT_PASSWORD=root123 -e MYSQL_DATABASE=taskmanager -e MYSQL_USER=nova -e MYSQL_PASSWORD=nova123 -p 3306:3306 -v mysql_data:/var/lib/mysql -d mysql:8.0
Mit Compose (elegant):
docker-compose up -d
Code Sentinel: „Compose = Infrastructure as Code! Einmal definieren, überall verwenden!“
Ich: „Also wie Maven für Dependencies, aber für Container?“
Code Sentinel: „Genau! Du verstehst es!“ 😊
Spring Boot Profiles – Der Game Changer!
Code Sentinel: „Nova, jetzt kommt das Coole: Spring Profiles! Du kannst verschiedene Konfigurationen für verschiedene Umgebungen haben!“
Schritt 5: Application Properties aufteilen
Code Sentinel zeigt mir die Struktur:
src/main/resources/ ├── application.properties # Standard Config ├── application-dev.properties # H2 Development └── application-docker.properties # MySQL Docker
application.properties (Basis):
# Standard Settings für alle Profiles spring.application.name=taskmanager server.port=8080 # JPA/Hibernate Settings spring.jpa.hibernate.ddl-auto=create-drop spring.jpa.show-sql=true # Active Profile (default) spring.profiles.active=dev
application-dev.properties (H2):
# H2 In-Memory Database (wie bisher) spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password= # H2 Console spring.h2.console.enabled=true spring.h2.console.path=/h2-console # JPA Platform spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
application-docker.properties (MySQL):
# MySQL Docker Database spring.datasource.url=jdbc:mysql://localhost:3306/taskmanager spring.datasource.username=nova spring.datasource.password=nova123 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # MySQL Platform spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect # MySQL specific settings spring.datasource.hikari.maximum-pool-size=10 spring.datasource.hikari.minimum-idle=2
Code Sentinel: „Siehst du das Pattern? Du hast jetzt eine Basis-Config plus spezifische Configs pro Umgebung!“
Schritt 6: MySQL Dependency hinzufügen
pom.xml erweitern:
<!-- MySQL Connector (nur wenn docker profile aktiv) --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
Code Sentinel: „Das ist immer geladen, aber verwendet wird es nur mit docker profile!“
Der magische Profile-Switch! ✨
Code Sentinel: „Nova, jetzt pass auf – das ist der coole Teil:“
H2 Development Mode:
# Standard - läuft mit H2 mvn spring-boot:run # Oder explizit dev profile mvn spring-boot:run -Dspring-boot.run.profiles=dev
Browser: http://localhost:8080/h2-console
→ funktioniert! ✅
MySQL Docker Mode:
# Mit docker profile starten mvn spring-boot:run -Dspring-boot.run.profiles=docker
Log Output:
2024-01-15 10:30:15.123 INFO 12345 --- [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2024-01-15 10:30:15.456 INFO 12345 --- [main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2024-01-15 10:30:15.789 INFO 12345 --- [main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect
Ich: „HOLY SHIT! Gleiche App, verschiedene Datenbanken! Das ist wie Shapeshifting!“ 🤯
Meine ersten Tests mit beiden Setups
Test 1: H2 Profile (gewohnt)
# App mit H2 starten mvn spring-boot:run -Dspring-boot.run.profiles=dev # Task erstellen curl -X POST http://localhost:8080/api/tasks \ -H "Content-Type: application/json" \ -d '{"title":"H2 Test","description":"Memory Database"}' # H2 Console checken: http://localhost:8080/h2-console # Daten sind da! ✅
Test 2: Docker Profile (neu!)
# Docker MySQL läuft bereits docker-compose ps # Status: Up ✅ # App mit MySQL starten mvn spring-boot:run -Dspring-boot.run.profiles=docker # Task erstellen curl -X POST http://localhost:8080/api/tasks \ -H "Content-Type: application/json" \ -d '{"title":"MySQL Test","description":"Docker Database"}' # MySQL direkt checken docker-compose exec mysql mysql -u nova -p taskmanager
MySQL Console:
mysql> SELECT * FROM task; +----+--------------+-----------------+-----------+ | id | title | description | completed | +----+--------------+-----------------+-----------+ | 1 | MySQL Test | Docker Database | 0 | +----+--------------+-----------------+-----------+ 1 row in set (0.00 sec)
Ich: „DIE DATEN SIND ECHT DA! In einer echten Datenbank! Nicht nur im Speicher!“ 🎉
Profile-Switch während Development
Das Coolste: Ich kann jetzt einfach switchen!
# Morgens: Schnelle H2 Tests export SPRING_PROFILES_ACTIVE=dev mvn spring-boot:run # Nachmittags: Echte MySQL Tests export SPRING_PROFILES_ACTIVE=docker mvn spring-boot:run # Oder in der IDE: VM options: -Dspring.profiles.active=docker
Code Sentinel: „Siehst du? Ein Codebase, multiple Umgebungen! Das ist Production-ready Development!“
Was ich dabei gelernt habe
✅ Spring Profiles = Umgebungs-Magic
- Eine App, verschiedene Konfigurationen
application-{profile}.properties
überschreibtapplication.properties
- Switchen mit
-Dspring.profiles.active=profilename
✅ Docker Compose = Environment as Code
# Mein Setup ist jetzt versioniert! services: mysql: image: mysql:8.0 # Complete environment definition
✅ Volumes = Persistent Data
docker-compose down # Container stoppen docker-compose up -d # Neu starten # → Daten sind noch da! 🎉
✅ Development Flexibility
- H2: Super schnell für Unit Tests
- MySQL: Production-ähnlich für Integration Tests
- Switch per Command Line
Meine Stolpersteine (und Lösungen)
😅 „Profile nicht gefunden“
Fehler: application-dokcer.properties
(Typo!)
Lösung: Dateinamen genau prüfen: application-docker.properties
😅 „MySQL Connection refused“
Lösung: docker-compose ps
checken – Container muss laufen!
😅 „Table doesn’t exist“ nach Profile-Switch
Ursache: ddl-auto=create-drop
löscht Tabellen bei jedem Neustart
Learning: Das ist ok für Development, Production braucht Migrations!
😅 „Welches Profile ist gerade aktiv?“
Lösung: Spring Boot Log zeigt es:
2024-01-15 10:30:12.345 INFO 12345 --- [main] d.j.taskmanager.TaskmanagerApplication : The following profiles are active: docker
Code Sentinel’s Docker Serie Preview! 🐳
Code Sentinel: „Nova, das war nur ein Vorgeschmack! Ich arbeite an einer 7-teiligen Docker Serie für unser Blog am Freitag 05.09.2025 kommt der 1.Teil .“
🐳 Docker Serie – Coming Soon:
Container vs. VMs
Images, Die Docker-Serie umfasst 7 Hauptteile:
Teil 1: „Docker Fundamentals für Java Developers“
- Container vs. VMs – Unterschiede und Vorteile
- Images, Container, Volumes – mit Analogien erklärt
- Docker Installation (Linux, macOS, Windows)
- Beispiel: Postgres-Container starten + CloudBeaver/pgAdmin verbinden
Teil 2 – Docker Compose & Multi-Container Apps
- Service Orchestration mit
docker-compose.yml
- Netzwerke, Abhängigkeiten (
depends_on
) - Development Environments as Code
- Beispielprojekt: Spring Boot Personen-API mit Postgres + pgAdmin
Teil 3 – Production Docker – Security, Monitoring & Deployment
- Multi-Stage Builds (kleinere, sichere Images)
- Security Best Practices (non-root, read-only, cap_drop)
- Healthchecks + Ressourcengrenzen
- Monitoring (Actuator, Prometheus, Grafana)
- Supply Chain Security (SBOM, Trivy, Signaturen)
Teil 4 – Day-2 Operations & Orchestration Basics
- Day-2 Ops: Alles nach dem Deployment (Updates, Backups, Monitoring, Alerting)
- Updates & Rollouts (Immutable Tags, Rolling Updates, Blue/Green)
- Backup & Disaster Recovery (Postgres-Backup/Restore)
- Observability (Logs, Metrics, Traces – Prometheus/Grafana)
- Orchestration Basics: Compose vs. Swarm vs. Kubernetes
Teil 5 – Security & Advanced Kubernetes Strategies
- Security Essentials: non-root, Capabilities, Secrets, Scans, SBOM
- Zero-Downtime Strategien: Rolling, Canary, Blue/Green
- Advanced Kubernetes Features: Ingress Controller, Persistente Volumes, ConfigMaps & Secrets, Horizontal Pod Autoscaler
Teil 6 – CI/CD Integration für Docker & Kubernetes
- Pipelines für Build, Test, Deploy
- Vulnerability Scans (Trivy, Syft) in CI
- Image Signaturen (cosign)
- GitOps mit ArgoCD oder Flux
Teil 7 – Best Practices & Anti-Patterns
- Do’s & Don’ts beim Arbeiten mit Docker & Kubernetes
- Typische Fehler (Images zu groß, Secrets im Repo,
latest
in Prod) - Sentinel’s Best-Practices-Checkliste
Ich: „Nach heute kann ich es kaum erwarten! Docker ist ja noch viel mächtiger als ich dachte!“
An die Community: Eure Setups?
Fragen an euch:
- Wie managed ihr verschiedene Database-Environments? Profiles, Docker, oder was anderes?
- Docker Compose vs. einzelne Container – was ist euer Workflow?
- Testing-Strategy: H2 für Unit Tests, MySQL für Integration Tests?
Was ich wissen will:
- Production Profiles: Wie sehen eure
application-prod.properties
aus? - Secret Management: Passwörter in Properties = sicher? (Spoiler: probably not 😅)
- Database Migrations: Flyway vs. Liquibase für Schema-Updates?
Fazit: Profiles + Docker = Developer Superpowers! 🚀
Vorher: Eine App, eine Konfiguration, ein Setup
Nachher: Eine App, multiple Environments, flexible Development!
Das Beste: Code Sentinel hat mir das Setup eingerichtet, aber ich verstehe was passiert! Kein Black-Box-Magic!
Nächste Woche Learning Monday #4: „Testing meine Task-API – Unit Tests vs. Integration Tests“
Übrigens Cassian Holt hat gerade eine Testing Serie hier in unserem Block laufen!
Dann will ich lernen:
- Tests mit H2 Profile (schnell)
- Tests mit MySQL Docker (realistic)
- @TestContainers (Code Sentinel’s Geheimtipp!)
Docker Serie Watch: Code Sentinel’s erste Episode kommt diese Woche! 👀
Keep coding! (Mit den richtigen Tools!) 🔥
FAQ – Spring Profiles & Docker für Anfänger
Frage 1: Kann ich mehrere Profiles gleichzeitig aktivieren?
Antwort: Ja! spring.profiles.active=dev,debug,logging
– Spring lädt alle Properties files in Reihenfolge.
Frage 2: Was passiert wenn ich ein falsches Profile angebe?
Antwort: Spring Boot verwendet die default Config aus application.properties
. Kein Crash, aber möglicherweise unerwartetes Verhalten.
Frage 3: Docker Compose vs. einzelne docker run Commands?
Antwort: Compose für Multi-Container Setups (App + DB + Redis). Einzelne Commands für Quick-Tests. Compose ist „Infrastructure as Code“!
Frage 4: Sind meine Daten sicher in Docker Volumes?
Antwort: Ja, sie überleben Container-Neustarts. Aber für Production brauchst du Backup-Strategien und externe Storage!
Nächste Woche: „Testing mit verschiedenen Profiles – @TestContainers entdecken!“
0 Kommentare