{"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\/da\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds","title":{"rendered":"Moderne applikationer p\u00e5 OpenShift, del 2: relaterede builds chained builds","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hej alle sammen! Dette er det andet indl\u00e6g i vores serie, hvor vi viser, hvordan man implementerer moderne webapplikationer p\u00e5 Red Hat OpenShift. <\/p>\n<p><img decoding=\"async\" alt=\"Moderne applikationer p\u00e5 OpenShift, del 2: relaterede builds chained builds\" src=\"\/wp-content\/uploads\/2020\/08\/b1f6ae855a69597c6e86c5198e4a628c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nI det forrige indl\u00e6g n\u00e6vnte vi kort mulighederne for det nye builder-image S2I (source-to-image), der er beregnet til at bygge og implementere moderne webapplikationer p\u00e5 OpenShift-platformen. Dengang var vi interesseret i hurtigt at implementere en applikation, og i dag vil vi se p\u00e5, hvordan man kan bruge S2I-image som et 'rent' builder-image og kombinere det med tilknyttede builds i OpenShift.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Rent builder-image<\/h3>\n<p>\nSom n\u00e6vnt i f\u00f8rste del har de fleste moderne webapplikationer det, man kalder et build-trin, hvor operationer som transpilation af kode, konkatenering af flere filer og minificering typisk udf\u00f8res. De filer, der resulterer fra disse operationer \u2013 nemlig statisk HTML, JavaScript og CSS \u2013 placeres i output-mappen. Placeringen af denne mappe afh\u00e6nger normalt af, hvilke build-v\u00e6rkt\u00f8jer der anvendes, og for React vil det v\u00e6re mappen .\/build (vi vil komme n\u00e6rmere tilbage til dette sp\u00f8rgsm\u00e5l nedenfor).<\/p>\n<h4>Source-to-Image (S2I)<\/h4>\n<p>\nI dette indl\u00e6g ber\u00f8rer vi slet ikke emnet 'hvad er S2I, og hvordan bruger man det' (du kan l\u00e6se mere om det <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.okd.io\/latest\/architecture\/core_concepts\/builds_and_image_streams.html#source-build\">her<\/a><\/noindex>), men det er vigtigt at have en klar forst\u00e5else af de to faser af denne proces for at forst\u00e5, hvad Web App Builder-imaget g\u00f8r.<\/p>\n<h4>Assemblage-trin (assemble phase)<\/h4>\n<p>\nAssemblage-trinnet ligner i sin essens det, der sker, n\u00e5r du k\u00f8rer docker build og f\u00e5r et nyt Docker-image som resultat. Derfor opst\u00e5r dette trin, n\u00e5r en build startes p\u00e5 OpenShift-platformen.<\/p>\n<p>I tilf\u00e6lde af Web App Builder-image er det <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/bucharest-gold\/centos7-s2i-web-app\/blob\/master\/s2i\/assemble#L47\">assemble script<\/a><\/noindex>. Som standard bruger builder-image konstruktionen npm run build, men dette kan overstyres via milj\u00f8variablen NPM_BUILD.<\/p>\n<p>Som vi n\u00e6vnte tidligere, afh\u00e6nger placeringen af den f\u00e6rdige, allerede samlede applikation af, hvilke v\u00e6rkt\u00f8jer der anvendes. For eksempel, i tilf\u00e6lde af React, vil det v\u00e6re mappen .\/build, mens den for Angular-applikationer vil v\u00e6re mappen project_name\/dist. Og som allerede vist i det foreg\u00e5ende indl\u00e6g, kan placeringen af output-kataloget, som som standard er indstillet til build, overskrives via milj\u00f8variablen OUTPUT_DIR. Og da placeringen af output-mappen varierer fra framework til framework, kopierer du simpelthen det genererede output til den standardmappe i billedet, nemlig \/opt\/apt-root\/output. Dette er vigtigt for at forst\u00e5 den videre del af denne artikel, men lad os hurtigt gennemg\u00e5 n\u00e6ste trin \u2013 k\u00f8rsel (run phase).<\/p>\n<h4>K\u00f8rselsfase (run phase)<\/h4>\n<p>\nDenne fase opst\u00e5r, n\u00e5r der kaldes docker run for et nyt billede, der blev oprettet i samlingsfasen. Den finder ogs\u00e5 sted ved udrulning p\u00e5 OpenShift-platformen. Som standard <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/bucharest-gold\/centos7-s2i-web-app\/blob\/master\/s2i\/run\">k\u00f8rselskriptet<\/a><\/noindex> bruger <noindex><a rel=\"nofollow\" href=\"https:\/\/www.npmjs.com\/package\/serve\">serve module<\/a><\/noindex> til at levere statisk indhold, der ligger i det ovenfor n\u00e6vnte standard output-katalog.<\/p>\n<p>Denne metode er god til hurtig udrulning af applikationer, men det anbefales faktisk ikke at levere statisk indhold p\u00e5 denne m\u00e5de. Men da vi reelt leverer kun statisk indhold, er Node.js, der er installeret i vores billede, ikke n\u00f8dvendigt \u2013 en webserver er tilstr\u00e6kkelig.<\/p>\n<p>Med andre ord, n\u00e5r vi bygger har vi \u00e9t behov, n\u00e5r vi udf\u00f8rer \u2013 et andet. I en s\u00e5dan situation vil k\u00e6dede builds (chained builds) v\u00e6re nyttige.<\/p>\n<h3>K\u00e6dede builds (chained builds)<\/h3>\n<p>\nHer er hvad der st\u00e5r om <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> i OpenShift-dokumentationen:<\/p>\n<blockquote><p>\u00abTo builds kan k\u00e6des sammen, hvor den ene genererer en kompileret enhed, og den anden placerer denne enhed i et separat billede, der bruges til at k\u00f8re denne enhed.\u00bb\n<\/p><\/blockquote>\n<p>\nMed andre ord kan vi bruge Web App Builder billedet til at k\u00f8re vores build, og derefter bruge webserverbilledet, den samme NGINX, til at levere vores indhold.<\/p>\n<p>Dermed kan vi anvende Web App Builder billedet som en 'ren' builder og samtidig have et lille runtime-billede.<\/p>\n<p>Lad os nu se p\u00e5 dette med et konkret eksempel.<\/p>\n<p>Til tr\u00e6ning vil vi bruge <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\">en simpel React-applikation<\/a><\/noindex>, oprettet ved hj\u00e6lp af kommandolinjev\u00e6rkt\u00f8jet create-react-app.<\/p>\n<p>At samle det hele vil blive hjulpet af <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\/blob\/master\/.openshiftio\/application.yaml\">OpenShift-skabelonfilen<\/a><\/noindex>.<\/p>\n<p>Lad os se n\u00e6rmere p\u00e5 denne fil og starte med parameterafsnittet.<\/p>\n<pre><code class=\"plaintext\">parameters:\n  - name: SOURCE_REPOSITORY_URL\n    description: Kilden URL for applikationen\n    displayName: Kilde URL\n    required: true\n  - name: SOURCE_REPOSITORY_REF\n    description: Grennavnet for applikationen\n    displayName: Kildegren\n    value: master\n    required: true\n  - name: SOURCE_REPOSITORY_DIR\n    description: Placeringen inden for kilde-repositoriet af applikationen\n    displayName: Kildekatalog\n    value: .\n    required: true\n  - name: OUTPUT_DIR\n    description: Placeringen af de kompilere statiske filer fra din webapps-bygningsv\u00e6rkt\u00f8j\n    displayName: Outputkatalog\n    value: build\n    required: false\n<\/code><\/pre>\n<p>\nAlt er ret klart her, men v\u00e6r opm\u00e6rksom p\u00e5 parameteren OUTPUT_DIR. For React-applikationen i vores eksempel er der ikke noget at bekymre sig om, da React bruger standardv\u00e6rdien som outputmappe, men for Angular eller noget andet skal denne parameter \u00e6ndres passende.<\/p>\n<p>Lad os nu se p\u00e5 ImageStream-sektionen.<\/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>\nTag et kig p\u00e5 det tredje og fjerde billede. Begge er defineret som Docker-billeder, og her kan vi tydeligt se, hvor de kommer fra.<\/p>\n<p>Det tredje billede er web-app-builder, og det kommer fra nodeshift\/ubi8-s2i-web-app med taggen 10.x p\u00e5 <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/nodeshift\/ubi8-s2i-web-app\/\">Docker hub<\/a><\/noindex>.<\/p>\n<p>Det fjerde er NGINX-billedet (version 1.12) med taggen latest p\u00e5 <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/centos\/nginx-112-centos7\/\">Docker hub<\/a><\/noindex>.<\/p>\n<p>Lad os nu se p\u00e5 de to f\u00f8rste billeder. Begge er tomme ved start og oprettes kun i byggefase (build phase). Det f\u00f8rste billede, react-web-app-builder, vil v\u00e6re resultatet af samlingsfasen, der kombinerer billedet web-app-builder-runtime og vores kildekode. Det er derfor, vi har tilf\u00f8jet '-builder' til navnet p\u00e5 dette billede.<\/p>\n<p>Det andet billede, react-web-app-runtime, vil v\u00e6re resultatet af at kombinere nginx-image-runtime og nogle filer fra billedet react-web-app-builder. Dette billede vil ogs\u00e5 blive brugt ved implementering og vil kun indeholde webserver og den statiske HTML, JavaScript, CSS for vores applikation.<\/p>\n<p>Forvirrende? Lad os nu se p\u00e5 byggekonfigurationerne, s\u00e5 det bliver lidt klarere.<\/p>\n<p>Vi har to byggekonfigurationer i vores skabelon. Her er den f\u00f8rste, og den er ret 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 \/\/ 1\n    source:   \/\/ 2 \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 \/\/ 3 \n            value: ${OUTPUT_DIR}\n        from:\n          kind: ImageStreamTag\n          name: web-app-builder-runtime:latest \/\/ 4\n        incremental: true \/\/ 5\n      type: Source\n    triggers: \/\/ 6\n    - github:\n        secret: ${GITHUB_WEBHOOK_SECRET}\n      type: GitHub\n    - type: ConfigChange\n    - imageChange: {}\n      type: ImageChange\n<\/code><\/pre>\n<p>\nSom vi kan se, siger linjen med m\u00e6rket 1, at resultatet af denne bygning vil blive placeret i det p\u00e5g\u00e6ldende billede react-web-app-builder, som vi s\u00e5 tidligere i afsnittet om ImageStreams.<\/p>\n<p>Linjen med m\u00e6rket 2 siger, hvor koden skal hentes fra. I vores tilf\u00e6lde er det et git-repositorium, og beliggenhed, ref og kontekstmappe er defineret ved hj\u00e6lp af parametre, som vi allerede har set ovenfor.<\/p>\n<p>Linjen med m\u00e6rket 3 \u2013 det har vi allerede set i afsnittet om parametre. Den tilf\u00f8jer milj\u00f8variablen OUTPUT_DIR, som i vores eksempel svarer til build.<br \/>\nLinjen med m\u00e6rket 4 siger, at vi skal bruge billedet web-app-builder-runtime, som vi allerede har set i afsnittet om ImageStreams.<\/p>\n<p>Linjen med m\u00e6rket 5 siger, at vi \u00f8nsker at bruge inkrementel bygning, hvis S2I-billedet underst\u00f8tter det, og billedet Web App Builder g\u00f8r det. Ved f\u00f8rste k\u00f8rsel, efter at samlingsfasen er afsluttet, vil billedet gemme mappen node_modules i en arkivfil. Derefter vil billedet blot udpakke denne mappe ved efterf\u00f8lgende k\u00f8rsel for at forkorte byggetiden.<\/p>\n<p>Og endelig er linjen med m\u00e6rket 6 blot et par triggere, s\u00e5 bygningen starter automatisk uden manuel indgriben, n\u00e5r der sker \u00e6ndringer.<\/p>\n<p>Generelt set er dette en temmelig standardbyggekonfiguration.<\/p>\n<p>Lad os nu se p\u00e5 den anden byggekonfiguration. Den ligner meget den f\u00f8rste, men der er \u00e9n vigtig forskel.<\/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 \/\/ 1\n    source: \/\/ 2\n      type: Image\n      images:                              \n        - from:\n            kind: ImageStreamTag\n            name: react-web-app-builder:latest \/\/ 3\n          paths:\n            - sourcePath: \/opt\/app-root\/output\/.  \/\/ 4\n              destinationDir: .  \/\/ 5\n             \n    strategy: \/\/ 6\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 \/\/ 7\n<\/code><\/pre>\n<p>\nS\u00e5, den anden build-konfiguration \u2013 react-web-app-runtime, starter ganske standard.<\/p>\n<p>I linjen med m\u00e6rket 1 er der ikke noget nyt \u2013 den siger blot, at resultatet af build'en placeres i billedet react-web-app-runtime.<\/p>\n<p>Linjen med m\u00e6rket 2 angiver, ligesom i den forrige konfiguration, hvor vi henter kildekoden fra. Men bem\u00e6rk, at vi her siger, at den hentes fra billedet. Og det billede, vi netop har oprettet \u2013 fra react-web-app-builder (angivet i linjen med m\u00e6rket 3). De filer, vi \u00f8nsker at bruge, findes inde i billedet, og deres placering der defineres i linjen med m\u00e6rket 4, i vores tilf\u00e6lde er det \/opt\/app-root\/output\/. Hvis du husker, s\u00e5 er det netop der, filerne, der genereres som resultat af vores applikations build, placeres.<\/p>\n<p>M\u00e5lmappen, der er angivet i linjen med m\u00e6rket 5 \u2013 er blot den aktuelle mappe (det hele, lad os huske, k\u00f8rer inden i en slags magisk ting kaldet OpenShift, og ikke p\u00e5 din lokale computer).<\/p>\n<p>Sektionen strategy \u2013 linjen med m\u00e6rket 6 \u2013 ligner ogs\u00e5 den f\u00f8rste build-konfiguration. Bare denne gang agter vi at bruge nginx-image-runtime, som vi allerede har set i afsnittet ImageStream.<\/p>\n<p>Endelig er linjen med m\u00e6rket 7 \u2013 sektionen af triggers, der aktiverer denne build hver gang billedet react-web-app-builder \u00e6ndres.<\/p>\n<p>Ellers indeholder denne skabelon en helt standard deploymentskonfiguration samt ting, der vedr\u00f8rer tjenester og ruter, men vi vil ikke dykke ned i det. Bem\u00e6rk, at billedet, der skal implementeres \u2013 er billedet react-web-app-runtime.<\/p>\n<h3>Implementering af applikationen<\/h3>\n<p>\nS\u00e5, efter at vi har kigget p\u00e5 skabelonen, lad os se, hvordan vi bruger den til at implementere applikationen.<\/p>\n<p>Vi kan bruge OpenShift-klientv\u00e6rkt\u00f8jet kaldet oc til at implementere vores skabelon:<\/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>\nDen f\u00f8rste kommando p\u00e5 sk\u00e6rmen ovenfor \u2013 er en bevidst ingeni\u00f8rmetode til at finde skabelonen .\/openshiftio\/application.yaml.<\/p>\n<p>Den anden kommando opretter blot en ny applikation baseret p\u00e5 denne skabelon.<\/p>\n<p>Efter at disse kommandoer er k\u00f8rt, vil vi se, at vi har f\u00e5et to builds:<\/p>\n<p><img decoding=\"async\" alt=\"Moderne applikationer p\u00e5 OpenShift, del 2: relaterede builds chained builds\" src=\"\/wp-content\/uploads\/2020\/08\/c6b2b2fcadfcd3e5a8a2adb4eff69bf2.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Og n\u00e5r vi vender tilbage til oversigtssk\u00e6rmen, ser vi den k\u00f8rende pod:<\/p>\n<p><img decoding=\"async\" alt=\"Moderne applikationer p\u00e5 OpenShift, del 2: relaterede builds chained builds\" src=\"\/wp-content\/uploads\/2020\/08\/983fab3029d222555dc13790d4a3e70f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Et klik p\u00e5 linket \u2013 og vi g\u00e5r til vores applikation, som er en standard React App-side:<\/p>\n<p><img decoding=\"async\" alt=\"Moderne applikationer p\u00e5 OpenShift, del 2: relaterede builds chained builds\" src=\"\/wp-content\/uploads\/2020\/08\/d5b658875e0e865bf456955aaac15464.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h3>Bilag 1<\/h3>\n<p>\nFor Angular enthusiasts, we also have <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/angular-web-app\">an application example<\/a><\/noindex>.<\/p>\n<p>The template here is the same, except for the OUTPUT_DIR variable.<\/p>\n<h3>Appendix 2<\/h3>\n<p>\nIn this article, we used NGINX as the web server, but it's quite easy to replace it with Apache; just change the template file. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\/blob\/master\/.openshiftio\/application.yaml#L66\">NGINX image<\/a><\/noindex> og f\u00e5 en fungerende kommando. <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/centos\/httpd-24-centos7\/\">Apache image<\/a><\/noindex>.<\/p>\n<h3>Konklusion<\/h3>\n<p>\nIn the first part of this series, we showed how to quickly deploy modern web applications on the OpenShift platform. Today, we explored what the Web App image does and how it can be combined with a clean web server like NGINX using chained builds to organize a build more suitable for production conditions. In the next, final article of this series, we will show how to run a development server for your application on OpenShift and ensure synchronization between local and remote files.<\/p>\n<h3>Content of this article series<\/h3>\n<p><\/p>\n<ul>\n<li>Part 1: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/511954\/\">how to deploy modern web applications in just a few steps<\/a><\/noindex>;<\/li>\n<li>Part 2: how to apply the new S2I image together with an existing HTTP server image, such as NGINX, using OpenShift's chained builds for organizing production deployment;<\/li>\n<li>Part 3: how to run a development server for your application on the OpenShift platform and synchronize it with the local file system.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Yderligere ressourcer<\/h3>\n<p><\/p>\n<ul>\n<li>Gratis e-bog <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/books\/deploying-openshift\">Deploying to OpenShift<\/a><\/noindex>.<\/li>\n<li>Information on <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/topics\/kubernetes\/\">OpenShift og Kubernetes<\/a><\/noindex>.<\/li>\n<\/ul>\n<p>Kilde: <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.3 - 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\/da\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\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\/da\/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\udd47Modern applications on OpenShift, part 2: chained builds | ProHoster","description":"Hej alle sammen! Dette er det andet indl\u00e6g i vores serie, hvor vi viser, hvordan man implementerer moderne webapplikationer p\u00e5 Red Hat OpenShift.","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","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\/da\/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\/da\/wp-json\/wp\/v2\/posts\/90874","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=90874"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/90874\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media\/90875"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=90874"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=90874"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=90874"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}