{"id":90874,"date":"2020-08-07T01:42:20","date_gmt":"2020-08-06T23:42:20","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds"},"modified":"2020-08-07T01:42:20","modified_gmt":"2020-08-06T23:42:20","slug":"sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds","status":"publish","type":"post","link":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds","title":{"rendered":"Applications modernes sur OpenShift, partie 2 : constructions cha\u00een\u00e9es","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Bonjour \u00e0 tous ! Voici le deuxi\u00e8me post de notre s\u00e9rie o\u00f9 nous montrons comment d\u00e9ployer des applications web modernes sur Red Hat OpenShift. <\/p>\n<p><img decoding=\"async\" alt=\"Applications modernes sur OpenShift, partie 2 : constructions cha\u00een\u00e9es\" src=\"\/wp-content\/uploads\/2020\/08\/b1f6ae855a69597c6e86c5198e4a628c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDans le post pr\u00e9c\u00e9dent, nous avons bri\u00e8vement abord\u00e9 les capacit\u00e9s du nouveau builder-image S2I (source-to-image), con\u00e7u pour construire et d\u00e9ployer des applications web modernes sur la plateforme OpenShift. \u00c0 l'\u00e9poque, nous nous int\u00e9ressions \u00e0 la rapidit\u00e9 du d\u00e9ploiement d'une application, et aujourd'hui nous verrons comment utiliser l'image S2I en tant que builder-image \u00ab propre \u00bb et la combiner avec des builds associ\u00e9s OpenShift.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Builder-image propre<\/h3>\n<p>\nComme mentionn\u00e9 dans la premi\u00e8re partie, la plupart des applications web modernes ont ce qu'on appelle une \u00e9tape de construction, o\u00f9 des op\u00e9rations telles que la transpilation du code, la concat\u00e9nation de plusieurs fichiers et la minification sont g\u00e9n\u00e9ralement effectu\u00e9es. Les fichiers r\u00e9sultants de ces op\u00e9rations \u2013 \u00e0 savoir HTML statique, JavaScript et CSS \u2013 sont plac\u00e9s dans le dossier output. L'emplacement de ce dossier d\u00e9pend g\u00e9n\u00e9ralement des outils de construction utilis\u00e9s, et pour React, ce sera le dossier .\/build (nous y reviendrons plus en d\u00e9tail ci-dessous).<\/p>\n<h4>Source-to-Image (S2I)<\/h4>\n<p>\nDans ce post, nous n'aborderons pas le sujet de \u00ab ce qu'est S2I et comment l'utiliser \u00bb (vous pouvez lire plus \u00e0 ce sujet <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.okd.io\/latest\/architecture\/core_concepts\/builds_and_image_streams.html#source-build\">ici<\/a><\/noindex>), mais il est important d'avoir une compr\u00e9hension claire des deux \u00e9tapes de ce processus pour savoir ce que fait l'image Web App Builder.<\/p>\n<h4>Phase d'assemblage<\/h4>\n<p>\nLa phase d'assemblage ressemble beaucoup \u00e0 ce qui se passe lorsque vous lancez un docker build et que vous obtenez une nouvelle image Docker en r\u00e9sultat. Cette \u00e9tape se produit donc lors du d\u00e9marrage d'un build sur la plateforme OpenShift.<\/p>\n<p>Dans le cas de l'image Web App Builder, l'installation des d\u00e9pendances de votre application et le d\u00e9marrage du build sont g\u00e9r\u00e9s par <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/bucharest-gold\/centos7-s2i-web-app\/blob\/master\/s2i\/assemble#L47\">le script d'assemblage<\/a><\/noindex>. Par d\u00e9faut, l'image builder utilise la commande npm run build, mais elle peut \u00eatre red\u00e9finie via la variable d'environnement NPM_BUILD.<\/p>\n<p>Comme nous l'avons mentionn\u00e9 pr\u00e9c\u00e9demment, l'emplacement de l'application finale d\u00e9j\u00e0 assembl\u00e9e d\u00e9pend des outils utilis\u00e9s. Par exemple, dans le cas de React, ce sera le dossier .\/build, et pour les applications Angular, ce sera le dossier project_name\/dist. Et, comme d\u00e9j\u00e0 montr\u00e9 dans le post pr\u00e9c\u00e9dent, l'emplacement du r\u00e9pertoire de sortie, qui est par d\u00e9faut d\u00e9fini comme build, peut \u00eatre red\u00e9fini via la variable d'environnement OUTPUT_DIR. Puisque l'emplacement du dossier de sortie varie d'un framework \u00e0 l'autre, vous copiez simplement la sortie g\u00e9n\u00e9r\u00e9e dans le dossier standard de l'image, \u00e0 savoir dans \/opt\/apt-root\/output. Cela est important pour comprendre la suite de cet article, mais pour l'instant, examinons rapidement la prochaine \u00e9tape : la phase d'ex\u00e9cution (run phase).<\/p>\n<h4>Phase d'ex\u00e9cution (run phase)<\/h4>\n<p>\nCette \u00e9tape se produit lorsqu'un nouvel image, cr\u00e9\u00e9e lors de l'\u00e9tape d'assemblage, est appel\u00e9e avec docker run. Elle se produit \u00e9galement lors du d\u00e9ploiement sur la plateforme OpenShift. Par d\u00e9faut <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/bucharest-gold\/centos7-s2i-web-app\/blob\/master\/s2i\/run\">script d'ex\u00e9cution<\/a><\/noindex> utilise <noindex><a rel=\"nofollow\" href=\"https:\/\/www.npmjs.com\/package\/serve\">module de service<\/a><\/noindex> pour servir le contenu statique situ\u00e9 dans le r\u00e9pertoire de sortie standard mentionn\u00e9 ci-dessus.<\/p>\n<p>Cette m\u00e9thode est bonne pour un d\u00e9ploiement rapide d'applications, mais en r\u00e9alit\u00e9, il n'est pas recommand\u00e9 de servir le contenu statique de cette mani\u00e8re. \u00c9tant donn\u00e9 que nous ne servons en r\u00e9alit\u00e9 que du contenu statique, Node.js install\u00e9 dans notre image n'est pas n\u00e9cessaire \u2013 un serveur web suffit.<\/p>\n<p>En d'autres termes, \u00e0 la compilation, nous avons besoin d'une chose, en ex\u00e9cution, d'une autre. Dans cette situation, les constructions li\u00e9es (chained builds) seront utiles.<\/p>\n<h3>Constructions li\u00e9es (chained builds)<\/h3>\n<p>\nVoici ce que dit la documentation OpenShift \u00e0 propos de <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.okd.io\/latest\/dev_guide\/builds\/advanced_build_operations.html#dev-guide-chaining-builds\">chained builds<\/a><\/noindex> :<\/p>\n<blockquote><p>\u00ab Deux constructions peuvent \u00eatre li\u00e9es l'une \u00e0 l'autre, l'une g\u00e9n\u00e9rant une entit\u00e9 compil\u00e9e et l'autre pla\u00e7ant cette entit\u00e9 dans une image distincte, qui est utilis\u00e9e pour ex\u00e9cuter cette entit\u00e9.\u00bb\n<\/p><\/blockquote>\n<p>\nEn d'autres termes, nous pouvons utiliser l'image Web App Builder pour ex\u00e9cuter notre construction, puis utiliser l'image du serveur web, comme NGINX, pour servir notre contenu.<\/p>\n<p>Ainsi, nous pouvons appliquer l'image Web App Builder comme un \u00ab constructeur \u00bb \u00ab propre \u00bb tout en ayant une petite image d'ex\u00e9cution.<\/p>\n<p>Passons maintenant \u00e0 un exemple concret.<\/p>\n<p>Pour cet exercice, nous utiliserons <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\">une application React simple<\/a><\/noindex>, cr\u00e9\u00e9e \u00e0 l'aide de l'outil de ligne de commande create-react-app.<\/p>\n<p>Pour tout rassembler, nous allons utiliser <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\/blob\/master\/.openshiftio\/application.yaml\">un fichier mod\u00e8le OpenShift<\/a><\/noindex>.<\/p>\n<p>Examinons ce fichier plus en d\u00e9tail, et commen\u00e7ons par la section des param\u00e8tres.<\/p>\n<pre><code class=\"plaintext\">param\u00e8tres :\n  - nom : SOURCE_REPOSITORY_URL\n    description : L'URL source de l'application\n    displayName : URL source\n    required : true\n  - nom : SOURCE_REPOSITORY_REF\n    description : Le nom de la branche pour l'application\n    displayName : Branche source\n    value : master\n    required : true\n  - nom : SOURCE_REPOSITORY_DIR\n    description : L'emplacement au sein du d\u00e9p\u00f4t source de l'application\n    displayName : R\u00e9pertoire source\n    value : .\n    required : true\n  - nom : OUTPUT_DIR\n    description : L'emplacement des fichiers statiques compil\u00e9s de votre g\u00e9n\u00e9rateur d'applications web\n    displayName : R\u00e9pertoire de sortie\n    value : build\n    required : false\n<\/code><\/pre>\n<p>\nTout cela est assez clair, mais il faut pr\u00eater attention au param\u00e8tre OUTPUT_DIR. Pour l'application React de notre exemple, il n'y a pas de souci, car React utilise par d\u00e9faut la valeur de sortie par d\u00e9faut, tandis que pour Angular ou d'autres, ce param\u00e8tre devra \u00eatre ajust\u00e9 de mani\u00e8re ad\u00e9quate.<\/p>\n<p>Jetons maintenant un \u0153il \u00e0 la section des ImageStreams.<\/p>\n<pre><code class=\"plaintext\">- apiVersion : v1\n  kind : ImageStream\n  metadata :\n    name : react-web-app-builder  \/\/ 1 \n  spec : {}\n- apiVersion : v1\n  kind : ImageStream\n  metadata :\n    name : react-web-app-runtime  \/\/ 2 \n  spec : {}\n- apiVersion : v1\n  kind : ImageStream\n  metadata :\n    name : web-app-builder-runtime \/\/ 3\n  spec :\n    tags :\n    - name : latest\n      from :\n        kind : DockerImage\n        name : nodeshift\/ubi8-s2i-web-app:10.x\n- apiVersion : v1\n  kind : ImageStream\n  metadata :\n    name : nginx-image-runtime \/\/ 4\n  spec :\n    tags :\n    - name : latest\n      from :\n        kind : DockerImage\n        name : 'centos\/nginx-112-centos7:latest'\n<\/code><\/pre>\n<p>\nRegardez les troisi\u00e8me et quatri\u00e8me images. Elles sont toutes deux d\u00e9finies comme des images Docker, et il est clair de voir d'o\u00f9 elles proviennent.<\/p>\n<p>La troisi\u00e8me image est web-app-builder, et elle provient de nodeshift\/ubi8-s2i-web-app avec le tag 10.x sur <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/nodeshift\/ubi8-s2i-web-app\/\">Docker hub<\/a><\/noindex>.<\/p>\n<p>La quatri\u00e8me est l'image NGINX (version 1.12) avec le tag latest sur <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/centos\/nginx-112-centos7\/\">Docker hub<\/a><\/noindex>.<\/p>\n<p>Jetons maintenant un \u0153il aux deux premi\u00e8res images. Elles sont toutes deux vides au d\u00e9part et ne sont cr\u00e9\u00e9es qu'\u00e0 l'\u00e9tape de construction (build phase). La premi\u00e8re image, react-web-app-builder, sera le r\u00e9sultat de l'\u00e9tape d'assemblage, qui combinera l'image web-app-builder-runtime et notre code source. C'est pourquoi nous avons inscrit \u00ab -builder \u00bb dans le nom de cette image.<\/p>\n<p>La deuxi\u00e8me image, react-web-app-runtime, sera le r\u00e9sultat de la combinaison de nginx-image-runtime et de certains fichiers de l'image react-web-app-builder. Cette image sera \u00e9galement utilis\u00e9e lors du d\u00e9ploiement et contiendra uniquement le serveur web, ainsi que le HTML, le JavaScript et le CSS statiques de notre application.<\/p>\n<p>C'est confus ? Regardons maintenant les configurations de construction et cela deviendra un peu plus clair.<\/p>\n<p>Dans notre mod\u00e8le, il y a deux configurations de construction. Voici la premi\u00e8re d'entre elles, qui est assez standard :<\/p>\n<pre><code class=\"plaintext\">  apiVersion: v1\n  kind: BuildConfig\n  metadata:\n    name: react-web-app-builder\n  spec:\n    output:\n      to:\n        kind: ImageStreamTag\n        name: react-web-app-builder:latest \n    source:   \n      git:\n        uri: ${SOURCE_REPOSITORY_URL}\n        ref: ${SOURCE_REPOSITORY_REF}\n      contextDir: ${SOURCE_REPOSITORY_DIR}\n      type: Git\n    strategy:\n      sourceStrategy:\n        env:\n          - name: OUTPUT_DIR \n            value: ${OUTPUT_DIR}\n        from:\n          kind: ImageStreamTag\n          name: web-app-builder-runtime:latest \n        incremental: true \n      type: Source\n    triggers: \n    - github:\n        secret: ${GITHUB_WEBHOOK_SECRET}\n      type: GitHub\n    - type: ConfigChange\n    - imageChange: {}\n      type: ImageChange\n<\/code><\/pre>\n<p>\nComme nous le voyons, la ligne avec l'\u00e9tiquette 1 indique que le r\u00e9sultat de cette construction sera plac\u00e9 dans l'image react-web-app-builder que nous avons vue pr\u00e9c\u00e9demment dans la section ImageStream.<\/p>\n<p>La ligne avec l'\u00e9tiquette 2 indique d'o\u00f9 prendre le code. Dans notre cas, il s'agit d'un d\u00e9p\u00f4t git, et l'URI, la r\u00e9f\u00e9rence et le r\u00e9pertoire contextuel sont d\u00e9finis par les param\u00e8tres que nous avons d\u00e9j\u00e0 vus ci-dessus.<\/p>\n<p>La ligne avec l'\u00e9tiquette 3 \u2013 nous l'avons d\u00e9j\u00e0 vue dans la section des param\u00e8tres. Elle ajoute la variable d'environnement OUTPUT_DIR, qui dans notre exemple est \u00e9gale \u00e0 build.<br \/>\nLa ligne avec l'\u00e9tiquette 4 indique d'utiliser l'image web-app-builder-runtime, que nous avons d\u00e9j\u00e0 vue dans la section ImageStream.<\/p>\n<p>La ligne avec l'\u00e9tiquette 5 indique que nous souhaitons utiliser une construction incr\u00e9mentielle, si l'image S2I le prend en charge, et l'image Web App Builder le prend en charge. Lors du premier lancement, apr\u00e8s la fin de l'assemblage, l'image conservera le dossier node_modules dans un fichier archive. Ensuite, lors des ex\u00e9cutions suivantes, l'image se contentera de d\u00e9compresser ce dossier pour r\u00e9duire la dur\u00e9e de construction.<\/p>\n<p>Enfin, la ligne avec l'\u00e9tiquette 6 \u2013 ce ne sont que quelques d\u00e9clencheurs pour que la construction se lance automatiquement, sans intervention manuelle, lorsque quelque chose change.<\/p>\n<p>En g\u00e9n\u00e9ral, c'est une configuration de construction assez standard.<\/p>\n<p>Jetons un \u0153il \u00e0 la deuxi\u00e8me configuration de construction. Elle est tr\u00e8s similaire \u00e0 la premi\u00e8re, mais il y a une diff\u00e9rence importante.<\/p>\n<pre><code class=\"plaintext\">apiVersion: v1\n  kind: BuildConfig\n  metadata:\n    name: react-web-app-runtime\n  spec:\n    output:\n      to:\n        kind: ImageStreamTag\n        name: react-web-app-runtime:latest \n    source: \n      type: Image\n      images:                              \n        - from:\n            kind: ImageStreamTag\n            name: react-web-app-builder:latest \n          paths:\n            - sourcePath: \/opt\/app-root\/output\/. \n              destinationDir: . \n             \n    strategy: \n      sourceStrategy:\n        from:\n          kind: ImageStreamTag\n          name: nginx-image-runtime:latest\n        incremental: true\n      type: Source\n    triggers:\n    - github:\n        secret: ${GITHUB_WEBHOOK_SECRET}\n      type: GitHub\n    - type: ConfigChange\n    - type: ImageChange\n      imageChange: {}\n    - type: ImageChange\n      imageChange:\n        from:\n          kind: ImageStreamTag\n          name: react-web-app-builder:latest\n<\/code><\/pre>\n<p>\nDonc, la deuxi\u00e8me configuration de construction \u2013 react-web-app-runtime, commence de mani\u00e8re assez standard.<\/p>\n<p>Il n'y a rien de nouveau dans la ligne marqu\u00e9e 1 \u2014 elle indique simplement que le r\u00e9sultat de la construction est plac\u00e9 dans l'image react-web-app-runtime.<\/p>\n<p>La ligne marqu\u00e9e 2, comme dans la configuration pr\u00e9c\u00e9dente, indique d'o\u00f9 prendre le code source. Mais notez que nous disons ici qu'il provient de l'image. En fait, de l'image que nous venons de cr\u00e9er \u2013 react-web-app-builder (indiqu\u00e9e dans la ligne marqu\u00e9e 3). Les fichiers que nous voulons utiliser se trouvent \u00e0 l'int\u00e9rieur de l'image et leur emplacement y est d\u00e9fini dans la ligne marqu\u00e9e 4, qui est \/opt\/app-root\/output\/. Si vous vous souvenez, c'est pr\u00e9cis\u00e9ment l\u00e0 que sont stock\u00e9s les fichiers g\u00e9n\u00e9r\u00e9s par les r\u00e9sultats de la construction de notre application.<\/p>\n<p>Le dossier de destination, d\u00e9fini dans la ligne marqu\u00e9e 5, est simplement le r\u00e9pertoire courant (rappelez-vous que tout cela fonctionne \u00e0 l'int\u00e9rieur d'une sorte de chose magique appel\u00e9e OpenShift, et non sur votre ordinateur local).<\/p>\n<p>La section strategy \u2013 ligne marqu\u00e9e 6 \u2013 ressemble \u00e9galement \u00e0 la premi\u00e8re configuration de construction. Cette fois, nous allons utiliser nginx-image-runtime, que nous avons d\u00e9j\u00e0 vu dans la section ImageStream.<\/p>\n<p>Enfin, la ligne marqu\u00e9e 7 \u2013 est la section des d\u00e9clencheurs qui active cette construction chaque fois que l'image react-web-app-builder change.<\/p>\n<p>Pour le reste, ce mod\u00e8le contient une configuration de d\u00e9ploiement tout \u00e0 fait standard, ainsi que des \u00e9l\u00e9ments li\u00e9s aux services et aux routes, mais nous ne nous attarderons pas l\u00e0-dessus. Notez que l'image qui sera d\u00e9ploy\u00e9e est l'image react-web-app-runtime.<\/p>\n<h3>D\u00e9ploiement de l'application<\/h3>\n<p>\nDonc, apr\u00e8s avoir examin\u00e9 le mod\u00e8le, voyons comment l'utiliser pour d\u00e9ployer l'application.<\/p>\n<p>Nous pouvons utiliser l'outil client OpenShift appel\u00e9 oc pour d\u00e9ployer notre mod\u00e8le :<\/p>\n<pre><code class=\"plaintext\">$ find . | grep openshiftio | grep application | xargs -n 1 oc apply -f\n\n$ oc new-app --template react-web-app -p SOURCE_REPOSITORY_URL=https:\/\/github.com\/lholmquist\/react-web-app\n<\/code><\/pre>\n<p>\nLa premi\u00e8re commande \u00e0 l'\u00e9cran ci-dessus est un moyen d\u00e9lib\u00e9r\u00e9ment technique de trouver le mod\u00e8le \/openshiftio\/application.yaml.<\/p>\n<p>La deuxi\u00e8me commande cr\u00e9e simplement une nouvelle application bas\u00e9e sur ce mod\u00e8le.<\/p>\n<p>Apr\u00e8s que ces commandes aient fonctionn\u00e9, nous verrons que nous avons deux constructions :<\/p>\n<p><img decoding=\"async\" alt=\"Applications modernes sur OpenShift, partie 2 : constructions cha\u00een\u00e9es\" src=\"\/wp-content\/uploads\/2020\/08\/c6b2b2fcadfcd3e5a8a2adb4eff69bf2.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Et en retournant \u00e0 l'\u00e9cran Overview, nous verrons le pod d\u00e9marr\u00e9 :<\/p>\n<p><img decoding=\"async\" alt=\"Applications modernes sur OpenShift, partie 2 : constructions cha\u00een\u00e9es\" src=\"\/wp-content\/uploads\/2020\/08\/983fab3029d222555dc13790d4a3e70f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Un clic sur le lien \u2014 et nous serons redirig\u00e9s vers notre application, qui est une page d'application React App par d\u00e9faut :<\/p>\n<p><img decoding=\"async\" alt=\"Applications modernes sur OpenShift, partie 2 : constructions cha\u00een\u00e9es\" src=\"\/wp-content\/uploads\/2020\/08\/d5b658875e0e865bf456955aaac15464.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h3>Annexe 1<\/h3>\n<p>\nPour les amateurs d'Angular, nous avons aussi <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/angular-web-app\">exemple d'application<\/a><\/noindex>.<\/p>\n<p>Le mod\u00e8le ici est le m\u00eame, \u00e0 l'exception de la variable OUTPUT_DIR.<\/p>\n<h3>Annexe 2<\/h3>\n<p>\nDans cet article, nous avons utilis\u00e9 NGINX comme serveur web, mais il est assez facile de le remplacer par Apache, il suffit de modifier le fichier mod\u00e8le <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\/blob\/master\/.openshiftio\/application.yaml#L66\">image NGINX<\/a><\/noindex> sur <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/centos\/httpd-24-centos7\/\">image Apache<\/a><\/noindex>.<\/p>\n<h3>Conclusion<\/h3>\n<p>\nDans la premi\u00e8re partie de cette s\u00e9rie, nous avons montr\u00e9 comment d\u00e9ployer rapidement des applications web modernes sur la plateforme OpenShift. Aujourd'hui, nous avons examin\u00e9 ce que fait l'image Web App et comment elle peut \u00eatre associ\u00e9e \u00e0 un serveur web pur comme NGINX gr\u00e2ce \u00e0 des builds li\u00e9s (chained build) pour organiser une construction d'application plus adapt\u00e9e aux conditions de production. Dans le prochain article final de cette s\u00e9rie, nous montrerons comment ex\u00e9cuter un serveur de d\u00e9veloppement sur OpenShift pour votre application et synchroniser les fichiers locaux et distants.<\/p>\n<h3>Contenu de cette s\u00e9rie d'articles<\/h3>\n<p><\/p>\n<ul>\n<li>Partie 1 : <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/511954\/\">comment d\u00e9ployer des applications web modernes en quelques \u00e9tapes seulement<\/a><\/noindex>;<\/li>\n<li>Partie 2 : comment appliquer la nouvelle image S2I avec l'image de serveur HTTP d\u00e9j\u00e0 existante, comme NGINX, en utilisant des builds li\u00e9s d'OpenShift, pour organiser un d\u00e9ploiement en production ;<\/li>\n<li>Partie 3 : comment ex\u00e9cuter un serveur de d\u00e9veloppement sur la plateforme OpenShift pour votre application et le synchroniser avec le syst\u00e8me de fichiers local.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Ressources suppl\u00e9mentaires<\/h3>\n<p><\/p>\n<ul>\n<li>E-book gratuit <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/books\/deploying-openshift\">D\u00e9ploiement sur OpenShift<\/a><\/noindex>.<\/li>\n<li>Informations sur <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/topics\/kubernetes\/\">OpenShift et Kubernetes<\/a><\/noindex>.<\/li>\n<\/ul>\n<p>Source : <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/513948\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u0421 \u0432\u0430\u043c\u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u0441\u0435\u0440\u0438\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430 Red Hat OpenShift \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043f\u043e\u0441\u0442\u0435 \u043c\u044b \u0441\u043b\u0435\u0433\u043a\u0430 \u0437\u0430\u0442\u0440\u043e\u043d\u0443\u043b\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043d\u043e\u0432\u043e\u0433\u043e builder-\u043e\u0431\u0440\u0430\u0437\u0430 S2I (source-to-image), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u0438 \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u044f \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439 \u043d\u0430 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 OpenShift. \u0422\u043e\u0433\u0434\u0430 \u043d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043b\u0430 \u0442\u0435\u043c\u0430 \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":90875,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-90874","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u0421 \u0432\u0430\u043c\u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u0441\u0435\u0440\u0438\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430 Red Hat OpenShift \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"fr_FR\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0421\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 OpenShift, \u0447\u0430\u0441\u0442\u044c 2: \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 chained builds | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u0421 \u0432\u0430\u043c\u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u0441\u0435\u0440\u0438\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430 Red Hat OpenShift \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-08-06T23:42:20+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-08-06T23:42:20+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Applications modernes sur OpenShift, partie 2 : builds li\u00e9s chained builds | ProHoster","description":"Bonjour \u00e0 tous ! Voici le deuxi\u00e8me post de notre s\u00e9rie o\u00f9 nous montrons comment d\u00e9ployer des applications web modernes sur Red Hat OpenShift.","canonical_url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"fr_FR","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0421\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 OpenShift, \u0447\u0430\u0441\u0442\u044c 2: \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438 chained builds | ProHoster","og:description":"\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u0421 \u0432\u0430\u043c\u0438 \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u0441\u0435\u0440\u0438\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c, \u043a\u0430\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430 Red Hat OpenShift \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.","og:url":"https:\/\/prohoster.info\/fr\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-08-06T23:42:20+00:00","article:modified_time":"2020-08-06T23:42:20+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"90874","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 12:40:03","updated":"2022-10-04 00:42:31","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/90874","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/comments?post=90874"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/posts\/90874\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media\/90875"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/media?parent=90874"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/categories?post=90874"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/fr\/wp-json\/wp\/v2\/tags?post=90874"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}