Eine Shopware Installation dauert nicht lange. Das ist die gute Nachricht, und sie ist überprüfbar: Wir haben für diesen Artikel Shopware 6.7.13.1 an einem Abend dreimal von Grund auf installiert und dabei jeden Schritt mit der Stoppuhr und dem Zollstock begleitet. Das Ergebnis vorweg — 17,5 Sekunden für das Herunterladen des Projekts mit leerem Cache, 27,3 Sekunden für die eigentliche Installation inklusive 848 Datenbank-Migrationen. Zusammen also unter einer Minute.
Die schlechte Nachricht steht nicht in der Dokumentation: Beide Installationswege, die wir getestet haben, endeten mit einer Erfolgsmeldung und einem Shop, der beim ersten Aufruf trotzdem nicht funktionierte. Nicht mit einem Absturz. Nicht mit einer roten Fehlerseite. Mit einem stillen HTTP 400 und einer höflichen Seite namens „Sales Channel Not Found”. Und in unserer Composer-Installation war zusätzlich der Administrator-Login kaputt, während system:install ausdrücklich [OK] gemeldet hatte.
Genau darum geht es in diesem Artikel. Nicht um das Abtippen der offiziellen Befehle — die stehen in der Shopware-Doku und sind dort korrekt. Sondern um das, was zwischen „Befehl abgesetzt” und „Shop läuft wirklich” passiert, mit echten Zahlen aus einem echten Lauf.
Die Kurzfassung für Eilige
| gemessener Wert | |
|---|---|
| Getestete Version | 6.7.13.1 (veröffentlicht 25.08.2026) |
composer create-project, leerer Cache | 17,5 s |
composer create-project, warmer Cache | 19,6 s |
| Heruntergeladene Cache-Daten | 84 MB |
| Projektgröße nach Download | 332 MB, 33.720 Dateien |
PHP-Dateien im vendor/ | 17.300 |
| Composer-Pakete | 164 |
system:install --basic-setup | 27,3 s, Spitzenspeicher 225 MB |
| Ausgeführte Migrationen | 848 |
| Erzeugte Tabellen | 252 |
| Datenbankgröße direkt nach Installation | 14,5 MB (7,1 MB Daten, 7,3 MB Indizes) |
| Produkte / Kunden / Bestellungen danach | 0 / 0 / 0 |
| Storefront erster Aufruf (kalter Cache) | 2,39 s |
| Storefront danach (Median aus 20 Läufen) | 9 ms |
| dockware-Container bis HTTP 200 | 13,9 s |
/usr/bin/time -f "%e", Speicher als MAXRSS. Datenbankgrößen aus information_schema.tables. HTTP-Zeiten mit curl -w "%{time_total}" gegen den eingebauten PHP-Webserver — bewusst kein Produktionsstack, die Relationen sind aussagekräftig, die Absolutwerte nicht auf Live-Systeme übertragbar.
Die wichtigste Zahl dieser Tabelle ist die, die nicht dort steht: Nach beiden erfolgreichen Installationen lag die Zeit bis zum ersten funktionierenden Storefront-Aufruf nicht bei 27 Sekunden, sondern bei „so lange, bis man verstanden hat, warum 400 kommt”.
Die drei Wege — und welcher wofür gedacht ist

Shopware kennt im Wesentlichen drei Installationswege, und die Verwirrung beginnt damit, dass sie im Netz gerne als gleichwertige Alternativen dargestellt werden. Das sind sie nicht — sie haben verschiedene Zielgruppen.
1. Composer (shopware/production). Der Weg für alles, was später ein echtes Projekt wird. Du bekommst ein Verzeichnis mit einer composer.json, die du versionieren kannst, und ab da ist deine Shop-Installation ein reproduzierbares Softwareprojekt. Das ist der Weg, den wir für die Messungen genutzt haben.
2. dockware (Docker). Ein fertiges Container-Image mit Apache, MySQL, PHP, Adminer, Mailcatcher — alles vorkonfiguriert und vorinstalliert. Gedacht für lokale Entwicklung und zum Ausprobieren. In 13,9 Sekunden vom docker run zum antwortenden Shop, inklusive 16 Demo-Produkten.
3. Das Zip-Archiv von shopware.com. Der klassische „hochladen und im Browser durchklicken”-Weg. Er existiert weiterhin und ist für Leute gedacht, die auf einem Shared-Hosting keinen Shell-Zugang haben.
Ein Detail, das viele Anleitungen falsch darstellen: Auf GitHub gibt es keine fertigen Installationspakete. Wir haben die Release-Daten von shopware/shopware abgefragt — das Release v6.7.13.1 hat null Assets. Was dort liegt, ist der Quellcode des Entwicklungs-Monorepos, nicht ein installierbares Paket. Wer „Shopware von GitHub herunterladen” als Installationsweg beschreibt, hat einen anderen Vorgang gemeint.
Welchen Weg wähle ich?
| Situation | Weg |
|---|---|
| Neues Kundenprojekt, Git, CI/CD | Composer |
| Nur mal anschauen, lokal, heute | dockware |
| Plugin-Entwicklung, mehrere Versionen parallel | dockware |
| Shared Hosting ohne SSH | Zip-Archiv |
| Bestehendes Projekt aktualisieren | Composer (kein Neuinstallieren) |
Systemanforderungen: was wirklich geprüft wird

Statt die Anforderungen aus der Dokumentation abzuschreiben, haben wir sie direkt aus der composer.json des installierten Cores ausgelesen — das ist die Datei, gegen die Composer beim Installieren tatsächlich prüft.
PHP-Versionen laut Core: ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0. Shopware 6.7 läuft also von PHP 8.2 bis 8.5. Wer PHP 8.1 einsetzt, kommt an Composer nicht vorbei — und zwar mit einer klaren Fehlermeldung, das ist der angenehme Fall.
Pflicht-Extensions: 20 Stück. Ausgelesen und gegen unsere Installation geprüft:
ctype, curl, dom, fileinfo, filter, gd, intl, json, libxml, mbstring, openssl, pdo, pdo_mysql, session, simplexml, sodium, xml, xmlreader, zip, zlib
Auf unserem System waren alle 20 vorhanden — was daran liegt, dass es ein gepflegter Webserver ist. Auf einer frischen Minimal-Installation fehlen erfahrungsgemäß zuerst intl, gd und sodium. Prüfen lässt sich das in einer Zeile, bevor man überhaupt anfängt:
php -r 'foreach(["ctype","curl","dom","fileinfo","filter","gd","intl","json","libxml","mbstring","openssl","pdo","pdo_mysql","session","simplexml","sodium","xml","xmlreader","zip","zlib"] as $e) if(!extension_loaded($e)) echo "FEHLT: $e\n";'
Datenbank. Wir haben gegen MariaDB 10.11.14 installiert, ohne jede Sonderkonfiguration — und es lief. Das ist erwähnenswert, weil im Netz viel über nötige MySQL-Tuning-Parameter geschrieben wird. Für die Installation stimmt das nicht. Unsere Werte während des Setups: innodb_buffer_pool_size 128 MB (der Standard, nicht empfohlen für Produktion), max_allowed_packet 16 MB, group_concat_max_len 1.048.576. Die Installation lief damit ohne eine einzige Warnung durch.
Speicher. Der Spitzenverbrauch von system:install lag bei 225 MB RSS. Ein memory_limit von 512 MB ist damit komfortabel, 256 MB reichen in unserem Lauf ebenfalls. Die verbreitete Empfehlung „setz es auf -1” ist für die Installation nicht nötig — sie kaschiert nur, dass niemand nachgemessen hat.
Weg 1: Composer, Schritt für Schritt gemessen
composer create-project shopware/production:6.7.13.1 sw67 --no-interaction
Das war der komplette Download. 17,5 Sekunden mit vollständig leerem Cache-Verzeichnis, 19,6 Sekunden mit warmem Cache.
Diese Reihenfolge hat uns stutzig gemacht — der kalte Lauf war schneller als der warme. Genau deshalb ist ein einzelner Messwert wertlos: Der Unterschied von 2,1 Sekunden liegt in der Schwankungsbreite des Netzwerks und der Paralleljobs von Composer, nicht in einem Effekt des Caches. Wir schreiben das hier hin, statt die unpassende Zahl wegzulassen. Wer aus zwei Läufen einen Trend liest, hat geraten.
Was danach auf der Platte liegt:
| Wert | |
|---|---|
| Projektgröße | 332 MB |
| Dateien insgesamt | 33.720 |
PHP-Dateien in vendor/ | 17.300 |
| Composer-Pakete | 164 |
| Composer-Cache danach | 84 MB |
du -sh auf das Projektverzeichnis, find . -type f | wc -l für die Dateizahl, composer show | wc -l für die Pakete. Cache-Größe aus dem für den Kaltlauf angelegten leeren Cache-Verzeichnis.
332 MB für ein leeres Shopsystem ist eine Zahl, die man kennen sollte, bevor man auf einem 10-GB-VPS drei Instanzen plant. Zum Vergleich: Das dockware-Image bringt intern 592 MB mit, davon 529 MB allein im vendor/ — weil dort zusätzlich die Entwicklungs-Abhängigkeiten liegen.
Bemerkenswert an der Ausgabe war außerdem die letzte Zeile: „No security vulnerability advisories found.” Composer prüft das Ergebnis inzwischen automatisch gegen die Schwachstellen-Datenbank. Bei einer frischen Installation der neuesten Version ist das erwartbar — bei einem drei Jahre alten Projekt ist es die nützlichste Zeile des ganzen Vorgangs.
Die Datenbank-Verbindung
Vor der Installation braucht Shopware eine .env.local. Der Stolperstein steckt in der Zeile, die am harmlosesten aussieht:
DATABASE_URL="mysql://sw67:SwTest2026%21@127.0.0.1:3306/sw67_test"
Das %21 am Ende des Passworts ist ein kodiertes Ausrufezeichen. DATABASE_URL ist eine URL, und Sonderzeichen im Passwort müssen prozentkodiert werden — sonst bricht die Verbindung an einer Stelle, die nach einem Datenbankproblem aussieht, obwohl es ein Parsing-Problem ist. Betroffen sind unter anderem @ : / ? # [ ] ! $ & ' ( ) * + , ; =.
Ebenfalls bewusst gewählt: 127.0.0.1 statt localhost. Bei localhost versucht PHP eine Unix-Socket-Verbindung, bei 127.0.0.1 eine TCP-Verbindung. Auf Systemen, deren Socket-Pfad von der PHP-Konfiguration abweicht, ist das exakt der Unterschied zwischen „läuft” und „Connection refused” — bei identischer Datenbank.
Die Installation selbst
php bin/console system:install --basic-setup --create-database --force --no-interaction
27,3 Sekunden. Was in dieser knappen halben Minute passiert, haben wir währenddessen aus einer zweiten Shell mitgezählt: Nach 24 Sekunden Laufzeit standen bereits 244 Tabellen, kurz darauf 252. Die Migrationen laufen also nicht gleichmäßig, sondern der Löwenanteil des Schemas entsteht in einem einzigen Block am Anfang.

