ONMA Ratgeber

Website erstellen mit Java: der komplette Weg vom leeren Projekt bis zur erreichbaren URL

Vom JDK über Spring Boot und PostgreSQL bis Docker zeigt der Leitfaden, wie du eine Java-Website erstellst, bereitstellst und Kosten realistisch einordnest.

SchrittWas passiertWomit
1Entwicklungsumgebung einrichtenJDK 25 LTS, IntelliJ IDEA Community oder VS Code
2Build-Tool festlegenMaven mit Wrapper im Repository
3Projekt anlegenSpring Boot über start.spring.io, eingebetteter Tomcat
4Seiten rendernSpring MVC plus Thymeleaf-Templates
5Daten speichernPostgreSQL, Spring Data JPA, Migrationen mit Flyway
6PaketierenAusführbares JAR, WAR nur im Ausnahmefall
7AusliefernDocker-Image, Reverse Proxy mit TLS, DNS auf den Server

Diese Anleitung führt genau einen Pfad durch: von der JDK-Installation bis zu der URL, die ein Browser im Internet aufrufen kann. Keine Technologiekunde, kein Sprachvergleich, kein Programmierkurs. Sieben zusammenhängende Schritte mit den Befehlen dazu, die Entscheidungen, die unterwegs anfallen, und am Ende die ehrliche Rechnung, was dieser Weg gegenüber einem CMS an Aufwand und laufenden Kosten bedeutet.

Wann Java für eine Website die richtige Wahl ist

Java lohnt sich, wenn die Seite mehr ist als Inhalt: Anmeldung mit Rollen und Rechten, Berechnungen, Buchungsvorgänge, Anbindung an ein ERP oder an eine Fachlogik, die ohnehin schon in Java existiert. Dann arbeitet das Web-Frontend im selben Typsystem, im selben Build und mit denselben Tests wie der Rest der Anwendung. Auch der Betrieb über viele Jahre spricht dafür: Long-Term-Support-Releases, stabile APIs, ein großer Arbeitsmarkt.

Für eine reine Inhaltsseite, also Leistungen, Referenzen, Blog und Kontaktformular, ist Java der teuerste vertretbare Weg. Java ist nur eine von mehreren Möglichkeiten, eine Website zu programmieren; die üblichen Alternativen sind HTML plus CSS für statische Seiten, ein Static Site Generator mit angebundenem CMS oder ein klassisches CMS. Wer nur Texte pflegen will, bekommt das dort ohne Servlet-Container und ohne eigenen Server. Die Kostenabgrenzung dazu steht weiter unten.

Zur Klarstellung, weil die Begriffe ständig vermischt werden: Java und JavaScript sind verschiedene Sprachen ohne gemeinsame Herkunft. Java läuft in diesem Aufbau auf dem Server, JavaScript bei Bedarf im Browser.

Schritt 1: JDK und Entwicklungsumgebung

Installiere ein JDK der aktuellen LTS-Version. Das ist Java 25, erschienen im September 2025. Laut Oracle Java SE Support Roadmap läuft dafür der Premier Support bis September 2030 und der Extended Support bis September 2033. Diese Termine gelten für Oracles kommerzielles Supportmodell; kostenfreie Distributionen haben eigene, meist ähnlich lange Wartungszeiträume. Verbreitete freie Builds sind Eclipse Temurin, Amazon Corretto und Azul Zulu.

Prüfe nach der Installation:

java -version
javac -version

Beide müssen dieselbe Hauptversion melden. Tun sie das nicht, zeigt der Pfad auf zwei Installationen, und der erste Compilerlauf scheitert an unklaren Fehlern. Als Editor reicht IntelliJ IDEA Community; VS Code mit dem Extension Pack for Java funktioniert ebenfalls. Mehr Werkzeug brauchst du für diesen Weg nicht.

Falls eine Bibliothek oder eine Cloud-Plattform Java 25 noch nicht unterstützt, ist Java 21 weiterhin eine tragfähige LTS-Basis mit Premier Support bis September 2028. Dann musst du später auch das Docker-Basisimage auf 21 setzen.

Schritt 2: Build-Tool festlegen

Maven oder Gradle. Maven ist im Spring-Umfeld der Standard, hat die größte Zahl auffindbarer Beispiele und eine XML-Konfiguration, die auch nach zwei Jahren noch lesbar ist. Gradle baut schneller und ist flexibler, verlangt aber mehr eigene Entscheidungen. Für eine erste Java-Website: Maven.

Wichtiger als die Wahl selbst ist der Wrapper. Die Dateien mvnw, mvnw.cmd und das Verzeichnis .mvn/ gehören ins Projekt und ins Repository. Damit baut jeder Rechner und jeder Server mit derselben Maven-Version, ohne dass irgendwo lokal etwas installiert sein muss. Alle folgenden Befehle laufen deshalb über ./mvnw, unter Windows über mvnw.cmd:

./mvnw test
./mvnw package
./mvnw spring-boot:run

Schritt 3: Spring-Boot-Projekt anlegen

Spring Boot gilt als schnellster Einstieg in eine Java-Web-App, weil es den Servlet-Container bereits mitbringt und wenig Konfiguration verlangt. Du startest also nicht mit einem Applikationsserver, sondern mit einem ausführbaren Programm, das selbst einen Webserver enthält.

Projekt erzeugen, ohne die Weboberfläche von start.spring.io zu öffnen:

curl -L "https://start.spring.io/starter.zip?type=maven-project&language=java&javaVersion=25&groupId=de.beispiel&artifactId=website&name=website&dependencies=web,thymeleaf,data-jpa,postgresql,flyway,validation,actuator" \
  -o website.zip
unzip website.zip -d website
cd website
./mvnw spring-boot:run

Danach antwortet die Anwendung auf http://localhost:8080. Der Fehler 404 an dieser Stelle ist korrekt: Der Server läuft, es gibt nur noch keine Seite. Der Prozess blockiert dein Terminal, beenden kannst du ihn mit Strg und C.

Schritt 4: Die erste Seite mit Thymeleaf

Spring MVC ordnet eine URL einer Java-Methode zu, Thymeleaf setzt die gelieferten Daten in ein HTML-Template ein. Die Templates bleiben gültiges HTML und lassen sich auch ohne laufende Anwendung im Browser öffnen. Zwei Dateien genügen für die erste erreichbare Seite.

src/main/java/de/beispiel/website/PageController.java:

package de.beispiel.website;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class PageController {

    @GetMapping("/")
    public String start(Model model) {
        model.addAttribute("titel", "Willkommen");
        return "index";
    }
}

src/main/resources/templates/index.html:

<!DOCTYPE html>
<html lang="de" xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title th:text="${titel}">Website</title>
</head>
<body>
  <h1 th:text="${titel}">Website</h1>
</body>
</html>

Statische Dateien, also CSS, Bilder und Schriften, liegen unter src/main/resources/static/ und sind direkt unter ihrem Pfad erreichbar. Ein Layout, das alle Seiten teilen, baust du mit Thymeleaf-Fragmenten, nicht mit kopiertem HTML.

Ein Hinweis zur Einordnung der älteren Stack-Begriffe, die bei der Recherche unweigerlich auftauchen: Servlets, JavaServer Pages und JavaServer Faces sind die klassische Java-Web-Landschaft, Applikationsserver wie Tomcat, JBoss und WebSphere ihr historisches Betriebsmodell. Die Servlet-Schnittstelle benutzt du weiterhin, aber hinter Spring MVC und ohne eigenen Applikationsserver. Java-Applets dagegen, also in eine HTML-Seite eingebettete und im Browser ausgeführte Java-Programme, sind für neue Websites keine Option mehr: Chrome entfernte die dafür nötige NPAPI-Unterstützung im September 2015, Firefox zog mit Version 52 im März 2017 nach, Oracle entfernte das Java-Browser-Plugin mit JDK 11, und die Applet-API selbst ist seit JDK 25 aus dem JDK verschwunden. Wer auf Applet-Anleitungen stößt, liest Material für Bestandssysteme.

Schritt 5: Datenbank anbinden

PostgreSQL ist für eine Java-Website die pflegeleichteste Wahl. Für die Entwicklung reicht ein Container:

docker run --name website-db \
  -e POSTGRES_DB=website -e POSTGRES_USER=website -e POSTGRES_PASSWORD=geheim \
  -p 5432:5432 -d postgres:16

In src/main/resources/application.properties:

spring.datasource.url=jdbc:postgresql://localhost:5432/website
spring.datasource.username=website
spring.datasource.password=${DB_PASSWORD}
spring.jpa.hibernate.ddl-auto=validate
spring.flyway.enabled=true

Gestartet wird dann mit gesetzter Umgebungsvariable:

export DB_PASSWORD=geheim
./mvnw spring-boot:run

ddl-auto=validate ist die wichtigste Zeile der Datei. Das Schema wird nicht von Hibernate erzeugt, sondern von versionierten SQL-Dateien unter src/main/resources/db/migration/, etwa V1__initiales_schema.sql. Hibernate prüft beim Start nur noch, ob Java-Modell und Schema zusammenpassen. Wer stattdessen ddl-auto=update benutzt, spart sich anfangs die SQL-Dateien und hat beim ersten Produktionsumzug kein nachvollziehbares Schema mehr.

