Wer einen Shopware-Shop ernsthaft entwickelt, kennt das Problem: Das Live-System hat 30 GB
Produktbilder im public/media/-Ordner, dazu eine ähnliche Menge an Thumbnails.
Diesen Berg für jedes Staging zu synchronisieren ist langsam, teuer und nach drei Tagen wieder
veraltet. Schneller geht es, wenn die Staging-Instanz Bilder direkt aus dem Live-Shop nachlädt,
und zwar nur dann, wenn lokal kein Bild vorhanden ist.
Das Setup auf einen Blick
Drei Container per docker-compose: ein nginx-Proxy mit
Self-Signed-Zertifikat, ein Dockware-Dev-Image mit Shopware 6.7 und eine
MariaDB. Der Trick steckt an zwei Stellen:
- Eine
RewriteRulein derpublic/.htaccess, die alle Requests auf/media/*und/thumbnail/*per 302 auf den Live-Shop schickt, aber nur, wenn die Datei lokal nicht existiert. - Eine eigene
dev.conffür den nginx-Proxy, die HTTPS, Admin-Port 8888 und Mailhog-Port 9998 sauber durchreicht.
docker-compose.yml
version: "3.8"
services:
proxy:
container_name: proxy
image: dockware/proxy:latest
ports:
- "80:80"
- "443:443"
depends_on:
- shopwareshop
restart: always
volumes:
- "./dev.conf:/etc/nginx/conf.d/shop-1.conf"
shopwareshop:
image: dockware/dev:6.7.0.0
container_name: shopwareshop
environment:
- SHOP_DOMAIN=shopwareshop.de
entrypoint:
- bash
- -c
- |
sed -i 's|DATABASE_URL=.*|DATABASE_URL=mysql://shopuser:secret@db:3306/shopware|' /var/www/html/.env
sed -i '/RewriteEngine On/a\
\
# Proxy fuer Media/Thumbnail zum Live-Shop\
RewriteCond %{REQUEST_FILENAME} !-f\
RewriteCond %{REQUEST_URI} ^/(media|thumbnail)/ [NC]\
RewriteRule ^(media|thumbnail)/(.*)$ https://www.liveshop.de/$1/$2 [L,R=302,NC]' /var/www/html/public/.htaccess
/entrypoint.sh &
sleep 30
cd /var/www/html && bin/console theme:compile && bin/console assets:install && bin/console cache:clear
wait
volumes:
- "./git/button-king-6/custom:/var/www/html/custom"
- "./dev_bk/media:/var/www/html/public/media"
- "./dev_bk/thumbnail:/var/www/html/public/thumbnail"
db:
image: mariadb
container_name: mariadbshop
environment:
- MYSQL_ROOT_PASSWORD=hidden
- MYSQL_USER=dbuser
- MYSQL_PASSWORD=dbpassword
- MYSQL_DATABASE=shopware
volumes:
- "./mysqlconf:/etc/mysql/conf.d"
Warum das Entrypoint-Script so wichtig ist
Im shopwareshop-Service wird der Standard-Entrypoint überschrieben. Bevor Dockware den
eigentlichen Container startet, passieren drei Dinge:
- Die
DATABASE_URLin der.envwird auf den eigenen DB-Container umgebogen. - In die
public/.htaccesswerden direkt nachRewriteEngine Ondie Media-Proxy-Regeln eingefügt. - Nach 30 Sekunden Warmlauf werden Theme-Compile,
assets:installund Cache-Clear ausgeführt.
Wichtig: Das ist kein Apache-Reverse-Proxy, sondern eine einfache Redirect-Regel.
Der Browser bekommt die 302 zurück und holt das Bild selbst von www.liveshop.de. Das
spart zusätzlichen Apache-Modul-Overhead, vermeidet eine offene Ausgangsverbindung pro Request und
belastet die Bandbreite der Staging-Maschine nicht.
Die zwei Bedingungen sind das eigentliche Feature
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/(media|thumbnail)/ [NC]
RewriteRule ^(media|thumbnail)/(.*)$ https://www.liveshop.de/$1/$2 [L,R=302,NC]
!-fheißt: Die Datei existiert lokal nicht. Liegen für eine bestimmte Kategorie schon Bilder im gemounteten Volume, gewinnen die. Der Proxy springt erst ein, wenn lokal nichts vorhanden ist.^/(media|thumbnail)/beschränkt die Regel auf die zwei Shopware-Pfade. Bundles, statische Assets und Plugin-Resources bleiben unberührt.R=302statt 301 ist Absicht, damit der Browser den Redirect nicht permanent cacht. Sonst zeigt er auch nach einem lokalen Upload weiter auf den Live-Shop.
dev.conf: der nginx-Proxy
Dockware lauscht intern auf 80, 443, 8888 (Admin-UI) und 9998 (Mailhog). Die dev.conf
legt davor einen einzigen sauberen Eingang mit selbst-signiertem TLS:
server {
listen 80;
server_name shopwareshop.de;
location / {
proxy_pass https://shopwareshop;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
}
}
server {
listen 443 ssl;
server_name shopwareshop.de;
ssl_certificate /etc/nginx/ssl/selfsigned.crt;
ssl_certificate_key /etc/nginx/ssl/selfsigned.key;
location / {
proxy_pass https://shopwareshop;
}
}
server {
listen 8888 ssl;
server_name shopwareshop.de;
ssl_certificate /etc/nginx/ssl/selfsigned.crt;
ssl_certificate_key /etc/nginx/ssl/selfsigned.key;
location /admin { proxy_pass http://shopwareshop:8888; }
location /static { proxy_pass http://shopwareshop:8888; }
location /api { proxy_pass http://shopwareshop; }
location / { proxy_pass http://shopwareshop:8888; }
}
server {
listen 9998;
server_name shopwareshop.de;
location / {
proxy_set_header Host localhost;
proxy_pass http://shopwareshop:9998;
}
}
Damit ist die Storefront unter https://shopwareshop.de erreichbar, das Admin-Panel
unter https://shopwareshop.de:8888/admin und Mailhog unter
http://shopwareshop.de:9998.
Was lokal noch zu tun ist
-
Eintrag in der
/etc/hosts(bzw.C:\Windows\System32\drivers\etc\hosts):127.0.0.1 shopwareshop.de -
Datenbank-Dump vom Live-Shop einspielen (
mysql -u root -p shopware < dump.sql). Die DB-Struktur muss zur installierten Shopware-Version passen. -
Storage-Konfiguration in der
.envbzw. unterconfig/services.yamlauf lokales Filesystem stellen, sonst zeigen URLs auf einen S3-Bucket, der die Redirect-Regel umgeht.
Was zu beachten ist
1. DSGVO: Legt der Live-Shop kundenindividuelle Uploads (B2B-Datenblätter, signierte
Verträge, Reklamationsbilder) im /media/-Pfad ab, lädt jeder Aufruf der Staging-URL
diese Dateien beim Live-System nach. Für reine Produktbilder ist das unkritisch. Sobald
personenbezogene Inhalte dabei sind, gehört der Pfad-Filter feinjustiert (etwa nur
/media/produkt/* redirecten).
2. Bildänderungen werden „verschluckt": Wird im Live-Shop ein Produktbild
ausgetauscht, die Datenbank im Staging ist aber älter, fragt Shopware nach dem alten Dateinamen,
den es live nicht mehr gibt. Lösung: die Datenbank vor jedem Test frisch ziehen oder einen
404-Fallback in der RewriteRule akzeptieren.
3. Niemals in Produktion: Die Regel ist für Dev und Staging gedacht. In Produktion gehört der echte Storage-Layer konfiguriert (Filesystem, S3, CDN); Self-Redirects auf den eigenen Live-Host wären eine Endlosschleife.
4. Self-Signed-Zertifikat: Browser warnen bei shopwareshop.de. Für
Tests einmal akzeptieren oder das Zertifikat via mkcert als lokal vertrauenswürdig
markieren.
5. Theme-Compile dauert: Das sleep 30 im Entrypoint ist ein
pragmatischer Hack, kein sauberes Healthcheck-Pattern. Auf langsameren Maschinen besser auf
60 Sekunden erhöhen oder einen echten Wait-On-Loop einbauen.
Wann sich das wirklich lohnt
Bei kleinen Shops mit wenigen hundert MB Mediathek nicht; da reicht ein rsync.
Interessant wird der Ansatz, sobald eine Vollkopie spürbar Zeit frisst oder die Festplatte des
Dev-Rechners sprengt, also bei Shops ab einigen tausend Produkten mit Lifestyle-Bildern,
Konfigurator-Renderings oder PDF-Datenblättern. Dazu kommt: Das Setup eignet sich gut für
CI-Container, die einen frisch geklonten Shop in unter zwei Minuten aufstellen müssen.
Brauchen Sie ein verlässliches Staging-Setup?
Ob Dockware, eigene Compose-Files oder CI-gestützte Pipelines: Ich richte Shopware-Stagings so ein, dass sie wirklich nutzbar bleiben.
Anfrage senden