Das Endergebnis:
| Wert | |
|---|---|
| Tabellen | 252 |
Einträge in migration | 848 |
| Datenbankgröße | 14,5 MB |
| davon Daten / Indizes | 7,1 MB / 7,3 MB |
Die Zahl, die uns überrascht hat: Die Indizes sind größer als die Daten. 7,3 gegen 7,1 MB. Das ist bei einem leeren Shop kein Zufall, sondern Bauart — Shopware legt das vollständige Indexschema unabhängig vom Inhalt an. Praktische Konsequenz für Backups und Migrationen: Die Datenbankgröße eines Shops sagt wenig über seine Inhaltsmenge aus, solange man Daten und Indizes nicht trennt.
Was --basic-setup nicht tut: Demo-Daten anlegen. Nach der Installation standen in unserer Datenbank 0 Produkte, 0 Kunden, 0 Bestellungen — aber 2 Sales Channels und 848 Migrationseinträge. Das dockware-Image dagegen kommt mit 16 Produkten und 1 Kunden. Wer die Installation testen will, sollte wissen, welche der beiden Ausgangslagen er vor sich hat, bevor er sich über einen leeren Shop wundert.
Der erste Fehler: „[OK]” trotz kaputtem Login

system:install meldete bei uns brav [OK] Successfully copied all bundle files und [OK] Cache ... successfully cleared. Exit-Code 0. Alles grün.
Dann der erste API-Login:
{"errors":[{"code":"0","status":"500","title":"Internal Server Error",
"detail":"Key provided is shorter than 256 bits, ..."}]}
Ursache: unser APP_SECRET war 29 Zeichen lang = 232 Bit. Die Grenze liegt bei 256 Bit, also 32 Zeichen. Wir lagen drei Zeichen darunter.
Das Bittere daran ist nicht der Fehler — den haben wir selbst verursacht, weil wir für den Test einen Platzhalter eingetippt haben. Das Bittere ist der Zeitpunkt, zu dem er sichtbar wird. Die Installation prüft die Länge nicht. Das Schema wird angelegt, die Bundles werden kopiert, der Cache wird gebaut, alles meldet Erfolg — und erst wenn ein Mensch sich zum ersten Mal in der Administration anmelden will, kippt es. Auf einem Kundensystem passiert das typischerweise Tage später, mit maximalem Abstand zwischen Ursache und Symptom.
Die Regel dahinter, die weit über Shopware hinausgeht: Ein Installer, der eine Konfiguration nur speichert statt sie zu validieren, verschiebt den Fehler in die Zukunft und macht ihn dabei teurer. Der Fix dauerte bei uns acht Sekunden:
# 32 Byte = 64 Hex-Zeichen = 512 Bit, sicher über der Grenze
NEW=$(openssl rand -hex 32)
sed -i "s/^APP_SECRET=.*/APP_SECRET=$NEW/" .env.local
php bin/console cache:clear
Danach lieferte derselbe Aufruf ein Token mit 419 Zeichen und GET /api/_info/version antwortete mit {"version":"6.7.13.1"}. Wir haben also nicht „vermutlich behoben”, sondern den Beweis geholt, der vorher gefehlt hat.
Wichtig für alle, die ihr Secret selbst setzen: openssl rand -hex 32 erzeugt 64 Zeichen. Die naheliegende Abkürzung openssl rand -hex 16 erzeugt 32 Zeichen — und die sehen aus wie „genau richtig”, liegen aber bei einer HMAC-Prüfung auf Bit-Ebene genau auf der Kante. Nimm die 64.
Der zweite Fehler: HTTP 400 statt Startseite
Der Shop lief. Die API antwortete. Und der Aufruf der Startseite lieferte:
HTTP/1.1 400 Bad Request
<title>Sales Channel Not Found</title>
Kein Absturz. Kein 500er. Kein Eintrag, der nach einem Notfall aussieht. Eine gestaltete Seite, die höflich mitteilt, dass sie den Verkaufskanal nicht kennt.
Die Ursache steht in einer einzigen Tabelle:
SELECT url FROM sales_channel_domain;
-- default.headless0
-- http://localhost:8099
Shopware ordnet eine eingehende Anfrage anhand des Host-Headers einem Sales Channel zu. Unser curl sprach 127.0.0.1:8099 an — in der Datenbank stand localhost:8099. Für einen Menschen ist das dieselbe Maschine. Für die Zuordnung sind es zwei verschiedene Domains, und keine davon heißt 127.0.0.1.
Der Beweis in drei Zeilen:
| Angesprochener Host | Antwort |
|---|---|
127.0.0.1:8099 | 400 Sales Channel Not Found |
localhost:8099 (Host-Header) | 200, 78.031 Bytes Storefront |
Und exakt derselbe Fehler trat im zweiten Installationsweg wieder auf. Der dockware-Container antwortete auf http://127.0.0.1:8100/ ebenfalls mit 400 — obwohl das Image fertig konfiguriert ausgeliefert wird und im Log fröhlich SHOP URL: http://localhost steht. Mit Host: localhost kam sofort eine 200 mit vollständigem Storefront.
| Host-Header an dockware | Antwort |
|---|---|
localhost | 200 (1,90 s, kalt) |
localhost:8100 | 400 |
127.0.0.1:8100 | 400 |
Das ist der eigentliche Fund dieses Abends: Zwei völlig verschiedene Installationswege, dieselbe Stolperfalle, und in beiden Fällen sieht das Ergebnis nicht nach einem Konfigurationsfehler aus, sondern nach einem kaputten Shop. Wer zum ersten Mal installiert, sucht an dieser Stelle den Fehler in der Datenbank, im Cache oder in den Berechtigungen — also überall dort, wo er nicht ist.
Auch interessant: localhost funktionierte beim Container, localhost:8100 nicht. Der Port ist Teil der gespeicherten Domain. Da dockware intern auf Port 80 lauscht und wir von außen 8100 gemappt haben, passt nur die portlose Variante.
Die Diagnose in einer Zeile
mysql -e "SELECT url FROM sales_channel_domain;" DEINE_DB
Was dort steht, muss exakt dem entsprechen, was der Browser in die Adresszeile schreibt — inklusive http/https, inklusive www, inklusive Port. Ändern lässt sich das in der Administration unter Verkaufskanäle → Domains, oder direkt beim Setup mit --shop-url.
Weg 2: dockware im Vergleich
Für lokale Entwicklung ist der Container-Weg schwer zu schlagen:
docker run -d --name shop -p 127.0.0.1:8100:80 dockware/dev:6.7.2.2
13,9 Sekunden vom Absetzen des Befehls bis zur ersten HTTP-200-Antwort — gemessen als Schleife mit Zwei-Sekunden-Takt, der Treffer fiel im fünften Versuch. Enthalten sind darin Apache, MySQL, PHP 8.3.25, Adminer, Mailcatcher, ein installierter Shop mit 236 Tabellen, 12,9 MB Datenbank und 16 Demo-Produkten.
Ein Detail, das wir aus eigener Praxis unterstreichen: Das -p 127.0.0.1:8100:80 ist kein Schönheitsfehler, sondern Pflicht. Die verbreitete Kurzform -p 8100:80 bindet den Port an 0.0.0.0 — also an jede Netzwerkschnittstelle des Servers, inklusive der öffentlichen. Wir haben genau diesen Fehler in der Vergangenheit teuer bezahlt: ein per Docker-Default offen ins Internet gebundener PostgreSQL-Port, der uns eine BSI-Meldung eingebracht hat. Wie man einen Server von Anfang an so aufsetzt, dass solche Dinge auffallen, haben wir in Linux Server einrichten und IT-Sicherheitslücken beschrieben.
Composer oder Container?
| Composer | dockware | |
|---|---|---|
| Zeit bis lauffähig | ~45 s (17,5 + 27,3) | 13,9 s |
| Belegter Platz | 332 MB + DB | ~1,8 GB Image |
| Demo-Daten | keine | 16 Produkte, 1 Kunde |
| Datenbank | selbst bereitstellen | enthalten |
| Versionierbar (Git) | ja | nur das Projekt darin |
| Für Produktion | ja | nein (Dev-Image) |
| Version wechseln | Composer-Constraint | anderes Image-Tag |
Die ehrliche Empfehlung: dockware zum Lernen, Ausprobieren und für Plugin-Entwicklung. Composer für alles, was jemals live geht. Und wer beides parallel nutzt, sollte wissen, dass die Versionen auseinanderlaufen — unser Container lief auf 6.7.2.2 mit 236 Tabellen, die Composer-Installation auf 6.7.13.1 mit 252. Elf Patch-Versionen entsprachen hier 16 zusätzlichen Tabellen.
Performance direkt nach der Installation
Nach dem Setup haben wir den Storefront vermessen — bewusst gegen den eingebauten PHP-Webserver, also ohne nginx, ohne OPcache-Tuning, ohne HTTP-Cache. Die Absolutwerte sind damit nicht auf Produktion übertragbar, die Relation aber sehr wohl:
| Zustand | Zeit |
|---|---|
Erster Aufruf nach cache:clear | 2,39 s |
| Zweiter Aufruf | 53 ms |
| Dritter Aufruf | 50 ms |
| Median aus 20 warmen Läufen | 9 ms |
| p95 aus 20 warmen Läufen | 12 ms |
curl -w "%{time_total}" gegen php -S, Host-Header localhost:8099, Storefront-Startseite (78.031 Bytes). Cache-Verzeichnis zwischen den Messreihen mit rm -rf var/cache/prod_* geleert.
Faktor 265 zwischen erstem und typischem Aufruf. Das ist der Grund, warum eine frisch deployte Shopware-Installation sich langsam anfühlt und zehn Minuten später nicht mehr — und warum ein Performance-Urteil nach dem ersten Klick wertlos ist. Wer nach einem Deployment misst, muss den Cache vorher warmlaufen lassen, sonst misst er das Kompilieren des Containers statt die Auslieferung der Seite.
Das gilt übrigens auch für die Live-Messung mit externen Tools: Wie man Web-Performance so misst, dass die Zahl etwas bedeutet, haben wir in unserem Core-Web-Vitals-Test umgesetzt.
Nach der Installation: was noch fehlt

