Dans l'article précédent, nous avons légèrement évoqué les capacités de la nouvelle image de générateur S2I (source-image), conçue pour créer et déployer des applications Web modernes sur la plate-forme OpenShift. Ensuite, nous nous sommes intéressés au sujet du déploiement rapide des applications, mais aujourd'hui nous allons voir comment utiliser une image S2I comme une image de constructeur "propre" et la combiner avec des assemblys OpenShift associés.
Image de constructeur propre
Comme nous l'avons mentionné dans la première partie, la plupart des applications Web modernes ont une étape dite de construction, qui effectue généralement des opérations telles que la transpilation de code, la concaténation de plusieurs fichiers et la minification. Les fichiers résultants - HTML statique, JavaScript et CSS - sont ajoutés au dossier de sortie. L'emplacement de ce dossier dépend généralement des outils de construction utilisés, et pour React, ce sera le dossier ./build (nous y reviendrons plus en détail ci-dessous).
Source-image (S2I)
Dans cet article, nous ne parlons pas du tout de "qu'est-ce que S2I et comment l'utiliser" (vous pouvez en savoir plus ici ), mais il est important d'être clair sur les deux étapes de ce processus afin de comprendre ce que fait l'image Web App Builder.
Assemblez la phase
L'étape d'assemblage est intrinsèquement très similaire à ce qui se passe lorsque vous exécutez la construction de docker et que vous vous retrouvez avec une nouvelle image Docker. En conséquence, cette étape se produit lors du démarrage d'une compilation sur la plate-forme OpenShift.
Dans le cas d'une image Web App Builder, le script d'assemblage est responsable de l'installation des dépendances de votre application et de l'exécution de la génération . Par défaut, l'image du générateur utilise la construction npm run build, mais elle peut être remplacée via la variable d'environnement NPM_BUILD.
Comme nous l'avons dit précédemment, l'emplacement de l'application terminée et déjà construite dépend des outils que vous utilisez. Par exemple, dans le cas de React, ce sera le dossier. / Build, et pour les applications Angular, le dossier project_name / dist. Et, comme indiqué dans le dernier article, l'emplacement du répertoire de sortie, qui est défini pour construire par défaut, peut être remplacé via la variable d'environnement OUTPUT_DIR. Eh bien, puisque l'emplacement du dossier de sortie diffère d'un framework à l'autre, vous copiez simplement la sortie générée dans le dossier standard de l'image, à savoir / opt / apt-root / output. Ceci est important pour comprendre le reste de cet article, mais pour l'instant, jetons un coup d'œil à l'étape suivante - l'exécution (phase d'exécution).
Phase d'exécution
Cette étape se produit lorsque l'exécution du menu fixe est appelée sur une nouvelle image créée lors de l'étape d'assemblage. Cela se produit également lors du déploiement sur la plate-forme OpenShift. Par défaut, le script d'exécution utilise le module de service pour servir le contenu statique situé dans le répertoire de sortie standard ci-dessus.
Cette méthode permet de déployer rapidement des applications, mais il n'est généralement pas recommandé de diffuser du contenu statique de cette manière. Eh bien, puisque nous ne servons en réalité que du contenu statique, le Node.js installé à l'intérieur de notre image n'est pas nécessaire - un serveur Web suffit.
En d'autres termes, nous avons besoin d'une chose lors de l'assemblage et d'une autre lors de l'exécution. C'est là que les versions chaînées sont utiles.
Constructions chaînées
Voici ce qu'ils écrivent sur les builds chaînés dans la documentation OpenShift:
"Deux assemblys peuvent être liés l'un à l'autre, l'un générant l'entité compilée et l'autre hébergeant l'entité dans une image distincte utilisée pour exécuter cette entité."
En d'autres termes, nous pouvons utiliser l'image Web App Builder pour exécuter notre build, puis utiliser l'image du serveur Web, NGINX, pour diffuser notre contenu.
Ainsi, nous pouvons utiliser l'image Web App Builder comme un générateur "pur" tout en conservant une petite image d'exécution.
Regardons maintenant cela avec un exemple spécifique.
Pour ce didacticiel, nous utiliserons une application React simple construite avec l'outil de ligne de commande create-react-app.
Le fichier modèle OpenShift nous aidera à tout mettre en place .
Examinons de plus près ce fichier et commençons par la section des paramètres.
parameters:
- name: SOURCE_REPOSITORY_URL
description: The source URL for the application
displayName: Source URL
required: true
- name: SOURCE_REPOSITORY_REF
description: The branch name for the application
displayName: Source Branch
value: master
required: true
- name: SOURCE_REPOSITORY_DIR
description: The location within the source repo of the application
displayName: Source Directory
value: .
required: true
- name: OUTPUT_DIR
description: The location of the compiled static files from your web apps builder
displayName: Output Directory
value: build
required: false
Tout est assez clair ici, mais vous devez faire attention au paramètre OUTPUT_DIR. Pour l'application React de notre exemple, il n'y a rien à craindre, car React utilise la valeur par défaut comme dossier de sortie, mais dans le cas de Angular ou autre, ce paramètre devra être modifié si nécessaire.
Jetons maintenant un coup d'œil à la section ImageStreams.
- apiVersion: v1
kind: ImageStream
metadata:
name: react-web-app-builder // 1
spec: {}
- apiVersion: v1
kind: ImageStream
metadata:
name: react-web-app-runtime // 2
spec: {}
- apiVersion: v1
kind: ImageStream
metadata:
name: web-app-builder-runtime // 3
spec:
tags:
- name: latest
from:
kind: DockerImage
name: nodeshift/ubi8-s2i-web-app:10.x
- apiVersion: v1
kind: ImageStream
metadata:
name: nginx-image-runtime // 4
spec:
tags:
- name: latest
from:
kind: DockerImage
name: 'centos/nginx-112-centos7:latest'
Jetez un œil aux troisième et quatrième images. Ils sont tous deux définis comme des images Docker et vous pouvez clairement voir d'où ils viennent.
La troisième image est web-app-builder et elle est tirée de nodeshift / ubi8-s2i-web-app avec la balise 10.x sur Docker hub .
La quatrième est une image NGINX (version 1.12) avec la dernière balise sur le hub Docker .
Jetons maintenant un coup d'œil aux deux premières images. Ils sont tous deux vides au début et ne sont créés qu'à la phase de construction. La première image, react-web-app-builder, sera le résultat d'une étape d'assemblage qui fusionnera l'image web-app-builder-runtime et notre code source. C'est pourquoi nous mettons "-builder" dans le nom de cette image.
La deuxième image - react-web-app-runtime - sera le résultat de la combinaison de nginx-image-runtime et de certains fichiers de l'image react-web-app-builder. Cette image sera également utilisée lors du déploiement et ne contiendra que le serveur Web et le HTML statique, JavaScript, CSS de notre application.
Confus? Jetons maintenant un œil aux configurations de construction et cela deviendra un peu plus clair.
Il existe deux configurations de construction dans notre modèle. Voici le premier, et c'est assez standard:
apiVersion: v1
kind: BuildConfig
metadata:
name: react-web-app-builder
spec:
output:
to:
kind: ImageStreamTag
name: react-web-app-builder:latest // 1
source: // 2
git:
uri: ${SOURCE_REPOSITORY_URL}
ref: ${SOURCE_REPOSITORY_REF}
contextDir: ${SOURCE_REPOSITORY_DIR}
type: Git
strategy:
sourceStrategy:
env:
- name: OUTPUT_DIR // 3
value: ${OUTPUT_DIR}
from:
kind: ImageStreamTag
name: web-app-builder-runtime:latest // 4
incremental: true // 5
type: Source
triggers: // 6
- github:
secret: ${GITHUB_WEBHOOK_SECRET}
type: GitHub
- type: ConfigChange
- imageChange: {}
type: ImageChange
Comme vous pouvez le voir, la ligne étiquetée 1 indique que le résultat de cette compilation sera placé dans la même image react-web-app-builder que nous avons vue plus tôt dans la section ImageStreams.
La ligne étiquetée 2 vous indique où obtenir le code. Dans notre cas, il s'agit d'un référentiel git, et l'emplacement, la référence et le dossier de contexte sont définis par les paramètres que nous avons déjà vus ci-dessus.
La ligne étiquetée 3 est déjà vue dans la section des paramètres. Il ajoute la variable d'environnement OUTPUT_DIR, qui est construite dans notre exemple.
La ligne étiquetée 4 indique d'utiliser l'image web-app-builder-runtime que nous avons déjà vue dans la section ImageStream.
La ligne étiquetée 5 indique que nous voulons utiliser une construction incrémentielle si l'image S2I la prend en charge et l'image Web App Builder le fait. Au premier lancement, après avoir terminé l'étape d'assemblage, l'image enregistrera le dossier node_modules dans un fichier archive. Ensuite, lors des exécutions suivantes, l'image décompressera simplement ce dossier pour raccourcir le temps de construction.
Et enfin, la ligne étiquetée 6 n'est que quelques déclencheurs pour que la construction démarre automatiquement, sans intervention manuelle, lorsque quelque chose change.
Dans l'ensemble, c'est une configuration de construction assez standard.
Jetons maintenant un coup d'œil à la deuxième configuration de construction. C'est très similaire au premier, mais il y a une différence importante.
apiVersion: v1
kind: BuildConfig
metadata:
name: react-web-app-runtime
spec:
output:
to:
kind: ImageStreamTag
name: react-web-app-runtime:latest // 1
source: // 2
type: Image
images:
- from:
kind: ImageStreamTag
name: react-web-app-builder:latest // 3
paths:
- sourcePath: /opt/app-root/output/. // 4
destinationDir: . // 5
strategy: // 6
sourceStrategy:
from:
kind: ImageStreamTag
name: nginx-image-runtime:latest
incremental: true
type: Source
triggers:
- github:
secret: ${GITHUB_WEBHOOK_SECRET}
type: GitHub
- type: ConfigChange
- type: ImageChange
imageChange: {}
- type: ImageChange
imageChange:
from:
kind: ImageStreamTag
name: react-web-app-builder:latest // 7
Donc, la deuxième configuration de construction est react-web-app-runtime, et cela commence assez standard.
La ligne étiquetée 1 n'a rien de nouveau - elle indique simplement que le résultat de la construction est mis dans l'image react-web-app-runtime.
La ligne étiquetée 2, comme dans la configuration précédente, indique où obtenir le code source. Mais remarquez qu'ici nous disons qu'il est tiré de l'image. De plus, à partir de l'image que nous venons de créer - de react-web-app-builder (indiqué dans la ligne étiquetée 3). Les fichiers que nous voulons utiliser sont situés à l'intérieur de l'image et leur emplacement y est spécifié sur la ligne étiquetée 4, dans notre cas, il s'agit de / opt / app-root / output /. Si vous vous en souvenez, c'est ici que sont placés les fichiers générés à partir des résultats de la construction de notre application.
Le dossier de destination, spécifié dans la ligne étiquetée 5, est juste le répertoire courant (rappelez-vous, tout cela tourne à l'intérieur d'une chose magique appelée OpenShift, pas sur votre ordinateur local).
La section de stratégie - ligne étiquetée 6 - est également similaire à la première configuration de construction. Seulement cette fois, nous allons utiliser le nginx-image-runtime, que nous avons déjà vu dans la section ImageStream.
Enfin, la ligne étiquetée 7 est la section des déclencheurs qui déclenche cette compilation chaque fois que l'image react-web-app-builder change.
Sinon, ce modèle contient une configuration de déploiement assez standard, ainsi que des éléments liés aux services et aux routes, mais nous n'entrerons pas dans cela. Notez que l'image qui sera déployée est l'image react-web-app-runtime.
Déployer l'application
Donc, après avoir examiné le modèle, voyons comment l'utiliser pour déployer l'application.
Nous pouvons utiliser un outil client OpenShift appelé oc pour déployer notre modèle:
$ find . | grep openshiftio | grep application | xargs -n 1 oc apply -f
$ oc new-app --template react-web-app -p SOURCE_REPOSITORY_URL=https://github.com/lholmquist/react-web-app
La première commande de la capture d'écran ci-dessus est un moyen délibérément d'ingénierie de trouver le modèle. / Openshiftio / application.yaml.
La deuxième commande crée simplement une nouvelle application basée sur ce modèle.
Après l'exécution de ces commandes, nous verrons que nous avons deux assemblys:
Et en revenant à l'écran Aperçu, nous verrons le pod lancé:
Cliquez sur le lien et nous serons redirigés vers notre application, qui est la page par défaut de l'application React:
Annexe 1
Pour les amateurs angulaires, nous avons également un exemple d'application .
Le modèle est le même ici, sauf pour la variable OUTPUT_DIR.
Annexe 2
Dans cet article, nous avons utilisé comme serveur Web NGINX, mais il est assez facile de le remplacer par Apache, il suffit de changer le fichier image du modèle NGINX sur le chemin de l'Apache .
Conclusion
Dans la première partie de cette série, nous vous avons montré comment déployer rapidement des applications Web modernes sur la plateforme OpenShift. Aujourd'hui, nous avons examiné ce qui fait une image d'application Web et comment elle peut être combinée avec un serveur Web pur comme NGINX en utilisant des versions en chaîne pour créer une version d'application plus prête pour la production. Dans le prochain article final de cette série, nous vous montrerons comment exécuter un serveur de développement pour votre application sur OpenShift et synchroniser les fichiers locaux et distants.
Contenu de cette série d'articles
- Partie 1: comment déployer des applications Web modernes en quelques étapes seulement ;
- Partie 2: comment utiliser une nouvelle image S2I avec une image de serveur HTTP existante, par exemple NGINX, en utilisant les assemblys OpenShift associés pour organiser un déploiement de production;
- 3: OpenShift .