{"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\/de\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds","title":{"rendered":"Moderne Anwendungen auf OpenShift, Teil 2: Verkn\u00fcpfte Builds","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hallo zusammen! Hier ist der zweite Beitrag aus unserer Reihe, in der wir zeigen, wie man moderne Webanwendungen auf Red Hat OpenShift bereitstellt. <\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 2: Verkn\u00fcpfte Builds\" src=\"\/wp-content\/uploads\/2020\/08\/b1f6ae855a69597c6e86c5198e4a628c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nIm vorherigen Beitrag haben wir kurz die M\u00f6glichkeiten des neuen S2I (Source-to-Image) Builder-Images er\u00f6rtert, das zur Erstellung und Bereitstellung moderner Webanwendungen auf der OpenShift-Plattform dient. Dabei haben wir uns mit dem Thema der schnellen Bereitstellung von Anwendungen besch\u00e4ftigt, und heute schauen wir uns an, wie man das S2I-Image als 'reines' Builder-Image verwenden und mit verkn\u00fcpften Builds in OpenShift kombinieren kann.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>Reines Builder-Image<\/h3>\n<p>\nWie bereits im ersten Teil erw\u00e4hnt, verf\u00fcgen die meisten modernen Webanwendungen \u00fcber einen sogenannten Build-Schritt, in dem normalerweise Operationen wie Code-Transpilation, das Zusammenf\u00fchren mehrerer Dateien und Minifizierung stattfinden. Die aus diesen Vorg\u00e4ngen resultierenden Dateien \u2013 also statisches HTML, JavaScript und CSS \u2013 werden im Output-Ordner abgelegt. Der Ort dieses Ordners h\u00e4ngt normalerweise davon ab, welche Build-Tools verwendet werden, und f\u00fcr React ist dies der Ordner .\/build (wir werden auf dieses Thema weiter unten detaillierter eingehen).<\/p>\n<h4>Source-to-Image (S2I)<\/h4>\n<p>\nIn diesem Beitrag besch\u00e4ftigen wir uns nicht mit dem Thema \u201eWas ist S2I und wie verwendet man es?\u201c (dar\u00fcber k\u00f6nnen Sie mehr lesen <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.okd.io\/latest\/architecture\/core_concepts\/builds_and_image_streams.html#source-build\">hier<\/a><\/noindex>), jedoch ist es wichtig, die beiden Phasen dieses Prozesses klar zu verstehen, um zu begreifen, was das Web App Builder-Image macht.<\/p>\n<h4>Phase der Assemblierung<\/h4>\n<p>\nDie Assemblierungsphase \u00e4hnelt im Wesentlichen dem, was passiert, wenn Sie `docker build` ausf\u00fchren und schlie\u00dflich ein neues Docker-Image erhalten. Diese Phase tritt entsprechend auf, wenn der Build auf der OpenShift-Plattform gestartet wird.<\/p>\n<p>Im Fall des Web App Builder-Images ist das <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/bucharest-gold\/centos7-s2i-web-app\/blob\/master\/s2i\/assemble#L47\">Assemblierungsskript<\/a><\/noindex>f\u00fcr die Installation der Abh\u00e4ngigkeiten Ihrer Anwendung und den Start des Builds verantwortlich. Standardm\u00e4\u00dfig verwendet das Builder-Image den Befehl `npm run build`, dieser kann jedoch \u00fcber die Umgebungsvariable NPM_BUILD \u00fcberschrieben werden.<\/p>\n<p>Wie bereits erw\u00e4hnt, h\u00e4ngt der Standort der bereitgestellten Anwendung von den verwendeten Werkzeugen ab. Bei React zum Beispiel befindet sich dieser im Ordner \/build, w\u00e4hrend es bei Angular-Anwendungen der Ordner project_name\/dist ist. Und wie bereits im letzten Beitrag gezeigt, kann der Speicherort des Ausgabeverzeichnisses, das standardm\u00e4\u00dfig auf build gesetzt ist, \u00fcber die Umgebungsvariable OUTPUT_DIR \u00fcberschrieben werden. Da der Speicherort des Ausgabeverzeichnisses je nach Framework unterschiedlich ist, kopieren Sie einfach die generierte Ausgabe in das Standardverzeichnis im Image, n\u00e4mlich nach \/opt\/apt-root\/output. Dies ist wichtig f\u00fcr das Verst\u00e4ndnis des weiteren Teils dieses Artikels. Lassen Sie uns nun schnell zum n\u00e4chsten Schritt \u00fcbergehen \u2013 der Phase des Ausf\u00fchrens (run phase).<\/p>\n<h4>Phase des Ausf\u00fchrens (run phase)<\/h4>\n<p>\nDiese Phase tritt ein, wenn f\u00fcr das neue Image, das in der Assemblierungsphase erstellt wurde, der Befehl docker run aufgerufen wird. Dies geschieht auch bei der Bereitstellung auf der OpenShift-Plattform. Standardm\u00e4\u00dfig <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/bucharest-gold\/centos7-s2i-web-app\/blob\/master\/s2i\/run\">run script<\/a><\/noindex> nutzt <noindex><a rel=\"nofollow\" href=\"https:\/\/www.npmjs.com\/package\/serve\">serve module<\/a><\/noindex> zum Bereitstellen von statischem Inhalt, der im oben angegebenen Standard-Ausgabeverzeichnis liegt.<\/p>\n<p>Diese Methode eignet sich gut f\u00fcr die schnelle Bereitstellung von Anwendungen, allerdings sollte statischer Inhalt nicht auf diese Weise bereitgestellt werden. Da wir tats\u00e4chlich nur statischen Inhalt bereitstellen, ist die in unserem Node.js-Image enthaltene Installation nicht erforderlich \u2013 ein Webserver reicht aus.<\/p>\n<p>Anders gesagt, ben\u00f6tigen wir bei der Erstellung das eine, beim Ausf\u00fchren das andere. In solchen Situationen sind verkettete Builds (chained builds) n\u00fctzlich.<\/p>\n<h3>Verkettete Builds (chained builds)<\/h3>\n<p>\nDas steht in der <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.okd.io\/latest\/dev_guide\/builds\/advanced_build_operations.html#dev-guide-chaining-builds\">Dokumentation zu chained builds<\/a><\/noindex> :<\/p>\n<blockquote><p>\u201eZwei Builds k\u00f6nnen miteinander verkn\u00fcpft werden, wobei einer ein kompiliertes Artefakt erzeugt und der andere dieses Artefakt in einem separaten Image speichert, das verwendet wird, um dieses Artefakt auszuf\u00fchren.\u201c\n<\/p><\/blockquote>\n<p>\nAnders gesagt, wir k\u00f6nnen das Image Web App Builder verwenden, um unseren Build auszuf\u00fchren, und dann das Image des Webservers, also NGINX, verwenden, um unseren Inhalt bereitzustellen.<\/p>\n<p>So k\u00f6nnen wir das Image Web App Builder als \u201ereinen\u201c Builder verwenden und gleichzeitig ein kleines Runtime-Image haben.<\/p>\n<p>Schauen wir uns das nun an einem konkreten Beispiel an.<\/p>\n<p>F\u00fcr die \u00dcbung verwenden wir <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\">eine einfache React-Anwendung<\/a><\/noindex>, erstellt mit dem Befehlszeilenwerkzeug create-react-app.<\/p>\n<p>Um alles zusammenzuf\u00fchren, ben\u00f6tigen wir <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\/blob\/master\/.openshiftio\/application.yaml\">die OpenShift-Vorlagendatei.<\/a><\/noindex>.<\/p>\n<p>Wir werden diese Datei im Detail durchgehen und beginnen mit dem Abschnitt f\u00fcr Parameter.<\/p>\n<pre><code class=\"plaintext\">parameters:\n  - name: SOURCE_REPOSITORY_URL\n    description: Die Quell-URL f\u00fcr die Anwendung\n    displayName: Quell-URL\n    required: true\n  - name: SOURCE_REPOSITORY_REF\n    description: Der Branch-Name f\u00fcr die Anwendung\n    displayName: Quell-Branch\n    value: master\n    required: true\n  - name: SOURCE_REPOSITORY_DIR\n    description: Der Speicherort innerhalb des Quell-Repositorys der Anwendung\n    displayName: Quellverzeichnis\n    value: .\n    required: true\n  - name: OUTPUT_DIR\n    description: Der Speicherort der kompilierten statischen Dateien von Ihrem Web-App-Builder\n    displayName: Ausgabeverzeichnis\n    value: build\n    required: false\n<\/code><\/pre>\n<p>\nDas ist alles recht klar, aber man sollte auf den Parameter OUTPUT_DIR achten. F\u00fcr die React-Anwendung aus unserem Beispiel besteht kein Grund zur Sorge, da React den Standardwert f\u00fcr das Ausgabeverzeichnis verwendet. Bei Angular oder etwas anderem muss dieser Parameter entsprechend angepasst werden.<\/p>\n<p>Nun schauen wir uns den Abschnitt der ImageStreams an.<\/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>\nBetrachten Sie die dritte und vierte Abbildung. Beide sind als Docker-Images definiert, und es ist deutlich zu sehen, woher sie stammen.<\/p>\n<p>Das dritte Image ist der web-app-builder und stammt von nodeshift\/ubi8-s2i-web-app mit dem Tag 10.x auf <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/nodeshift\/ubi8-s2i-web-app\/\">Docker Hub<\/a><\/noindex>.<\/p>\n<p>Das vierte ist das NGINX-Image (Version 1.12) mit dem Tag latest auf <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/centos\/nginx-112-centos7\/\">Docker Hub<\/a><\/noindex>.<\/p>\n<p>Jetzt schauen wir uns die ersten beiden Images an. Beide sind zu Beginn leer und werden nur w\u00e4hrend des Build-Prozesses erstellt. Das erste Image \u2013 react-web-app-builder \u2013 wird das Ergebnis der Assembly-Phase sein, in der das Image web-app-builder-runtime und unser Quellcode kombiniert werden. Deshalb haben wir in den Namen dieses Images \u201e-builder\u201c aufgenommen.<\/p>\n<p>Das zweite Image \u2013 react-web-app-runtime \u2013 entsteht durch die Kombination von nginx-image-runtime und einigen Dateien aus dem Image react-web-app-builder. Dieses Image wird ebenfalls beim Deployment verwendet und enth\u00e4lt ausschlie\u00dflich den Webserver sowie das statische HTML, JavaScript und CSS unserer Anwendung.<\/p>\n<p>Klingt kompliziert? Lassen Sie uns die Build-Konfigurationen ansehen, dann wird es etwas klarer.<\/p>\n<p>In unserer Vorlage gibt es zwei Build-Konfigurationen. Hier ist die erste, die ziemlich standardm\u00e4\u00dfig ist:<\/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>\nWie wir sehen k\u00f6nnen, gibt die Zeile mit dem Label 1 an, dass das Ergebnis dieses Builds in das Image react-web-app-builder eingef\u00fcgt wird, das wir zuvor im Abschnitt \u00fcber ImageStreams gesehen haben.<\/p>\n<p>Die Zeile mit dem Label 2 gibt an, wo der Code herkommt. In unserem Fall handelt es sich um ein Git-Repository, und die Position, der Ref und der Kontext-Ordner sind durch Parameter definiert, die wir bereits zuvor gesehen haben.<\/p>\n<p>Die Zeile mit dem Label 3 haben wir bereits im Abschnitt Parameter gesehen. Sie f\u00fcgt die Umgebungsvariable OUTPUT_DIR hinzu, die in unserem Beispiel den Wert build hat.<br \/>\nDie Zeile mit dem Label 4 weist darauf hin, dass wir das Image web-app-builder-runtime verwenden m\u00f6chten, das wir bereits im Abschnitt ImageStream gesehen haben.<\/p>\n<p>Die Zeile mit dem Label 5 besagt, dass wir einen inkrementellen Build verwenden m\u00f6chten, sofern das S2I-Image dies unterst\u00fctzt, und das Image Web App Builder unterst\u00fctzt dies. Beim ersten Start wird nach Abschluss der Assemblierungsphase der Ordner node_modules in einer Archivdatei gespeichert. Bei sp\u00e4teren Starts wird das Image einfach diesen Ordner entpacken, um die Build-Dauer zu verk\u00fcrzen.<\/p>\n<p>Und schlie\u00dflich enth\u00e4lt die Zeile mit dem Label 6 nur einige Trigger, damit der Build automatisch ausgef\u00fchrt wird, ohne manuelles Eingreifen, wenn sich etwas \u00e4ndert.<\/p>\n<p>Insgesamt handelt es sich um eine recht standardisierte Build-Konfiguration.<\/p>\n<p>Schauen wir uns nun die zweite Build-Konfiguration an. Sie \u00e4hnelt der ersten sehr, weist jedoch eine wichtige Abweichung auf.<\/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>\nDie zweite Build-Konfiguration \u2013 react-web-app-runtime \u2013 beginnt ganz Standardm\u00e4\u00dfig.<\/p>\n<p>In der Zeile mit dem Label 1 gibt es nichts Neues \u2013 sie sagt einfach, dass das Ergebnis der Build in das Bild react-web-app-runtime gelegt wird.<\/p>\n<p>Die Zeile mit dem Label 2 gibt an, woher der Quellcode stammt, \u00e4hnlich wie in der vorherigen Konfiguration. Dabei beachten Sie bitte, dass er aus dem Image stammt. Und zwar aus dem Image, das wir gerade erstellt haben \u2013 aus react-web-app-builder (wie in der Zeile mit dem Label 3 angegeben). Die Dateien, die wir verwenden m\u00f6chten, befinden sich innerhalb des Images, und ihr Speicherort wird in der Zeile mit dem Label 4 festgelegt, in unserem Fall ist das \/opt\/app-root\/output\/. Wenn Sie sich erinnern, werden genau dort die Dateien abgelegt, die aus dem Build-Ergebnis unserer Anwendung generiert wurden.<\/p>\n<p>Der Zielordner, der in der Zeile mit dem Label 5 angegeben ist, ist einfach das aktuelle Verzeichnis (alles l\u00e4uft, erinnern Sie sich, innerhalb einer magischen Sache namens OpenShift und nicht auf Ihrem lokalen Computer).<\/p>\n<p>Der Abschnitt strategy \u2013 die Zeile mit dem Label 6 \u2013 \u00e4hnelt ebenfalls der ersten Build-Konfiguration. Dieses Mal werden wir jedoch das nginx-image-runtime verwenden, das wir im Abschnitt ImageStream bereits gesehen haben.<\/p>\n<p>Schlie\u00dflich ist die Zeile mit dem Label 7 der Abschnitt der Trigger, der diesen Build jedes Mal aktiviert, wenn sich das Image react-web-app-builder \u00e4ndert.<\/p>\n<p>Ansonsten enth\u00e4lt diese Vorlage eine ganz standardisierte Bereitstellungskonfiguration sowie Elemente, die mit Diensten und Routen zu tun haben. Wir werden jedoch nicht n\u00e4her darauf eingehen. Bitte beachten Sie, dass das Bild, das bereitgestellt wird, das Bild react-web-app-runtime ist.<\/p>\n<h3>Anwendungsbereitstellung<\/h3>\n<p>\nNachdem wir nun einen Blick auf die Vorlage geworfen haben, sehen wir uns an, wie wir sie f\u00fcr die Bereitstellung einer Anwendung nutzen k\u00f6nnen.<\/p>\n<p>Wir k\u00f6nnen das OpenShift-Client-Tool namens oc verwenden, um unsere Vorlage bereitzustellen:<\/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>\nDer erste Befehl im obigen Screenshot ist absichtlich technisch, um die Vorlage \/openshiftio\/application.yaml zu finden.<\/p>\n<p>Der zweite Befehl erstellt einfach eine neue Anwendung basierend auf dieser Vorlage.<\/p>\n<p>Nachdem diese Befehle ausgef\u00fchrt wurden, sehen wir, dass wir zwei Builds erhalten haben:<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 2: Verkn\u00fcpfte Builds\" src=\"\/wp-content\/uploads\/2020\/08\/c6b2b2fcadfcd3e5a8a2adb4eff69bf2.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Und wenn wir zum Bildschirm \u00dcbersicht zur\u00fcckkehren, sehen wir das gestartete Pod:<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 2: Verkn\u00fcpfte Builds\" src=\"\/wp-content\/uploads\/2020\/08\/983fab3029d222555dc13790d4a3e70f.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Ein Klick auf den Link und wir gelangen zu unserer Anwendung, die die Standardseite der React-App darstellt:<\/p>\n<p><img decoding=\"async\" alt=\"Moderne Anwendungen auf OpenShift, Teil 2: Verkn\u00fcpfte Builds\" src=\"\/wp-content\/uploads\/2020\/08\/d5b658875e0e865bf456955aaac15464.jpeg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h3>Erg\u00e4nzung 1<\/h3>\n<p>\nF\u00fcr Angular-Begeisterte haben wir ebenfalls <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/angular-web-app\">ein Anwendungsbeispiel<\/a><\/noindex>.<\/p>\n<p>Die Vorlage hier ist identisch, abgesehen von der Variable OUTPUT_DIR.<\/p>\n<h3>Erg\u00e4nzung 2<\/h3>\n<p>\nIn diesem Artikel haben wir NGINX als Webserver verwendet, es ist jedoch ziemlich einfach, ihn durch Apache zu ersetzen, indem Sie einfach die Vorlagendatei \u00e4ndern. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\/blob\/master\/.openshiftio\/application.yaml#L66\">NGINX-Image<\/a><\/noindex> findet man <noindex><a rel=\"nofollow\" href=\"https:\/\/hub.docker.com\/r\/centos\/httpd-24-centos7\/\">Apache-Image<\/a><\/noindex>.<\/p>\n<h3>Fazit<\/h3>\n<p>\nIm ersten Teil dieser Reihe haben wir gezeigt, wie man moderne Web-Anwendungen schnell auf der OpenShift-Plattform bereitstellt. Heute haben wir uns angesehen, was ein Web-App-Image ausmacht und wie es mit einem reinen Webserver wie NGINX mithilfe von verkn\u00fcpften Builds (chained builds) zu einer f\u00fcr Produktionsumgebungen geeigneten App-Bereitstellung kombiniert werden kann. Im n\u00e4chsten und letzten Artikel dieser Reihe zeigen wir, wie Sie auf OpenShift einen Entwicklungsserver f\u00fcr Ihre Anwendung starten und die Synchronisierung von lokalen und entfernten Dateien gew\u00e4hrleisten k\u00f6nnen.<\/p>\n<h3>Inhalt dieser Artikelreihe<\/h3>\n<p><\/p>\n<ul>\n<li>Teil 1: <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/511954\/\">wie man moderne Web-Anwendungen in nur wenigen Schritten bereitstellt<\/a><\/noindex>;<\/li>\n<li>Teil 2: wie man ein neues S2I-Image zusammen mit einem bereits vorhandenen HTTP-Server-Image, wie z.B. NGINX, unter Verwendung von verkn\u00fcpften OpenShift-Bauten f\u00fcr eine Produktionsbereitstellung einsetzt;<\/li>\n<li>Teil 3: So starten Sie auf der OpenShift-Plattform einen Entwicklungsserver f\u00fcr Ihre Anwendung und synchronisieren ihn mit dem lokalen Dateisystem.<\/li>\n<\/ul>\n<p><\/p>\n<h3>Zus\u00e4tzliche Ressourcen<\/h3>\n<p><\/p>\n<ul>\n<li>Kostenloses E-Book <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/books\/deploying-openshift\">Bereitstellung auf OpenShift<\/a><\/noindex>.<\/li>\n<li>Informationen \u00fcber <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/topics\/kubernetes\/\">OpenShift und Kubernetes<\/a><\/noindex>.<\/li>\n<\/ul>\n<p>Quelle: <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 4.9.10 - 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. \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\" \/>\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\/de\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"de_DE\" \/>\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. \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\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/de\/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\udd47Moderne Anwendungen auf OpenShift, Teil 2: Verkn\u00fcpfte Builds (Chained Builds) | ProHoster","description":"Hallo zusammen! Hier ist der zweite Post aus unserer Serie, in der wir zeigen, wie man moderne Webanwendungen auf Red Hat OpenShift bereitstellt. Im vorherigen Beitrag haben wir kurz die M\u00f6glichkeiten des neuen S2I (source-to-image) Builder-Images angesto\u00dfen, das f\u00fcr den Bau und die Bereitstellung moderner Webanwendungen auf der OpenShift-Plattform konzipiert ist. Damals ging es um die schnelle Bereitstellung einer Anwendung, und heute werden wir betrachten, wie","canonical_url":"https:\/\/prohoster.info\/de\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-2-svyazannye-sborki-chained-builds","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"de_DE","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. \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","og:url":"https:\/\/prohoster.info\/de\/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"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/90874","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/comments?post=90874"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/posts\/90874\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media\/90875"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/media?parent=90874"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/categories?post=90874"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/de\/wp-json\/wp\/v2\/tags?post=90874"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}