Zugangsdaten gehören nie ins Repository. In Produktion überschreibt die Umgebungsvariable SPRING_DATASOURCE_PASSWORD den Wert zur Laufzeit; das Verbindungspooling übernimmt Spring Boot automatisch über HikariCP.

Schritt 6: JAR oder WAR, und welcher Servlet-Container

Diese Entscheidung fehlt in den meisten Anleitungen, bestimmt aber den gesamten Betrieb.

JAR mit eingebettetem Container. ./mvnw clean package erzeugt target/website-0.0.1-SNAPSHOT.jar. Die Datei enthält die Anwendung und einen Tomcat, gestartet wird mit java -jar target/website-0.0.1-SNAPSHOT.jar. Ein Artefakt, ein Prozess, eine Portnummer, ein Log. Das ist der Normalfall und der einzige Weg, den diese Anleitung weiterverfolgt. Die Tests laufen vorher mit ./mvnw test.

WAR für einen externen Applikationsserver. Nur sinnvoll, wenn im Unternehmen bereits ein Tomcat, WildFly oder WebSphere betrieben wird und die Anwendung dort hineingehört. Dann setzt du <packaging>war</packaging> in der pom.xml, lässt die Hauptklasse von SpringBootServletInitializer erben und markierst spring-boot-starter-tomcat als provided. Der Preis: Deployment über fremde Konsolen, geteilter Speicher mit anderen Anwendungen und ein Container, dessen Version du nicht allein bestimmst.

Zur Auswahl des eingebetteten Containers: Tomcat ist Standard und passt fast immer. Jetty ist schlanker bei vielen gleichzeitigen, langlebigen Verbindungen, Undertow liegt dazwischen. Ohne gemessenen Anlass bleibt es bei Tomcat, weil zu jeder Fehlermeldung bereits eine Lösung dokumentiert ist.

Schritt 7: Container bauen und deployen

Ein zweistufiges Dockerfile hält das Image klein, weil das JDK nur zum Bauen gebraucht wird und nicht im Ergebnis landet:

FROM eclipse-temurin:25-jdk AS build
WORKDIR /src
COPY . .
RUN ./mvnw -B package -DskipTests

FROM eclipse-temurin:25-jre
WORKDIR /app
COPY --from=build /src/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app/app.jar"]

Gebaut wird mit docker build -t website:1.0 .. Auf dem Server laufen dann drei Dinge: der Anwendungscontainer auf Port 8080, PostgreSQL, und ein Reverse Proxy, der Port 443 nach 8080 weiterreicht und das TLS-Zertifikat verwaltet. Caddy erledigt das mit drei Zeilen und holt das Let’s-Encrypt-Zertifikat selbst, nginx braucht zusätzlich certbot:

www.beispiel.de {
    reverse_proxy app:8080
}

Port 8080 bleibt dabei unveröffentlicht; die Anwendung spricht niemals direkt mit dem Internet. Was sonst zum laufenden Betrieb gehört: ein Healthcheck unter /actuator/health aus spring-boot-starter-actuator, restart: unless-stopped im Compose-File für den Neustart nach einem Server-Reboot, ein Backup per pg_dump im Cron samt getesteter Wiederherstellung, und Logs an einem Ort, an dem man sie später wiederfindet. Erst wenn die Domain per DNS auf den Server zeigt und das Zertifikat ausgestellt ist, ist die URL erreichbar. Dass die Seite danach auch gefunden wird, ist eine eigene Aufgabe und nicht Teil dieses Ablaufs.

Java ausprobieren ohne lokale Installation

Wer vor Schritt 1 nur prüfen will, ob ihm die Sprache liegt, braucht kein JDK. Online-Editoren wie mycompiler.io, JDoodle oder OneCompiler führen Java-Code direkt im Browser aus, ohne Anmeldung und ohne Setup: Eingabefeld, Ausführen-Knopf, Konsolenausgabe.

Die Grenze dieser Werkzeuge ist klar. Sie führen ein Programm aus und zeigen dessen Konsolenausgabe. Eine Spring-Boot-Anwendung lädt Abhängigkeiten, öffnet einen Port und wartet dauerhaft auf HTTP-Anfragen, und genau das können die meisten dieser Editoren nicht abbilden. Für Syntax, Klassen, Collections und erste Übungen sind sie ideal, für die Website ab Schritt 3 nicht. Wer eine Zwischenstufe will, nimmt GitHub Codespaces oder Gitpod: Dort läuft eine vollständige Umgebung im Browser, inklusive Maven und erreichbarer Ports, und der gesamte Ablafolgt bis Schritt 7 funktioniert auch dort.

