Entwicklung und Produktion sind unterschiedlich. In der Entwicklung willst du Debug-Logs, lokale Datenbanken, keine echten E-Mails. In Produktion willst du das Gegenteil. Profile lösen dieses Problem elegant.
Ein Profil ist ein benannter Satz von Konfigurationen. Du definierst, was in welcher Umgebung gilt. Beim Start aktivierst du das passende Profil.
Der einfachste Weg: Separate Konfigurationsdateien pro Profil.
src/main/resources/
├── application.yaml # Gemeinsame Konfiguration
├── application-dev.yaml # Nur für Entwicklung
└── application-prod.yaml # Nur für Produktion
Die Namenskonvention ist application-{profil}.yaml.
application.yaml – gilt immer:
spring:
application:
name: arcade-highscore-api
server:
port: 8080application-dev.yaml – nur bei aktivem
dev-Profil:
logging:
level:
de.digitalfrontiers.arcade: DEBUG
org.springframework.web: DEBUG
spring:
data:
mongodb:
uri: mongodb://localhost:27017/arcade-devapplication-prod.yaml – nur bei aktivem
prod-Profil:
logging:
level:
root: WARN
de.digitalfrontiers.arcade: INFO
spring:
data:
mongodb:
uri: ${MONGODB_URI} # Aus Umgebungsvariable
server:
tomcat:
threads:
max: 400Mehrere Wege führen zum Ziel:
Kommandozeile:
./gradlew bootRun --args='--spring.profiles.active=dev'Umgebungsvariable:
export SPRING_PROFILES_ACTIVE=dev
./gradlew bootRunIn application.yaml (für Defaults):
spring:
profiles:
active: devIn der IDE: Die meisten IDEs haben ein Feld für aktive Profile in der Run-Konfiguration.
Spring Boot lädt die Konfigurationen in dieser Reihenfolge:
Profile-spezifische Werte überschreiben die Basis-Werte. Was nicht überschrieben wird, bleibt.
Du kannst mehrere Profile gleichzeitig aktivieren:
./gradlew bootRun --args='--spring.profiles.active=dev,debug,swagger'Alle genannten Profile werden geladen. Bei Konflikten gewinnt das zuletzt genannte.
Nicht nur Konfiguration – auch Beans können profilabhängig sein:
@Service
@Profile("dev")
public class MockEmailService implements EmailService {
@Override
public void send(String to, String subject, String body) {
// In Entwicklung: Nur loggen, nicht senden
log.info("Would send email to {}: {}", to, subject);
}
}
@Service
@Profile("prod")
public class SmtpEmailService implements EmailService {
@Override
public void send(String to, String subject, String body) {
// In Produktion: Echte E-Mail senden
mailSender.send(createMessage(to, subject, body));
}
}Mit dev-Profil wird MockEmailService
aktiviert. Mit prod-Profil SmtpEmailService.
Der restliche Code arbeitet mit dem EmailService-Interface
und merkt nichts.
| Profil | Zweck |
|---|---|
dev |
Lokale Entwicklung |
test |
Automatisierte Tests |
staging |
Staging-Umgebung |
prod |
Produktion |
debug |
Extra Debug-Logging |
docker |
Container-Deployment |
Die Namen sind Konvention, nicht Vorschrift. Du kannst beliebige Profile definieren.
Eine sinnvolle Basis-Konfiguration:
application.yaml:
spring:
application:
name: arcade-highscore-api
profiles:
active: dev # Default für Entwicklung
server:
port: 8080application-dev.yaml:
logging:
level:
de.digitalfrontiers.arcade: DEBUGapplication-prod.yaml:
logging:
level:
de.digitalfrontiers.arcade: INFO
server:
port: ${PORT:8080} # Cloud-Provider setzen PORTDas reicht für den Anfang. Mehr Profile kommen, wenn mehr Umgebungen dazukommen.
Profile sind mächtig – aber auch gefährlich. Zu viele Profile führen zu Konfigurationschaos. Niemand weiß mehr, welche Kombination was bewirkt.
Halte es einfach: - So wenig Profile wie nötig - Klare Trennung: dev, test, prod - Dokumentiere, was jedes Profil tut - Teste die Produktion nicht nur lokal