Remarque importante: ce projet est obsolète! Veuillez utiliser le claranet/spryker-demoshop comme référence bootstrap ou notre image parent claranet/php pour un cas d'utilisation PHP plus générique! Nous ne maintenons plus ce projet.
Cette image sert à fournir l'infrastructure de base pour YVE et ZED. Infrastructure en termes de scripts de construction / init et d'outillage supplémentaire autour du magasin lui-même. Cette image ne fournit pas un magasin prêt à l'emploi! Afin d'utiliser les fonctionnalités implémentées ici, écrivez votre propre Dockerfile - qui utilise cette image de base pour hériter de - le long de votre implémentation réelle d'une boutique Spryker.
Ce projet est toujours en version bêta et subira des changements de rupture possibles!
C'est pourquoi nous voulons obtenir des commentaires de votre part! Il s'agit d'un effort de travail en cours qui s'efforce de rendre le dockrizant un magasin Spryker aussi simple que possible. Afin d'atteindre avec succès cet objectif, nous devons identifier les étapes courantes pour être généralisées et mettre dans cette image de base. Alors parlez-nous de vos besoins et de vos expériences.
Si vous voulez voir cette image en action et comment elle va être utilisée, consultez le Spryker Demoshop contenerisé. Ce Demoshop sert d'implémentation de référence pour l'image de base. De la même manière que Spryker progresse leurs faisceaux et fait que Demoshop reflète les changements que nous utilisons le Demoshop exactement de la même manière.
Les traits de base sont:
ONBUILD pour connecter et contrôler le processus de construction de l'image de l'enfantAvantages de la conteneurisation:
La première prémisse est que nous avons décidé de servir le conteneur YVE et ZED à partir d'une image. L'avantage consiste à mettre à niveau toujours systématiquement la base de code partagée sur un cluster entier. Le compromis est des images légèrement plus grandes, car les exigences des deux composantes doivent être incluses.
Une autre prémisse est - et celle-ci est cruciale pour votre compréhension de cette pile - pour construire une image unifiée dans les environnements de développement et de production. Cela affecte l'utilisation de APPLICATION_ENV qui est évaluée par l'application Spryker elle-même.
Cette variable a l'impact suivant:
L'emplacement des fichiers de configuration locale et des ressources externes n'est rien qui nécessite une considération supplémentaire dans l'environnement conteneurisé, car toutes ces piles sont isolées de toute façon. Veuillez donc vous assurer qu'aucune instruction de configuration sous ./config/Shared/ n'utilisera APPLICATION_ENV pour identifier leurs pattes !!!
Nous considérons uniquement le point 1.1 d'une distinction. Et comme cela pourrait être réalisé en injectant des VAR appropriés dans les conteneurs efficaces, nous ne faisons pas de distinction entre les environnements lors de la construction des images. Étant donné que le point 1.1 nécessite généralement plus de dépendances pour être résolues, nous construisons toujours l'image avec APPLICATION_ENV définie au development . Mais dans quel mode l'application sera réellement exécutée est indépendante de la construction.
Cela signifie que même les conteneurs de production auront des dépendances de développement incluses. La raison principale en est l'exigence de parité Dev / Test / Prod pour s'assurer que les conteneurs se comportent exactement les mêmes à toutes les étapes et dans tous les environnements. Le compromis pour cette prémisse est à nouveau des images efficaces plus grandes. Pendant l'exécution, le comportement de l'application Spryker peut être contrôlé en définissant APPLICATION_ENV qui accepte development ou production . Si vous utilisez le script ./docker/run ces variables seront définies automatiquement.
L'idée derrière les scripts fournies dans ce sous-dossier ./shop/docker suit la distinction de base entre les environnements devel et prod . La principale différence entre ces environnements en termes de docker-compose est l'emploi des supports de liaison en mode de développement, ce qui permet au développeur de modifier la base de code de l'extérieur tout en exécutant le code en arrière-plan dans les conteneurs.
Étant donné que cette configuration s'efforce de réduire les efforts manuels, nous avons préparé des scripts de coquille qui rendent la logique nécessaire et vous soutiennent avec les raccourcis pour les tâches les plus courantes comme la construction de l'image ou la création ou la démolition de la configuration du conteneur. Découvrez ./docker/run help
L'environnement prod est destiné à tester le résultat de votre travail dans un environnement proche de produit, ce qui signifie qu'aucune donnée partagée entre votre référentiel local et le conteneur ne sera établi. De plus, l'application sera exécutée avec APPLICTION_ENV=production qui désactive les extensions spécifiques au développement.
Le concept introduit par cette image de base consiste à diviser l'image de la boutique résultante en 3 couches distinctes (effectivement, il y a plus de 3 couches, car chaque instruction du Dockerfile se traduit par une nouvelle couche; mais l'idée de 3 couches distinctes résume la logique de déclenchement onbuild plus facilement et compréhensible). Il y a quelques raisons à ceci:
Tout d'abord, il devrait tirer parti du cache Docker et accélérer les reconstructions itératives de l'image de la boutique. Étant donné que ces couches sont commandées de générique à spécifique, la nécessité de reconstruire toute la pile tout en travaillant de manière itérative sur la base de code de l'implémentation réelle de l'atelier doit être réduite.
Deuxièmement, différentes couches pourraient être récupérées en parallèle tout en tirant l'image, ce qui accélère le temps de création de conteneurs qui est pertinent non seulement pour le développement local, mais plutôt pour les déploiements de la configuration de la production. De plus, comme les couches génériques ne changent pas souvent, le besoin non seulement pour les reconstructions mais pour le refus de l'image entière doit également être réduit.
Malheureusement, cela ne vient pas sans coût, la taille effective de l'image sera légèrement plus élevée que celle qui se renforce d'une seule couche. À l'heure actuelle, cela semble être un compromis acceptable.
Quelles sont les responsabilités de ces couches et où se trouvent-ils et quand vont-ils être construits?
claranet/spryker-base (cette image):claranet/spryker-demoshop (l'image de l'atelier en aval, par exemple le Demoshop):spryker-base (Mind the $REBUILD_BASE_LAYER Build Variable) Dans le cas où vos dépendances PHP ou Node doivent être retirées d'un référentiel privé, il vous suffit de fournir un ~/.netrc . Ce fichier sera automatiquement détecté et temporairement à mesure que Docker Build Arg a injecté dans le conteneur de construction transitoire, utilisé par Git pour cloner les référentiels appropriés, puis essuyé la couche de retenue juste avant la fermeture de la couche.
Le format pour le $HOME/.netrc est le suivant:
machine git.company.local
login my_user_name
password my_private_token
Afin de prendre effet, toutes les dépendances données doivent être données en tant qu'URL HTTP, soit se transformer via git config --global "url.https://".insteadof "git://git@ qui a déjà été préparé par l'image de base.
Si vous souhaitez ajouter des règles plus spécifiques, créez un script de construction dans la couche de dépendance qui est exécuté avant le processus de résolution de dépendance:
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]"
Étant donné que les URL GIT peuvent être données dans une combinaison arbitraire, c'est dans certaines circonstances nécessaires.
Tout cela est nécessaire car Docker refuse d'implémenter des volumes de temps de construction, ce qui faciliterait ce processus. Mais ils ont eu des raisons frappantes en effet, car une caractéristique de telle risque risquerait de reproductibilité, car Dockerfile n'est pas la seule source d'intructions de construction. Le Is - comme dans n'importe quel argument technologique - pas de vérité absolue, seulement des compromis.
Étant donné que dans un environnement dockerisé, les services externes sont accessibles sur différentes adresses en fonction de l'environnement dans lequel le code est en cours d'exécution, nous avons besoin d'une configuration pour être ajustée. Nous utilisons donc le mécanisme natif de Spryker de la priorité du fichier de configuration afin d'injecter notre configuration via le fichier de configuration local du site config/Shared/config_local.php . Puisque ce fichier est celui qui remplace tous les autres.
L'ordre de configuration est le suivant:
config_default.php - Configuration de baseconfig_default-development.php - Configuration pertinente pour le mode de développement (voir APPLICATION_ENV )config_local.php - Configuration locale du site; Dans ce cas, c'est la configuration de l'environnement conteneurisé.Cette commande vous permet d'utiliser votre fichier de configuration complètement indépendamment de l'environnement efficace dans lequel la boutique fonctionnera. Vous pouvez même contrôler un comportement différent entre les environnements. Nous prions simplement le SO pour dire les paramètres locaux du site, dont cette idée provient.
Pour cela, nous devions supprimer config/Shared/config_local.php hors de la liste .gitignore .
Actuellement, les deux environnements devel et prod en utilisant des volumes sans nom, ce qui est dû à l'hypothèse d'un environnement transitoire. Cela signifie que toute la pile est créée dans le seul but de vérifier votre base de code. Il n'est en aucun cas une certaine configuration de grade de production, où les données doivent persister sur les recréations de conteneurs !!!
Le flux de travail supposé pourrait être décrit comme:
Afin de réutiliser les fonctionnalités implémentées ici, les aspects suivants doivent être alignés sur l'image de base:
./src/Pyz - Implémentation de votre boutique./config - Configuration./public/{Yves,Zed} - Application des points d'entrée (Root Document)composer.json et composer.lockpackages.json , packages.lock et yarn.lock./docker/build.conf./docker/build.d/./docker/init.d/Découvrez le Demoshop que nous avons préparé à utiliser cette image ici. Cela devrait répondre à toutes les questions que vous pourriez avoir.
Étant donné que la mise en œuvre de la référence est le Demoshop qui est maintenu par nous, c'est un assez bon démarreur. Soit en ne faisant que ce dépôt, soit en partant de zéro.
Si vous voulez commencer à zéro, les seuls artefacts d'intérêt dont vous avez besoin dans le Demoshop sont:
./docker/*./Dockerfile./.dockerignore./config/Shared/config_local.phpPar cela, vous êtes prêt à remplir votre référentiel avec votre code et à le personnaliser à vos besoins individuels.
Attention au Dockerfile qui a l'air aussi propre que ceci:
FROM claranet/spryker-base:latest
Cela sent la réutilisabilité. :)
Le squelette de la boutique et le Demoshop ont également obtenu un script shell sous ./docker/run qui vous fournit des raccourcis aux tâches les plus courantes. Découvrez le Readme.md là-bas pour plus de détails.
# 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
Ces variables doivent être fournies pendant la création de conteneurs en tant que variables d'environnement.
La plupart des variables sont consommées par le fichier config/Shared/config_local.php :
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"Consommé par les crochets d'initialisation:
ZED_ADMIN_PASSWORD - Si définissez le mot de passe par défaut de l'utilisateur [email protected] sera réinitialiséENABLE_XDEBUG - Le module PHP xdebug sera activé et configuré.ENABLE_OPCACHE - Le module PHP opcache sera activé et configuré. Ces variables doivent être fournies via votre projet spécifique ./docker/build.conf
PROJECT (obligatoire) - contrôle le préfixe du nom des services créés docker-composeIMAGE (obligatoire) - Quel est le nom de l'image Docker résultante?VERSION (obligatoire) - Sur quelle version de l'image Docker travaillons-nous?BUILD_DEPENDENCIES - Distribution (Debian) Packages à installer pendant la durée de constructionBASE_DEPENDENCIES - Distribution (Debian) Packages à installer en plusPHP_EXTENSIONS - Espace Seperated List of PHP Extension à installerNPM_DEPENDENCIES - Packages de distribution qui seront intallés avant la manipulation du NPM dans la couche DEPSKEEP_DEVEL_TOOLS (par défaut: false) - Les outils de développement doivent-ils être installés et maintenus au-delà de la construction?SKIP_CLEANUP (par défaut: false) - Évitez l'étape de nettoyage dans chaque étape de construction de couche. Cela aide à déboguer les questions. Sachez que cela saute également les références! Alors ne publiez jamais une telle image dans la nature !!!CRONJOB_HANDLER - Définit où les cronjobs doivent être enregistrés. Actuellement, Jenkins et Cond sont pris en charge.REBUILD_BASE_LAYER - Si cette version Var est donnée, le calque de base sera reconstruit lors de la construction d'image de l'atelier en aval Afin de contrôler le comportement de Nginx, PHP-FPM ou PHP, vous pouvez soit injecter la configuration de l'extérieur du conteneur en tant que supports de liaison ou via Dockerfile de l'image de l'atelier d'enfant.
La configuration des services est prête à inclure plusieurs fichiers qui constituaient la configuration effective.
Toutes les configurations sont préparées à s'attendre à un répertoire spécifique où tous les fichiers pertinents
Les emplacements attendus sont:
/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 .La configuration par défaut se trouve sous:
/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
Dans les environnements où vous ne pouvez monter que des répertoires complets dans le conteneur, nous avons préparé un mécanisme qui s'attend à une hiérarchie de répertoire sous /mnt/configs et sur la création du conteneur, il symbolie tous les fichiers sous cet emplacement à leur emplacement correspondant sous /etc/ .
# 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
En raison de la nature des systèmes de fichiers en couches, l'image d'enfant héritant de cette image de base peut simpley écraser les configurations afin d'atteindre le comportement souhaité de ces services.
Ceux-ci peuvent facilement être personnalisés en fournissant vous-même des fichiers de configuration via le Dockerfile :
FROM claranet/spryker-base:latest
COPY my_custom_zed.conf /etc/nginx/spryker/zed.conf.d/custom.conf
Étant donné que le déclencheur OnBuild sera les premières directives de l'enfant Dockerfile à exécuter, ces fichiers remplacés seront d'abord disponibles pendant l'exécution du conteneur.
La plupart des décisions de conception prises à l'image de base sont régies par l'idée de personnalisation et d'extensibilité. Une image de base qui ne pourrait être utilisée qu'une seule fois pour une image de boutique individuelle est assez inutile et loin de quelque chose appelé Base.
Le processus de construction est à peu près comme le nom l'indique le processus qui produit l'image qui est partagé par tous les conteneurs dérivés pendant l'exécution plus tard.
Certains scripts de construction considèrent les paramètres que vous pouvez définir ./docker/build.conf
Voir référence ci-dessus ..
Hook dir: ./docker/build.d/
Si vous souhaitez prolonger les étapes de construction héritées de l'image de base ou les désactiver, vous devez placer votre script de construction personnalisé sous ./docker/build.d/ . Vous y trouverez 3 répertoires reflétant chaque étape / couche:
./docker/build.d/base/ - Installations de niveau du système d'exploitation de base./docker/build.d/deps/ - traiter avec les dépendances PHP / nœuds spécifiques à l'atelier./docker/build.d/shop/ - traiter la génération de code de la base de code d'atelier réelleLes scripts de chaque subdir sont exécutés lexicalement exécutés (actual d'origine).
Par exemple, si vous souhaitez modifier la façon dont le cache de navigation est construit par l'image de base, vous devez fournir un script au même endroit où il est fourni par l'image de base sous ./docker/build.d/shop/650_build_navigation_cache.sh . Étant donné que l'image résultante ainsi que le conteneur utiliseront des systèmes de fichiers syndicaux, les fichiers fournis par l'image de la boutique sont prioritaires sur ceux fournis par l'image BAS. Par ce mécanisme, vous pouvez soit désactiver une fonctionnalité simplement en fournissant un script qui ne fait rien ou vous pouvez modifier le comportement en ajoutant un script qui fait quelque chose de différemment ou en plus.
Le même mécanisme décrit ci-dessus pourrait être utilisé pour modifier la façon dont l'initialisation du conteneur Spryker et l'ensemble de la configuration doivent être exécutées. L'image de base est livrée avec des paramètres significatifs valides pour les environnements communs, mais pourrait être remplacé en plaçant des scripts personnalisés à des emplacements appropriés.
L'image de base fournit des crochets pour les deux, l'initialisation de chacun des conteneurs et pour l'initialisation de l'ensemble de la configuration.
Hook dir: ./docker/entry.d/
Les arguments d'entrée d'exécution ( run-yves , run-zed , run-yves-and-zed , run-cron ) régissant quel rôle ce conteneur réel a, tous les fichiers répertoriés dans ce répertoire de crochet. Via les variables, les scripts décident des services à activer et de commencer pendant l'exécution.
Une tâche commune serait d'activer xdebug comme demandé via Env var ENABLE_XDEBUG sur la création de conteneurs.
En raison de la nature, tous les crochets seront exécutés sur chaque début de conteneur.
Hook dir: ./docker/init.d/
Généralement, chaque instance de magasin doit effectuer des étapes initiales pour initialiser un tel magasin. Au cours de cette configuration, une large initialisation, tous les scripts de shell sous le hook dir se font exécuter. Par exemple, pour initialiser la base de données avec des données factices comme le Demoshop placent le script sous ./docker/init.d/500_import_demo_data.sh .
Cela ne se fait pas implicitement, un conteneur séparé doit être engendré avec le point d'entrée arg init .
Hook dir: ./docker/deploy.d/
Identique à la procédure d'initiation est la procédure de déploiement. Cette procédure sera effectuée lors des déploiements. Le concept de cycle de vie se compose de ces 2 crochets: init sera appelé la première fois, et le déploiement chaque fois qu'une nouvelle version de l'image sera effectuée.
Cela ne se fait pas implicitement, un conteneur séparé doit être engendré avec le deploy arg d'entrée.
Comme déjà mentionné, vous êtes libre d'ajouter vos étapes de construction et d'initiales très personnalisées. Le script ./docker/common.inc.sh vous aidera avec des fonctions utiles. Vérifiez-le par vous-même.
Rendez votre étape de construction révélatrice en utilisant des fonctions de sortie préparées:
errorText - augmenter une erreursuccessText - renvoyer le succèssectionHead - Tive imprimé pour un groupe de tâchessectionText - Imprimer les informations sur l'étape de construction intermédiaire Nous fournissons une fonction install_packages pour toutes les étapes de construction incluses. Veuillez vous assurer que vous l'utilisez! Il est livré avec la possibilité de signaler les packages en tant que dépendances "construire". Les packages signalés en tant que dépendances de construction seront supprimés après les finitions de construction de couche. Pour signaler les packages en tant que dépendances de construction, il suffit de --build comme premier argument:
# remove "gcc" at the end of our image build
install_packages --build gcc
# keep "top" in the resulting image
install_packages top
Nous en sommes encore aux premiers stades de ce projet, donc la documentation peut être incomplète. Si vous souhaitez en savoir plus sur les fonctionnalités que nous fournissons, veuillez jeter un œil à la bibliothèque Shell.
Dans les instances YVE / ZED, vous pouvez trouver Nginx, PHP-FPM et les journaux d'application dans / data / logs /
Nous dépendons des images PHP officielles: https://hub.docker.com/_/php/
Très bonne question en effet!
Nous avons décidé d'opter pour Alpine en raison des temps de construction d'images plus courts - à la fois la construction de la source et l'installation du package. Il s'agissait plus ou moins d'une preuve de concept qui devrait démontrer que même des projets de charge lourde peuvent être hébergés sur Alpine. Les avantages attendus sont des tailles d'image réduites et du temps de construction plus rapide ainsi que des temps d'exécution plus rapides.
Malheureusement, il s'avère que Musl Lib C introduit une limitation qui est insupportable dans le contexte client - où la polyvalence est la clé. Depuis 0.9.6, nous sommes passés aux images basées sur Debian.
Deux choses me viennent à l'esprit:
Plus à venir bientôt. :)
Veuillez jeter un œil aux / problèmes.