Aufwand und Kosten gegenüber einem CMS

Die ehrliche Abgrenzung, damit die Entscheidung vor dem ersten Befehl fällt und nicht nach drei Wochen:

Java-Website (Spring Boot)Website im CMS
Erste erreichbare Seitevon 1 bis 3 Tagen mit Java-Vorkenntnissenwenige Stunden
Inhalte pflegenohne eigenes Redaktionssystem nur über ein neues Deploymentim Browser, ohne Entwickler
Hostingeigener VPS oder Container-Plattform, allein die JVM belegt ab etwa 1 GB RAMShared Hosting genügt
Laufende Kosten pro Monatvon etwa 5 bis 20 Euro für einen kleinen VPS, mehr mit verwalteter Datenbank oder Container-Plattformvon etwa 3 bis 10 Euro für Shared Hosting mit Domain und Datenbank
WartungJDK-Updates, Spring-Updates, Datenbank, Zertifikate, Backups, MonitoringKern- und Plugin-Updates
Stärkeeigene Fachlogik, Anbindungen, eigenes DatenmodellInhalt, Struktur, Tempo

Zu den Zahlen: Ein VPS mit 2 vCPU und 4 GB RAM liegt bei den gängigen europäischen Anbietern im September 2026 bei etwa 5 bis 8 Euro im Monat, bei manchen zuzüglich eines kleinen Betrags für die IPv4-Adresse und für Backup-Speicher. Eine verwaltete PostgreSQL-Instanz statt des selbst betriebenen Containers kostet erfahrungsgemäß noch einmal etwa so viel wie der Server selbst. Shared-Hosting-Pakete mit Domain, Datenbank und E-Mail starten bei ungefähr 3 Euro. Aktionspreise gelten meist nur im ersten Vertragszeitraum; für den Vergleich zählt der reguläre Folgepreis, und Anbieterpreise ändern sich, also prüfe sie vor der Entscheidung nach.

Die Hosting-Zeile ist der Punkt, an dem die meisten Projekte kippen. Eine Java-Anwendung ist ein dauerhaft laufender Prozess mit eigenem Speicherbedarf, kein PHP-Skript, das pro Anfrage startet und danach verschwindet. Damit fällt klassisches Shared Hosting aus, und der Vergleich läuft zwangsläufig gegen einen VPS oder eine Container-Plattform. Der größere Posten ist ohnehin nicht die Miete, sondern die Arbeit: Betriebssystem, JVM, Spring Boot, PostgreSQL, TLS, Backups und Überwachung wollen als Gesamtsystem gepflegt werden.

Der belastbare Test vor der Entscheidung lautet deshalb nicht “kann ich Java”, sondern: Gibt es auf dieser Seite mindestens eine Funktion, die ein CMS nicht ohne Eigenentwicklung abbildet? Lautet die Antwort nein, ist der Weg oben technisch sauber und trotzdem die falsche Wahl.

Häufige Fragen

Ist Java für Anfänger geeignet, um eine Website zu bauen? Als erste Programmiersprache ist Java lernbar, aber der Weg zur fertigen Website führt zusätzlich über Build-Tool, Framework, Datenbank und Deployment. Das sind vier Themen neben der Sprache selbst. Für den reinen Spracheinstieg ist ein Online-Editor der kürzere Weg.

Brauche ich zwingend Tomcat als separate Installation? Nein. Das JAR aus Schritt 6 enthält den Servlet-Container bereits. Ein separater Applikationsserver ist nur nötig, wenn es ihn im Betrieb ohnehin schon gibt.

Braucht jede Java-Website eine Datenbank? Nein. Eine Seite ohne dauerhaft gespeicherte Daten startet auch ohne PostgreSQL. Sobald Inhalte, Konten oder Vorgänge gespeichert werden, sollte das Schema aber von Anfang an über Migrationen verwaltet werden.

Kann ich eine bestehende Java-Anwendung als Website zugänglich machen? Ja, das ist der eigentliche Stärkefall. Die Fachlogik bleibt unverändert, Spring MVC und Thymeleaf kommen als Web-Schicht darüber, Spring Data bindet die Datenbank an.

Was ist mit dem Google Web Toolkit? Mit GWT schreibst du Frontend-Code in Java, den ein Compiler in JavaScript für den Browser übersetzt. Für neue Projekte ist das ein Sonderweg mit eigener Wartungslast, nicht der hier beschriebene Pfad, der serverseitig rendert.