Eine gelungene Installation ist noch kein Shop. Die Punkte, die in unserem Lauf offen blieben:
1. APP_ENV=prod. Der Standard aus dem Container-Setup ist dev — dockware lief bei uns ausdrücklich mit (env: dev, debug: true). Auf einem öffentlich erreichbaren System ist das eine Informationspreisgabe, kein Komfortmerkmal.
2. Ein echter Webserver. php -S ist ein Testwerkzeug, kein Server. Für Produktion braucht es nginx oder Apache mit PHP-FPM — die Grundlagen dazu stehen in nginx als Reverse Proxy und im Vergleich Apache vs nginx.
3. HTTPS. Ohne TLS keine sichere Session, und mit gemischten Protokollen im Sales-Channel-Domain-Eintrag landet man wieder bei genau dem 400er von oben.
4. Die Datenbank tunen. Unsere innodb_buffer_pool_size stand auf dem Standardwert von 128 MB. Für die Installation reicht das, für einen Shop mit echtem Katalog nicht ansatzweise.
5. Der Admin-Nutzer. --basic-setup legt admin mit dem Passwort shopware an. Das ist bequem und öffentlich dokumentiert — also auch für jeden anderen bequem.
6. Backups, bevor es Daten gibt. Der beste Zeitpunkt, das Wiederherstellen zu üben, ist der, an dem noch nichts kaputtgehen kann.
Was die Installation über die Kosten verrät
Eine Sache, die man in einer Installationsanleitung selten liest: Der Installationsvorgang selbst ist bei allen Editionen identisch. Was wir hier installiert haben, ist die Community Edition — quelloffen, ohne Lizenzkosten, mit demselben Kern, auf dem auch die kommerziellen Pläne aufsetzen.
Die Kosten entstehen nicht bei der Installation, sondern danach: Hosting, Plugins, Agenturzeit, Wartung. Wir haben das an anderer Stelle mit echten Zahlen durchgerechnet — in Was kostet Shopware 6? und in Shopware Shop Kosten. Wer noch vor der Entscheidung steht, ob überhaupt selbst gehostet werden soll, findet die Architekturfrage in Shopware Cloud vs. Self-hosted und den Systemvergleich in Shopify vs Shopware beziehungsweise in unserer Übersicht Bestes Shopsystem.
Häufige Fragen
Wie lange dauert eine Shopware Installation?
In unserer Messung am 29.08.2026: 17,5 Sekunden für composer create-project und 27,3 Sekunden für system:install, zusammen also unter einer Minute auf einem Server mit 12 vCPU und NVMe-Speicher. Über dockware waren es 13,9 Sekunden bis zur ersten HTTP-200-Antwort. Auf schwächerer Hardware und langsamerer Anbindung dauert es länger, die Größenordnung bleibt aber Minuten, nicht Stunden.
Welche PHP-Version brauche ich für Shopware 6.7?
Die composer.json des Cores erlaubt ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0, also PHP 8.2 bis 8.5. Wir haben mit PHP 8.3.6 installiert. Ältere Versionen lehnt Composer bereits beim Download mit einer eindeutigen Fehlermeldung ab.
Welche PHP-Extensions verlangt Shopware?
20 Stück: ctype, curl, dom, fileinfo, filter, gd, intl, json, libxml, mbstring, openssl, pdo, pdo_mysql, session, simplexml, sodium, xml, xmlreader, zip, zlib. Am häufigsten fehlen auf frischen Servern intl, gd und sodium.
Wie viel Speicherplatz braucht eine Shopware-Installation?
Nach composer create-project lagen 332 MB in 33.720 Dateien auf der Platte, dazu 14,5 MB Datenbank direkt nach dem Setup. Der Composer-Cache belegte zusätzlich 84 MB. Das dockware-Entwicklungsimage bringt intern 592 MB mit, davon 529 MB im vendor/-Verzeichnis.
Warum zeigt mein frisch installierter Shop „Sales Channel Not Found”?
Weil der aufgerufene Host nicht zu einem Eintrag in der Tabelle sales_channel_domain passt. Shopware ordnet Anfragen über den Host-Header zu — 127.0.0.1:8099 und localhost:8099 sind dabei zwei verschiedene Domains. Prüfen mit SELECT url FROM sales_channel_domain; und den Eintrag an die tatsächlich genutzte Adresse anpassen. Der Fehler liefert HTTP 400, keinen 500er, und sieht deshalb nicht wie ein Konfigurationsproblem aus.
Warum funktioniert der Admin-Login nach der Installation nicht?
Ein häufiger Grund ist ein zu kurzes APP_SECRET. Shopware verlangt mindestens 256 Bit, also 32 Zeichen. Bei uns waren es 29 Zeichen (232 Bit) — die Installation meldete trotzdem Erfolg, und erst der OAuth-Aufruf brach mit „Key provided is shorter than 256 bits” ab. Lösung: openssl rand -hex 32 erzeugt 64 Zeichen, danach cache:clear.
Wie viele Datenbanktabellen legt Shopware 6.7 an?
In unserer Installation von 6.7.13.1 waren es 252 Tabellen und 848 Migrationseinträge. Das dockware-Image mit Version 6.7.2.2 hatte 236 Tabellen — die Zahl wächst also mit jeder Version.
Legt die Installation Demo-Daten an?
system:install --basic-setup nicht: Nach unserem Lauf standen 0 Produkte, 0 Kunden und 0 Bestellungen in der Datenbank, aber 2 Sales Channels. Das dockware-Entwicklungsimage dagegen liefert 16 Demo-Produkte und einen Demo-Kunden mit.
Kann ich Shopware von GitHub herunterladen und installieren?
Nicht als fertiges Paket. Das Release v6.7.13.1 im Repository shopware/shopware hat keine Release-Assets — dort liegt der Quellcode des Entwicklungs-Monorepos. Für eine Installation nimmt man composer create-project shopware/production oder das Zip-Archiv von shopware.com.
Warum ist der erste Seitenaufruf so langsam?
Weil der Symfony-Container und die Twig-Templates beim ersten Zugriff kompiliert werden. Bei uns dauerte der erste Aufruf nach cache:clear 2,39 Sekunden, der Median der folgenden 20 Aufrufe lag bei 9 Millisekunden — Faktor 265. Nach jedem Deployment sollte der Cache deshalb warmgelaufen sein, bevor echte Besucher darauf treffen.
Fazit
Eine Shopware Installation ist technisch unspektakulär: zwei Befehle, unter einer Minute, 332 MB auf der Platte, 252 Tabellen in der Datenbank. Wer die 20 Extensions vorher prüft und das Passwort in der DATABASE_URL korrekt kodiert, kommt ohne Zwischenfälle durch.
Der eigentliche Aufwand liegt woanders — und das ist die Erkenntnis dieses Abends. Beide Installationswege endeten mit einer Erfolgsmeldung und einem Shop, der beim ersten Aufruf HTTP 400 lieferte. In einem Fall war zusätzlich der Administrator-Login kaputt, während der Installer ausdrücklich [OK] gemeldet hatte. Keiner dieser beiden Zustände erzeugt einen Absturz, einen Stacktrace oder einen Logeintrag, der nach einem Notfall aussieht. Sie sehen aus wie ein kaputtes System, sind aber zwei Zeilen Konfiguration.
Wer das weiß, verliert dabei zehn Minuten. Wer es nicht weiß, sucht einen Abend lang im Cache, in den Dateirechten und in der Datenbank — an allen Stellen also, an denen der Fehler nicht ist.
