Wichtiger Hinweis: Dieses Projekt ist veraltet! Bitte verwenden Sie die claranet/spryker-demoshop als Bootstrap-Referenz oder unser claranet/php Elternbild für einen generischen PHP-Anwendungsfall! Wir pflegen dieses Projekt nicht mehr.
Dieses Bild dient dazu, YVE und ZED die Basisinfrastruktur bereitzustellen. Infrastruktur in Bezug auf Build/INIT -Skripte und weitere Werkzeuge im Geschäft selbst. Dieses Bild bietet keinen fertigen Laden! Um die hier implementierten Funktionen zu verwenden, schreiben Sie Ihre eigene Dockerfile , die dieses Basisbild verwendet, um von Ihrer tatsächlichen Implementierung eines Spryker -Shops zu erben.
Dieses Projekt befindet sich noch in der Beta und wird mögliche Veränderungen unterziehen!
Deshalb möchten wir gerne Feedback von Ihnen erhalten! Dies ist eine laufende Arbeit, die sich bemüht, einen Spryker -Shop so einfach wie möglich zu docken. Um dieses Ziel erfolgreich zu erreichen, müssen wir gemeinsame Schritte identifizieren, die es wert sind, verallgemeinert und in dieses Basisbild einzusteigen. Erzählen Sie uns also von Ihren Bedürfnissen und Ihren Erfahrungen.
Wenn Sie dieses Bild in Aktion sehen möchten und wie es verwendet wird, schauen Sie sich den Container -Spryker Demoshop an. Dieser Demoshop dient als Referenzimplementierung für das Basisbild. Genauso wie Spryker ihre Bundles voranschreitet und den Demoshop die Veränderungen widerspiegelt, verwenden wir den Demoshop genauso.
Kernmerkmale sind:
ONBUILD Trigger -Funktion, um sich in den Prozess des Kinderbilders einzuschließen und zu steuernVorteile der Containerisierung:
Die erste Prämisse ist, dass wir beschlossen haben, den YVE- und ZED -Behälter aus einem Bild zu servieren. Der Vorteil besteht darin, die gemeinsam genutzte Code -Basis immer konsequent über einen ganzen Cluster zu aktualisieren. Kompromisse sind etwas größere Bilder, da die Anforderungen beider Komponenten einbezogen werden müssen.
Eine weitere Prämisse ist - und diese ist entscheidend für Ihr Verständnis dieses Stapels -, um ein einheitliches Bild über Entwicklungs- und Produktionsumgebungen hinweg aufzubauen. Dies wirkt sich auf die Verwendung von APPLICATION_ENV aus, die von der Spryker -App selbst bewertet wird.
Diese Variable hat den folgenden Einfluss:
Der Standort lokaler Konfigurationsdateien und externer Ressourcen ist nichts, was in der Container -Umgebung zusätzlich berücksichtigt werden muss, da alle diese Stapel sowieso isoliert sind. Bitte stellen Sie sicher, dass keine Konfigurationsanweisung unter ./config/Shared/ APPLICATION_ENV verwendet, um ihre Pfade zu identifizieren !!!
Wir betrachten nur Punkt 1.1, der eine Auszeichnung wert ist. Und da dies durch die Injektion von ordnungsgemäßen Vars in die effektiven Behälter erreicht werden kann, unterscheiden wir nicht zwischen Umgebungen, während wir die Bilder erstellen. Da Punkt 1.1 in der Regel mehr Abhängigkeiten behoben werden müssen, erstellen wir das Bild immer mit APPLICATION_ENV auf development . In welchem Modus die Anwendung jedoch tatsächlich ausgeführt wird, ist unabhängig vom Build.
Dies bedeutet, dass selbst die Produktionsbehälter Dev -Abhängigkeiten enthalten werden. Der Hauptgrund dafür ist die Anforderung für die DEV/Test/Prod -Parität, um sicherzustellen, dass sich die Container in allen Stadien und in allen Umgebungen genau gleich verhalten. Der Kompromiss für diese Prämisse ist wieder größere effektive Bilder. Während der Laufzeit kann das Verhalten der Spryker -Anwendung gesteuert werden, indem APPLICATION_ENV eingesetzt wird, die entweder development oder production akzeptiert. Wenn Sie das Skript ./docker/run verwenden, werden diese Variablen automatisch festgelegt.
Die Idee hinter den devel ./shop/docker enthaltenen Skripten prod Der Hauptunterschied zwischen diesen Umgebungen in Bezug auf docker-compose ist die Einstellung von Bindmontage im Entwicklungsmodus, mit dem der Entwickler die Codebasis von außen bearbeiten kann, während der Code im Hintergrund innerhalb der Container ausgeführt wird.
Da dieses Setup die manuellen Bemühungen reduziert Schauen Sie sich ./docker/run help
Die prod Umgebung ist zum Testen des Ergebniss Ihrer Arbeit in einer nahezu prodierten Umgebung gedacht, was bedeutet, dass keine gemeinsamen Daten zwischen Ihrem lokalen Repository und dem Container festgelegt werden. Darüber hinaus wird die Anwendung mit APPLICTION_ENV=production Produktionssatz ausgeführt, die die Entwicklungsspezifischen Erweiterungen deaktiviert.
Das von diesem Basisbild eingeführte Konzept besteht darin, das resultierende Shop -Bild in 3 verschiedene Ebenen aufzuteilen (effektiv gibt es mehr als nur 3 Schichten, da jede Aussage in der Dockerfile zu einer neuen Ebene führt; aber die Idee von 3 verschiedenen Schichten abstrakt die Onbuild -Trigger -Logik leichter und verständlich). Dafür gibt es ein paar Grunde:
Erstens sollte es den Docker -Cache nutzen und die iterativen Umbauten des Ladenbildes beschleunigen. Da diese Schichten von generisch zu spezifisch bestellt werden, sollte der Umbau des gesamten Stapels bei gleichzeitig iterativ an der Codebasis der tatsächlichen Ladenumsetzung reduziert werden.
Zweitens könnten verschiedene Schichten parallel abgerufen werden, während das Bild gezogen wird, was die Erstellung der Container beschleunigt, was nicht nur für die lokale Entwicklung relevant ist, sondern vielmehr für Bereitstellungen des Produktionsaufbaus. Da sich generische Schichten nicht so oft ändern, muss nicht nur für den Umbau, sondern auch für die Wiedergutschen des gesamten Bildes reduziert werden.
Leider kommt dies nicht ohne Kosten, die effektive Bildgröße ist etwas höher als die, die nur um eine Schicht aufgebaut wird. Im Moment scheint dies ein akzeptabler Kompromiss zu sein.
Was sind die Verantwortung dieser Schichten und wo befinden sie sich und wann werden sie gebaut?
claranet/spryker-base (dieses Bild):claranet/spryker-demoshop (das nachgelagerte Ladenbild, z. B. Demoshop):spryker-base -Bild (Gedanken an $REBUILD_BASE_LAYER Build -Variable) Falls Ihre PHP- oder Knotenabhängigkeiten aus einem privaten Repository gezogen werden müssen, müssen Sie nur eine ~/.netrc bereitstellen. Diese Datei wird automatisch als in den transienten Build -Container injiziertem Docker -Build erfasst, das von Git zum Klonieren der entsprechenden Repositorys verwendet wird und danach die Überdachungsschicht kurz vor der Schließung der Schicht ausgelöscht wird.
Das Format für das $HOME/.netrc lautet wie folgt:
machine git.company.local
login my_user_name
password my_private_token
Um alle angegebenen Abhängigkeiten in Kraft zu setzen, müssen entweder als HTTP -URL angegeben werden oder sie werden über git config --global "url.https://".insteadof "git://git@ die bereits vom Basisbild hergestellt wurde.
Wenn Sie spezifischere Regeln hinzufügen möchten, erstellen Sie ein Build -Skript in der Abhängigkeitsebene, das vor dem Abhängigkeitsauflösungsprozess ausgeführt wird:
vi docker/build.d/deps/300_private_repo_override.sh
#!/bin/sh
sectionText "Diverting git transport from SSH to HTTPS: https://git.company.local"
git config --global "url.https://git.company.local/".insteadof "[email protected]:"
git config --global "url.https://git.company.local".insteadof "ssh://[email protected]"
Da Git -URLs in einer willkürlichen Kombination angegeben werden können, ist dies unter bestimmten Umständen erforderlich.
Dies alles ist notwendig, da Docker sich weigert, Build -Zeitmengen zu implementieren, was diesen Prozess weitaus einfacher machen würde. Aber sie bekamen in der Tat auffällige Gründe, da ein Merkmal eine Reproduzierbarkeit riskieren würde, da Dockerfile nicht die einzige Quelle für Build -Intructions ist. Das ist - wie in jedem technischen Argument - keine absolute Wahrheit, nur Kompromisse.
Da in einer dockerisierten Umgebung externe Dienste in unterschiedlicher Adresse erreichbar sind, je nach Umgebung, in der der Code ausgeführt wird, müssen wir eine gewisse Konfiguration angepasst werden. Wir verwenden daher den spryker -nativen Mechanismus der Konfigurationsdatei -Vorrang, um unsere Konfiguration über die lokale Konfigurationsdateikonfiguration config/Shared/config_local.php zu injizieren. Da diese Datei diejenige ist, die alle anderen überschreibt.
Die Konfigurationsreihenfolge ist wie folgt:
config_default.php - Basiskonfigurationconfig_default-development.php - Konfiguration für den Entwicklungsmodus relevant (siehe APPLICATION_ENV )config_local.php - Site Lokale Konfiguration; In diesem Fall ist die Konfiguration für Container -Umgebungen.Mit dieser Reihenfolge können Sie Ihre Konfigurationsdatei unabhängig von der effektiven Umgebung, in der der Shop ausgeführt wird, vollständig verwenden. Sie können sogar unterschiedliches Verhalten zwischen Umgebungen steuern. Wir haben nur die SO -Sagen -Site -lokalen Einstellungen außer Kraft gesetzt, aus denen diese Idee stammt.
Hierzu mussten wir config/Shared/config_local.php aus der Liste .gitignore entfernen.
Derzeit devel und prod sowohl Umgebungen als auch prodieren nicht genannte Volumina, was auf die Annahme einer vorübergehenden Umgebung zurückzuführen ist. Dies bedeutet, dass der gesamte Stack für den einzigen Zweck erstellt wird, Ihre Code -Basis -Aginst zu überprüfen. Es ist unter keinen Umständen als ein Setup der Produktionsstufe, bei dem Daten über die Erholung von Containern bestehen müssen !!!
Der angenommene Workflow könnte beschrieben werden als:
Um die hier implementierten Funktionen wiederzuverwenden, müssen die folgenden Aspekte mit dem Basisbild in Einklang gebracht werden:
./src/Pyz - Ihre Shop -Implementierung./config - Konfiguration./public/{Yves,Zed} - Eintragspunkte für Ihre Anwendung (Dokumentroot)composer.json und composer.lockpackages.json , packages.lock und yarn.lock./docker/build.conf./docker/build.d/./docker/init.d/ platzierenSchauen Sie sich den Demoshop an, den wir hier für die Verwendung dieses Bildes vorbereitet haben. Dies sollte alle Fragen beantworten, die Sie möglicherweise haben.
Da die Referenzimplementierung der Demoshop ist, der von uns aufrechterhalten wird, ist dies ein ziemlich guter Starter. Entweder durch das Abgabeding dieses Repo oder durch Anfangen von vorne.
Wenn Sie von vorne anfangen möchten, sind die einzigen Interessenartefakte, die Sie vom Demoshop benötigen,:
./docker/*./Dockerfile./.dockerignore./config/Shared/config_local.phpAuf diese Weise sind Sie bereit, Ihr Repository mit Ihrem Code zu füllen und an Ihre individuellen Anforderungen anzupassen.
Achten Sie auf die Dockerfile , die so sauber aussieht:
FROM claranet/spryker-base:latest
Dies riecht nach Wiederverwendbarkeit. :)
Das Shop Skeleton und das Demoshop haben auch ein Shell -Skript unter ./docker/run Weitere Informationen finden Sie in der Readme.md.
# Build the image
./docker/run build
# Run the demoshop in development mode
./docker/run devel up
# Stop all the containers of the demoshop including their artifacts
./docker/run devel down -v
Diese Variablen sollen während der Containererstellung als Umgebungsvariablen bereitgestellt werden.
Die meisten Variablen werden von der Datei config/Shared/config_local.php konsumiert:
APPLICATION_ENV="production"SPRYKER_SHOP_CC="DE"ZED_HOST="zed"YVES_HOST="yves"ES_HOST="elasticsearch"ES_PROTOCOL="http"ES_PORT="9200"REDIS_STORAGE_PROTOCOL="tcp"REDIS_STORAGE_HOST="redis"REDIS_STORAGE_PORT="6379"REDIS_STORAGE_PASSWORD=""REDIS_SESSION_PROTOCOL="tcp"REDIS_SESSION_HOST="redis"REDIS_SESSION_PORT="6379"REDIS_SESSION_PASSWORD=""ZED_DB_USERNAME="postgres"ZED_DB_PASSWORD=""ZED_DB_DATABASE="spryker"ZED_DB_HOST="database"ZED_DB_PORT="5432"JENKINS_URL="http://jenkins:8080/"RABBITMQ_HOST="rabbitmq"RABBITMQ_PORT="5672"RABBITMQ_USER="spryker"RABBITMQ_PASSWORD=""YVES_SSL_ENABLED="false"YVES_COMPLETE_SSL_ENABLED="false"ZED_SSL_ENABLED="false"ZED_API_SSL_ENABLED="false"Durch Initialisierungshaken konsumiert:
ZED_ADMIN_PASSWORD - Wenn das Standardkennwort des Benutzers [email protected] festgelegt wird, wird zurückgesetztENABLE_XDEBUG - Das PHP -Modul xdebug wird aktiviert und konfiguriert.ENABLE_OPCACHE - Das PHP -Modul opcache wird aktiviert und konfiguriert. Diese Variablen sollen über Ihr Projekt spezifisch sind ./docker/build.conf
PROJECT (obligatorisch)-kontrolliert das Name Präfix der docker-compose -erstellten DiensteIMAGE (obligatorisch) - Wie heißt das resultierende Docker -Bild?VERSION (obligatorisch) - An welcher Version des Docker -Bildes arbeiten wir?BUILD_DEPENDENCIES - Debian (DEBIAN) -Pakete (Distribution), die während der Bauzeit installiert werden sollenBASE_DEPENDENCIES - DEBIAN (DEVIAN) -Pakete (Distribution), die zusätzlich installiert werden sollenPHP_EXTENSIONS - Space Seperierte Liste der zu installierenden PHP -ErweiterungenNPM_DEPENDENCIES - Verteilungspakete, die vor der NPM -Handhabung in der DEPS -Ebene intalliert sindKEEP_DEVEL_TOOLS (Standard: false) - Sollen Entwicklungswerkzeuge installiert und über den Build hinaus gehalten werden?SKIP_CLEANUP (Standard: Falsch) - Überspringen Sie die Reinigungsschritt in jeder Schicht -Build -Phase. Dies hilft bei der Debugging -Themen. Seien Sie sich bewusst, dass dies auch die Anmeldeinformationen abweist! Lassen Sie also niemals ein solches Bild in die Wildnis los !!!CRONJOB_HANDLER - definiert, wo Cronjobs registriert werden sollen. Derzeit werden Jenkins und Crond unterstützt.REBUILD_BASE_LAYER - Wenn dieses Build Var angegeben ist Um das Verhalten von Nginx, PHP-FPM oder PHP zu kontrollieren, können Sie entweder Konfiguration von der Außenseite des Containers als Bindungsmontage oder über Dockerfile des Kindergeschäftsbildes injizieren.
Die Konfiguration von Diensten ist darauf vorbereitet, mehrere Dateien einzuschließen, die die effektive Konfiguration bildeten.
Alle Konfigurationen sind in einem bestimmten Verzeichnis zu erwarten, in dem alle relevanten Dateien werden
Die erwarteten Standorte sind:
/etc/nginx/spryker/yves.conf.d/*.conf/etc/nginx/spryker/zed.conf.d/*.conf/etc/php/fpm/yves.conf.d/*.conf/etc/php/fpm/zed.conf.d/*.conf/etc/php/ini/*.ini .Die Standardkonfiguration ist unter:
/etc/php/fpm/zed.conf.d/100_base.conf
/etc/php/fpm/zed.conf.d/200_pm.conf
/etc/php/fpm/zed.conf.d/300_php.conf
/etc/php/fpm/yves.conf.d/100_base.conf
/etc/php/fpm/yves.conf.d/200_pm.conf
/etc/php/fpm/yves.conf.d/300_php.conf
/etc/php/ini/xdebug.ini
/etc/php/ini/opcache.ini
/etc/nginx/spryker/zed.conf.d/500-default.conf
/etc/nginx/spryker/yves.conf.d/500_default.conf
In Umgebungen, in denen Sie nur vollständige Verzeichnisse in den Container montieren können, haben wir einen Mechanismus vorbereitet, der eine Verzeichnishierarchie unter /mnt/configs erwartet und bei der Containererstellung alle Dateien unter diesem Standort zu ihrem entsprechenden Ort unter /etc/ symlinkiert.
# For example:
/mnt/configs/nginx/zed.conf.d/600-custom-headers.conf --> /etc/nginx/zed.conf.d/600-custom-headers.conf
/mnt/configs/php/fpm/yves.conf.d/500-raise-processes.conf --> /etc/php/fpm/yves.conf.d/500-raise-processes.conf
Aufgrund der Art von geschichteten Dateisystemen kann das unter diesem Basisbild ererbte Kinderbild Konfigurationen überschreiben, um das gewünschte Verhalten dieser Dienste zu erreichen.
Diese können problemlos angepasst werden, indem Konfigurationsdateien über die Dockerfile selbst bereitgestellt werden:
FROM claranet/spryker-base:latest
COPY my_custom_zed.conf /etc/nginx/spryker/zed.conf.d/custom.conf
Da der Onbuild -Trigger die ersten Anweisungen der untergeordneten Dockerfile sein wird, die ausgeführt werden sollen, werden diese überschriebenen Dateien zuerst während der Laufzeit des Containers verfügbar sein.
Die meisten im Basisbild getroffenen Entwurfsentscheidungen unterliegen der Idee der Anpassbarkeit und Erweiterbarkeit. Ein Basisbild, das nur einmal für ein einzelnes Ladenbild verwendet werden kann, ist ziemlich nutzlos und weit weg von etwas, das als Basis bezeichnet wird.
Der Build -Prozess ist so ziemlich so, wie der Name den Prozess vorschlägt, der das Bild erzeugt, das während der Laufzeit später von allen abgeleiteten Containern geteilt wird.
Einige Build -Skripte berücksichtigen Parameter, die Sie in ./docker/build.conf einstellen können
Siehe Referenz oben ..
Hook Dir: ./docker/build.d/
Wenn Sie entweder die aus dem Basisbild geerbten Build -Schritte erweitern oder deaktivieren möchten, müssen Sie Ihr benutzerdefiniertes Build -Skript unter ./docker/build.d/ platzieren. Dort finden Sie 3 Verzeichnisse, die jede Stufe/Ebene widerspiegeln:
./docker/build.d/base/ - Installationen der Basisbetriebsebene./docker/build.d/deps/ - Verwandte sich mit dem Laden spezifischer PHP/Knoten -Abhängigkeiten./docker/build.d/shop/ - Bearbeiten Sie die Codegenerierung der tatsächlichen Shop -Code -BasisSkripte jedes Unterdirs werden lexikalisch ausgeführt (actuall sace).
Wenn Sie beispielsweise die Art und Weise ändern möchten, wie der Navigations -Cache vom Basisbild erstellt wird, müssen Sie ein Skript an demselben Ort angeben, das vom Basisbild unter ./docker/build.d/shop/650_build_navigation_cache.sh bereitgestellt wird. Da das resultierende Bild sowie der Container Union -Dateisysteme verwenden, erhalten die vom Shop -Bild bereitgestellten Dateien Vorrang vor den vom BAS -Bild bereitgestellten. Durch diesen Mechanismus können Sie entweder eine Funktionalität deaktivieren, indem Sie einfach ein Skript bereitstellen, das nichts tut, oder das Verhalten durch Hinzufügen eines Skripts, das etwas anders oder zusätzlich macht.
Der oben beschriebene gleiche Mechanismus könnte verwendet werden, um die Initialisierung des Spryker -Containers und die gesamte Einrichtung zu ändern. Das Basisbild verfügt über aussagekräftige Standardeinstellungen, die für gemeinsame Umgebungen gültig sind, kann jedoch durch das Platzieren benutzerdefinierter Skripte an den entsprechenden Stellen überschrieben werden.
Das Basisbild liefert Haken für beide, die Initialisierung des gesamten Containers und für die Initialisierung des gesamten Setups.
Hook Dir: ./docker/entry.d/
Die Runtime Entrypoint-Argumente ( run-yves , run-zed , run-yves-and-zed , run-cron ), die über die Rolle dieser tatsächlichen Container verfügen, die die in diesem Hook-Verzeichnis aufgeführten Dateien enthält. Über Variablen entscheiden die Skripte, welche Dienste ermöglicht werden sollen und während der Laufzeit beginnen sollen.
Eine häufige Aufgabe wäre es, xdebug zu aktivieren, wie sie über Env Var ENABLE_XDEBUG bei der Containererstellung angefordert werden.
Aufgrund der Natur werden alle Haken auf jedem Containerstart ausgeführt.
Hook Dir: ./docker/init.d/
In der Regel muss jede Ladeninstanz erste Schritte ausführen, um ein solches Geschäft zu initialisieren. Während dieser Setup -Weitinitialisierung werden alle Shell -Skripte unter dem Hook -Dirum ausgeführt. Zum Beispiel zum Initialisieren der Datenbank mit Dummy -Daten wie dem Demoshop platziert das Skript unter ./docker/init.d/500_import_demo_data.sh .
Dies geschieht nicht implizit, ein separater Container muss mit dem Einstiegspoint Arg init hervorgebracht werden.
Hook Dir: ./docker/deploy.d/
Gleich wie das Init -Verfahren ist das Bereitstellungsverfahren. Dieses Verfahren wird während des Einsatzes durchgeführt. Das Lebenszykluskonzept besteht aus diesen 2 Hooks: Init wird zum ersten Mal aufgerufen, und jedes Mal, wenn eine neue Version des Bildes durchgeführt wird.
Dies geschieht nicht implizit, ein separater Container muss mit dem deploy hervorgebracht werden.
Wie bereits erwähnt, können Sie Ihre sehr benutzerdefinierten Build- und Init -Schritte hinzufügen. Das Skript ./docker/common.inc.sh hilft Ihnen bei einigen nützlichen Funktionen. Schau es dir selbst an.
Machen Sie Ihren Build -Schritt mithilfe von vorbereiteten Ausgabefunktionen aus:
errorText - einen Fehler erhöhensuccessText - Erfolg zurücksendensectionHead - Drucküberschrift für eine Gruppe von AufgabensectionText - Intermediate Build -Schrittinformationen drucken Wir bieten eine install_packages -Funktion für alle enthaltenen Build -Schritte. Bitte stellen Sie sicher, dass Sie es verwenden! Es kommt mit der Möglichkeit, Pakete als "Build" -Entreichungen zu kennzeichnen. Pakete, die als Build-Abhängigkeit gekennzeichnet sind, werden nach Abschluss des Schichtbaus entfernt. Pakete als Build -Abhängigkeiten einfach festgelegt --build Sie als erstes Argument ein:
# remove "gcc" at the end of our image build
install_packages --build gcc
# keep "top" in the resulting image
install_packages top
Wir befinden uns noch in den frühen Phasen dieses Projekts, daher ist die Dokumentation möglicherweise unvollständig. Wenn Sie mehr über die von uns angebotenen Funktionen erfahren möchten, schauen Sie sich bitte die Shell -Bibliothek an.
In den YVVE/ZED-Instanzen (s) finden Sie NGINX-, PHP-FPM- und Anwendungsprotokolle innerhalb /Daten/Protokolle/
Wir sind abhängig von den offiziellen PHP -Bildern: https://hub.docker.com/_/php/
Sehr gute Frage in der Tat!
Wir haben uns für Alpine entschieden, aufgrund der kürzeren Bildaufbauzeiten - sowohl die Quellbau- als auch die Verpackungsinstallation. Es war mehr oder weniger ein Proof-of-Concept, was nachweisen sollte, dass selbst schwere Hebeprojekte auf Alpine gehostet werden können. Die erwarteten Vorteile sind reduzierte Bildgrößen und eine schnellere Bauzeit sowie schnellere Laufzeiten.
Leider stellt sich heraus, dass Musl Lib C eine Einschränkung einführt, die im Kundenkontext unerträglich ist - wo die Vielseitigkeit der Schlüssel ist. Seit 0.9.6 haben wir zu Debian -basierten Bildern umgestellt.
Zwei Dinge fallen mir in den Sinn:
Weitere werden bald kommen. :)
Bitte werfen Sie einen Blick auf /Probleme.