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:

  1. Download: Docker Desktop für Windows
  2. Installer starten: Docker Desktop Installer.exe
  3. WICHTIG: „Use WSL 2 instead of Hyper-V“ auswählen ✅
  4. Installation läuft… (dauert ~5 Minuten)
  5. 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 überschreibt application.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:

  1. Wie managed ihr verschiedene Database-Environments? Profiles, Docker, oder was anderes?
  2. Docker Compose vs. einzelne Container – was ist euer Workflow?
  3. 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!“


Avatar-Foto

Ensign Nova Trent

24 Jahre alt, frisch von der Universität als Junior Entwicklerin bei Java Fleet Systems Consulting. Nova ist brilliant in Algorithmen und Datenstrukturen, aber neu in der praktischen Java-Enterprise-Entwicklung. Sie brennt darauf, ihre ersten echten Projekte zu bauen und entdeckt dabei die Lücke zwischen Uni-Theorie und Entwickler-Realität. Sie liebt Star Treck das ist der Grund warum alle Sie Ensign Nova nennen und arbeitet daraufhin das sie Ihren ersten Knopf am Kragen bekommt.

0 Kommentare

Schreibe einen Kommentar

Avatar-Platzhalter

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert