{"id":92048,"date":"2020-08-22T07:42:57","date_gmt":"2020-08-22T05:42:57","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines"},"modified":"2020-08-22T07:42:57","modified_gmt":"2020-08-22T05:42:57","slug":"sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines","status":"publish","type":"post","link":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines","title":{"rendered":"Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e pipeline OpenShift Pipelines","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Ciao a tutti in questo blog! Questo \u00e8 il terzo post di una serie in cui mostriamo come distribuire applicazioni web moderne su Red Hat OpenShift.<\/p>\n<p><img decoding=\"async\" alt=\"Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e pipeline OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/9c3337b13a3f045d36343308ce6154cc.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nNei due post precedenti, abbiamo illustrato come distribuire applicazioni web moderne in pochi passaggi e come usare la nuova immagine S2I insieme a un'immagine di server HTTP predefinita, come NGINX, utilizzando build collegate (chained builds) per organizzare distribuzioni in produzione.<\/p>\n<p>Oggi mostreremo come avviare un server di sviluppo per la nostra applicazione sulla piattaforma OpenShift e sincronizzarlo con il file system locale, e discuteremo anche di cosa siano le OpenShift Pipelines e come possano essere utilizzate come alternativa alle build collegate.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h3>OpenShift come ambiente di sviluppo<\/h3>\n<p><\/p>\n<h4>Flusso di lavoro di sviluppo<\/h4>\n<p>\nCome gi\u00e0 accennato nel <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/511954\/\">primo post<\/a><\/noindex>, il processo di sviluppo tipico per le applicazioni web moderne \u00e8 essenzialmente un \"server di sviluppo\" che monitora le modifiche nei file locali. Quando queste si verificano, viene avviata la build dell'applicazione e poi questa viene aggiornata nel browser.<\/p>\n<p>Nella maggior parte dei moderni framework, un tale \"server di sviluppo\" \u00e8 integrato negli strumenti da riga di comando corrispondenti.<\/p>\n<h4>Esempio locale<\/h4>\n<p>\nPer iniziare, vediamo come funziona nel caso di un'esecuzione locale delle applicazioni. Prendiamo come esempio l'applicazione <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/lholmquist\/react-web-app\">React<\/a><\/noindex> tratta nei precedenti articoli, anche se praticamente gli stessi concetti di flusso di lavoro si applicano in tutti gli altri moderni framework.<br \/>\nDunque, per avviare il \"server di sviluppo\" nel nostro esempio con React, inseriamo il seguente comando:<\/p>\n<pre><code class=\"plaintext\">$ npm run start\n<\/code><\/pre>\n<p>\nAllora nella finestra del terminale vedremo qualcosa del genere:<\/p>\n<p><img decoding=\"async\" alt=\"Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e pipeline OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/06f84ffb4c9a6a5868b8b47b8ad1d9ec.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>E la nostra applicazione si aprir\u00e0 nel browser predefinito:<\/p>\n<p><img decoding=\"async\" alt=\"Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e pipeline OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/72341bb0796352e7343bf31ceb8233cd.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Ora, se apportiamo modifiche al file, l'applicazione dovrebbe aggiornarsi nel browser.<\/p>\n<p>OK, con lo sviluppo in modalit\u00e0 locale \u00e8 tutto chiaro, ma come ottenere lo stesso su OpenShift?<\/p>\n<h4>Server di sviluppo su OpenShift<\/h4>\n<p>\nSe ricordate, nel <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/513948\/\">post precedente<\/a><\/noindex>, abbiamo esaminato la cosiddetta fase di esecuzione (run phase) dell'immagine S2I e abbiamo visto che per impostazione predefinita la nostra applicazione web \u00e8 gestita dal modulo serve.<\/p>\n<p>Tuttavia, se guardiamo pi\u00f9 da vicino <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nodeshift\/ubi8-s2i-web-app\/blob\/master\/s2i\/run#L10\">run script<\/a><\/noindex> Da quell'esempio, c'\u00e8 una variabile di ambiente $NPM_RUN che consente di eseguire anche il proprio comando.<\/p>\n<p>Ad esempio, \u00e8 possibile utilizzare il modulo nodeshift per distribuire la nostra applicazione:<\/p>\n<pre><code class=\"plaintext\">$ npx nodeshift --deploy.env NPM_RUN=\"yarn start\" --dockerImage=nodeshift\/ubi8-s2i-web-app\n<\/code><\/pre>\n<p>\n<i>Nota: l'esempio sopra \u00e8 fornito in forma abbreviata per illustrare l'idea generale.<\/i><\/p>\n<p>Qui abbiamo aggiunto alla nostra distribuzione la variabile di ambiente NPM_RUN, che comunica al processo di esecuzione di avviare il comando yarn start, il quale avvia il server di sviluppo React all'interno del nostro pod OpenShift.<\/p>\n<p>Se esaminiamo il log del pod in esecuzione, troveremo circa il seguente output:<\/p>\n<p><img decoding=\"async\" alt=\"Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e pipeline OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/5b090223e08e32a3356608881068ce1a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Certo, tutto ci\u00f2 non avr\u00e0 senso fino a quando non saremo in grado di sincronizzare il codice locale con il codice che viene anch'esso monitorato per le modifiche, ma si trova su un server remoto.<\/p>\n<h4>Sincronizzazione del codice remoto e locale<\/h4>\n<p>\nFortunatamente, nodeshift facilita la sincronizzazione, e per monitorare le modifiche possiamo utilizzare il comando watch.<\/p>\n<p>Quindi, dopo aver eseguito il comando per distribuire il server di sviluppo per la nostra applicazione, possiamo tranquillamente usare il seguente comando:<\/p>\n<pre><code class=\"plaintext\">$ npx nodeshift watch\n<\/code><\/pre>\n<p>\nDi conseguenza, verr\u00e0 stabilita una connessione al pod in esecuzione che abbiamo creato poco prima, attivando la sincronizzazione dei nostri file locali con il cluster remoto, e i file nel nostro sistema locale inizieranno a essere monitorati per le modifiche.<\/p>\n<p>Quindi, se ora aggiorniamo il file src\/App.js, il sistema reagir\u00e0 a queste modifiche, copier\u00e0 le modifiche sul cluster remoto e avvier\u00e0 il server di sviluppo, il quale aggiorner\u00e0 quindi la nostra applicazione nel browser.<\/p>\n<p>Per completezza, mostriamo come appaiono questi comandi nella loro interezza:<\/p>\n<pre><code class=\"plaintext\">$ npx nodeshift --strictSSL=false --dockerImage=nodeshift\/ubi8-s2i-web-app --build.env YARN_ENABLED=true --expose --deploy.env NPM_RUN=\"yarn start\" --deploy.port 3000\n\n$ npx nodeshift watch --strictSSL=false\n<\/code><\/pre>\n<p>\nIl comando watch \u00e8 un'astrazione sopra il comando oc rsync, per maggiori informazioni su come funziona, si pu\u00f2 leggere <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.okd.io\/latest\/dev_guide\/copy_files_to_container.html\">qui<\/a><\/noindex>.<\/p>\n<p>Questo \u00e8 stato un esempio per React, ma la stessa metodologia pu\u00f2 essere utilizzata anche con altri framework, basta impostare la variabile di ambiente NPM_RUN nel modo corretto.<br \/>\n\u2003<\/p>\n<h3>Pipeline di OpenShift Pipelines<\/h3>\n<p><img decoding=\"async\" alt=\"Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e pipeline OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/33b932d3591b22dd00d82509b352d489.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>Successivamente parleremo di uno strumento chiamato OpenShift Pipelines e di come pu\u00f2 essere utilizzato come alternativa alle build concatenate.<\/p>\n<h4>Che cos'\u00e8 OpenShift Pipelines<\/h4>\n<p>\nOpenShift Pipelines \u00e8 un sistema CI\/CD basato sul cloud per l'integrazione continua e la consegna, progettato per organizzare pipeline utilizzando Tekton. Tekton \u00e8 un framework CI\/CD nativo Kubernetes flessibile e open source, che consente di automatizzare il deployment su varie piattaforme (Kubernetes, serverless, macchine virtuali, ecc.) astrarre rispetto al livello sottostante.<\/p>\n<p>Per capire questo articolo \u00e8 necessaria una certa familiarit\u00e0 con i Pipelines, quindi ti consigliamo vivamente di iniziare consultando <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/openshift\/pipelines-tutorial\">il manuale ufficiale<\/a><\/noindex>.<\/p>\n<h4>Configurazione dell'ambiente di lavoro<\/h4>\n<p>\nPer sperimentare con gli esempi di questo articolo, devi prima preparare l'ambiente di lavoro:<\/p>\n<ol>\n<li>Installa e configura un cluster OpenShift 4. Nei nostri esempi utilizziamo CodeReady Containers (CRD), le istruzioni per l'installazione possono essere trovate <noindex><a rel=\"nofollow\" href=\"https:\/\/cloud.redhat.com\/openshift\/install\/crc\/installer-provisioned\">qui<\/a><\/noindex>.<\/li>\n<li>Una volta che il cluster \u00e8 pronto, sar\u00e0 necessario installare il Pipeline Operator. Non preoccuparti, \u00e8 facile, le istruzioni per l'installazione <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/openshift\/pipelines-tutorial\/blob\/master\/install-operator.md\">qui<\/a><\/noindex>.<\/li>\n<li>Scarica <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/tektoncd\/cli#installing-tkn\">Tekton CLI<\/a><\/noindex> (tkn) <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/tektoncd\/cli#installing-tkn\">qui<\/a><\/noindex>.<\/li>\n<li>Esegui lo strumento da riga di comando create-react-app per creare un'applicazione che verr\u00e0 poi distribuita (si tratta di un'app semplice <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nodeshift-starters\/react-pipeline-example\">React<\/a><\/noindex>).<\/li>\n<li>(Facoltativo) Clona il repository per eseguire localmente l'esempio dell'app con il comando npm install e poi npm start.<\/li>\n<\/ol>\n<p>\nNel repository dell'applicazione ci sar\u00e0 anche una cartella k8s, dove si troveranno i file YAML di Kubernetes\/OpenShift utilizzati per il deployment dell'applicazione. Ci saranno Tasks, ClusterTasks, Resources e Pipelines che creeremo in questo <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nodeshift\/webapp-pipeline-tutorial\">repository<\/a><\/noindex>.<\/p>\n<h4>Iniziamo<\/h4>\n<p>\nPer prima cosa, per il nostro esempio, \u00e8 necessario creare un nuovo progetto nel cluster OpenShift. Chiamiamo questo progetto webapp-pipeline e lo creiamo con il seguente comando:<\/p>\n<pre><code class=\"plaintext\">$ oc new-project webapp-pipeline\n<\/code><\/pre>\n<p>\nIn seguito questo nome del progetto apparir\u00e0 nel codice, quindi, se decidi di dargli un nome diverso, non dimenticare di modificare di conseguenza il codice degli esempi. Da questo punto in poi procederemo dal basso verso l'alto: prima creeremo tutti i componenti della pipeline e solo successivamente la pipeline stessa.<\/p>\n<p>Quindi, prima di tutto\u2026<\/p>\n<h4>Tasks<\/h4>\n<p>\nCreeremo un paio di attivit\u00e0 (tasks) che poi aiuteranno a implementare l'applicazione nel nostro pipeline. La prima attivit\u00e0 \u2013 apply_manifests_task \u2013 si occupa dell'applicazione dei YAML dei risorse Kubernetes (service, deployment e route) che si trovano nella cartella k8s della nostra applicazione. La seconda attivit\u00e0 \u2013 update_deployment_task \u2013 \u00e8 responsabile dell'aggiornamento dell'immagine gi\u00e0 implementata a quella creata dal nostro pipeline.<\/p>\n<p>Non preoccuparti se non \u00e8 ancora molto chiaro. In realt\u00e0, queste attivit\u00e0 sono una sorta di utilit\u00e0 e le esamineremo pi\u00f9 in dettaglio tra poco. Ma per ora, creiamole semplicemente:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/tasks\/update_deployment_task.yaml\n$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/tasks\/apply_manifests_task.yaml\n<\/code><\/pre>\n<p>\nPoi, usando il comando tkn CLI, verifichiamo che le attivit\u00e0 siano state create:<\/p>\n<pre><code class=\"plaintext\">$ tkn task ls\n\nNAME                AGE\napply-manifests     1 minute ago\nupdate-deployment   1 minute ago\n<\/code><\/pre>\n<p>\n<i>Nota: queste sono attivit\u00e0 locali del tuo progetto attuale.<\/i><\/p>\n<h4>Attivit\u00e0 cluster (Cluster tasks)<\/h4>\n<p>\nLe attivit\u00e0 cluster sono fondamentalmente le stesse delle normali attivit\u00e0. Cio\u00e8, sono una collezione riutilizzabile di passaggi che vengono combinati in vari modi quando si esegue una specifica attivit\u00e0. La differenza \u00e8 che un'attivit\u00e0 cluster \u00e8 disponibile ovunque all'interno del cluster. Per vedere l'elenco delle attivit\u00e0 cluster, che vengono create automaticamente quando si aggiunge il Pipeline Operator, utilizziamo di nuovo il comando tkn CLI:<\/p>\n<pre><code class=\"plaintext\">$ tkn clustertask ls\n\nNAME                       AGE\nbuildah                    1 day ago\nbuildah-v0-10-0            1 day ago\njib-maven                  1 day ago\nkn                         1 day ago\nmaven                      1 day ago\nopenshift-client           1 day ago\nopenshift-client-v0-10-0   1 day ago\ns2i                        1 day ago\ns2i-go                     1 day ago\ns2i-go-v0-10-0             1 day ago\ns2i-java-11                1 day ago\ns2i-java-11-v0-10-0        1 day ago\ns2i-java-8                 1 day ago\ns2i-java-8-v0-10-0         1 day ago\ns2i-nodejs                 1 day ago\ns2i-nodejs-v0-10-0         1 day ago\ns2i-perl                   1 day ago\ns2i-perl-v0-10-0           1 day ago\ns2i-php                    1 day ago\ns2i-php-v0-10-0            1 day ago\ns2i-python-3               1 day ago\ns2i-python-3-v0-10-0       1 day ago\ns2i-ruby                   1 day ago\ns2i-ruby-v0-10-0           1 day ago\ns2i-v0-10-0                1 day ago\n<\/code><\/pre>\n<p>\nOra creiamo due attivit\u00e0 cluster. La prima generer\u00e0 un'immagine S2I e la invier\u00e0 al registry interno di OpenShift; la seconda eseguir\u00e0 la costruzione della nostra immagine basata su NGINX, utilizzando come contenuto l'applicazione gi\u00e0 costruita da noi.<\/p>\n<h4>Creiamo e inviamo l'immagine<\/h4>\n<p>\nNella creazione della prima attivit\u00e0, ripeteremo ci\u00f2 che abbiamo gi\u00e0 fatto nell'articolo precedente sulle build collegate. Ricordiamo che abbiamo utilizzato l'immagine S2I (ubi8-s2i-web-app) per \"compilare\" la nostra applicazione, ottenendo infine un'immagine memorizzata nel registro interno di OpenShift. Ora utilizzeremo questa immagine S2I dell'app web per creare un DockerFile per la nostra applicazione, e quindi utilizzeremo Buildah per eseguire una compilazione reale e inviare l'immagine risultante al registro interno di OpenShift, poich\u00e9 \u00e8 esattamente ci\u00f2 che OpenShift fa quando distribuisci le tue applicazioni utilizzando NodeShift.<\/p>\n<p>Ti chiedi da dove abbiamo preso tutte queste informazioni? Da <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/openshift\/pipelines-catalog\/blob\/master\/s2i-nodejs\/s2i-nodejs-task.yaml\">\u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 official Node.js<\/a><\/noindex>, l'abbiamo semplicemente copiata e adattata a noi.<\/p>\n<p>Ora creiamo l'attivit\u00e0 cluster s2i-web-app:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/clustertasks\/s2i-web-app-task.yaml\n<\/code><\/pre>\n<p>\nNon entreremo nei dettagli, ma ci fermeremo sul parametro OUTPUT_DIR:<\/p>\n<pre><code class=\"plaintext\">params:\n      - name: OUTPUT_DIR\n        description: La posizione della directory di output della build\n        default: build\n<\/code><\/pre>\n<p>\nPer impostazione predefinita, questo parametro \u00e8 uguale a build, ed \u00e8 l\u00ec che React colloca il contenuto compilato. In altri framework si utilizzano percorsi diversi, ad esempio in Ember si usa dist. L'output della nostra prima attivit\u00e0 cluster sar\u00e0 un'immagine contenente l'HTML, il JavaScript e il CSS che abbiamo compilato.<\/p>\n<h4>Compiliamo un'immagine basata su NGINX<\/h4>\n<p>\nPer quanto riguarda la nostra seconda attivit\u00e0 cluster, questa deve costruire un'immagine basata su NGINX, utilizzando il contenuto della nostra applicazione gi\u00e0 compilata. In sostanza, questa \u00e8 la parte della sezione precedente in cui abbiamo esaminato le build collegate.<\/p>\n<p>A tal fine, proprio come sopra, creeremo l'attivit\u00e0 cluster webapp-build-runtime:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/clustertasks\/webapp-build-runtime-task.yaml\n<\/code><\/pre>\n<p>\nSe guardiamo il codice di queste attivit\u00e0 cluster, vediamo che non viene specificato il repository Git con cui stiamo lavorando, n\u00e9 i nomi delle immagini che stiamo creando. Stiamo solo specificando cosa vogliamo passare in Git, o un'immagine in cui deve essere prodotto l'immagine finale. \u00c8 per questo che queste attivit\u00e0 cluster possono essere riutilizzate anche quando si lavora con altre applicazioni.<\/p>\n<p>E qui passiamo elegantemente al punto successivo\u2026<\/p>\n<h4>Risorse<\/h4>\n<p>\nQuindi, poich\u00e9, come abbiamo appena detto, i task di cluster devono essere il pi\u00f9 generali possibile, dobbiamo creare risorse che saranno utilizzate in input (repository Git) e in output (immagini finali). La prima risorsa di cui abbiamo bisogno \u00e8 Git, dove si trova la nostra applicazione, qualcosa del genere:<\/p>\n<pre><code class=\"plaintext\"># This resource is the location of the git repo with the web application source\napiVersion: tekton.dev\/v1alpha1\nkind: PipelineResource\nmetadata:\n  name: web-application-repo\nspec:\n  type: git\n  params:\n    - name: url\n      value: https:\/\/github.com\/nodeshift-starters\/react-pipeline-example\n    - name: revision\n      value: master\n<\/code><\/pre>\n<p>\nQui PipelineResource \u00e8 di tipo git. La chiave url nella sezione params punta a un repository specifico e imposta il branch master (questo \u00e8 facoltativo, ma lo scriviamo per completezza).<\/p>\n<p>Ora dobbiamo creare una risorsa per l'immagine, dove saranno salvati i risultati dell'esecuzione del task s2i-web-app, si fa cos\u00ec:<\/p>\n<pre><code class=\"plaintext\"># This resource is the result of running &quot;npm run build&quot;,  the resulting built files will be located in \/opt\/app-root\/output\napiVersion: tekton.dev\/v1alpha1\nkind: PipelineResource\nmetadata:\n  name: built-web-application-image\nspec:\n  type: image\n  params:\n    - name: url\n      value: image-registry.openshift-image-registry.svc:5000\/webapp-pipeline\/built-web-application:latest\n<\/code><\/pre>\n<p>\nQui PipelineResource \u00e8 di tipo image, e il valore del parametro url punta al registro delle immagini interno di OpenShift, specificamente a quello che si trova nello spazio dei nomi webapp-pipeline. Non dimenticare di cambiare questo parametro se utilizzi un altro spazio dei nomi.<\/p>\n<p>E, infine, l'ultima risorsa di cui avremo bisogno avr\u00e0 anch'essa il tipo image e sar\u00e0 l'immagine finale di NGINX, che verr\u00e0 utilizzata durante il deployment:<\/p>\n<pre><code class=\"plaintext\"># This resource is the image that will be just the static html, css, js files being run with nginx\napiVersion: tekton.dev\/v1alpha1\nkind: PipelineResource\nmetadata:\n  name: runtime-web-application-image\nspec:\n  type: image\n  params:\n    - name: url\n      value: image-registry.openshift-image-registry.svc:5000\/webapp-pipeline\/runtime-web-application:latest\n<\/code><\/pre>\n<p>\nE ancora, nota che questa risorsa salva l'immagine nel registro interno di OpenShift nello spazio dei nomi webapp-pipeline.<\/p>\n<p>Per creare tutte queste risorse in una volta, utilizziamo il comando create:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/resources\/resource.yaml\n<\/code><\/pre>\n<p>\nPuoi controllare che le risorse siano state create in questo modo:<\/p>\n<pre><code class=\"plaintext\">$ tkn resource ls\n<\/code><\/pre>\n<p><\/p>\n<h4>Pipeline del pipeline<\/h4>\n<p>\nOra che abbiamo tutti gli elementi necessari, creiamo il pipeline utilizzando il seguente comando:<\/p>\n<pre><code class=\"plaintext\">$ oc create -f https:\/\/raw.githubusercontent.com\/nodeshift\/webapp-pipeline-tutorial\/master\/pipelines\/build-and-deploy-react.yaml\n<\/code><\/pre>\n<p>\nMa prima di eseguire questo comando, diamo un'occhiata a questi elementi. Il primo \u00e8 il nome:<\/p>\n<pre><code class=\"plaintext\">apiVersion: tekton.dev\/v1alpha1\nkind: Pipeline\nmetadata:\n  name: build-and-deploy-react\n<\/code><\/pre>\n<p>\nPoi, nella sezione spec vediamo l'indicazione delle risorse che abbiamo creato in precedenza:<\/p>\n<pre><code class=\"plaintext\">spec:\n  resources:\n    - name: web-application-repo\n      type: git\n    - name: built-web-application-image\n      type: image\n    - name: runtime-web-application-image\n      type: image\n<\/code><\/pre>\n<p>\nSuccessivamente, creiamo i task che il nostro pipeline deve eseguire. Per prima cosa deve eseguire il task s2i-web-app che abbiamo gi\u00e0 creato:<\/p>\n<pre><code class=\"plaintext\">tasks:\n    - name: build-web-application\n      taskRef:\n        name: s2i-web-app\n        kind: ClusterTask\n<\/code><\/pre>\n<p>\nQuesto task prende i parametri di input (risorsa gir) e di output (risorsa built-web-application-image). Inoltre, le passiamo un parametro speciale per evitare la verifica di TLS, poich\u00e9 utilizziamo certificati self-signed:<\/p>\n<pre><code class=\"plaintext\">resources:\n        inputs:\n          - name: source\n            resource: web-application-repo\n        outputs:\n          - name: image\n            resource: built-web-application-image\n      params:\n        - name: TLSVERIFY\n          value: \"false\"\n<\/code><\/pre>\n<p>\nIl prossimo compito \u00e8 quasi identico, solo che qui viene chiamato il compito cluster webapp-build-runtime gi\u00e0 creato da noi:<\/p>\n<pre><code class=\"plaintext\">nome: build-runtime-image\n    taskRef:\n      nome: webapp-build-runtime\n      tipo: ClusterTask\n<\/code><\/pre>\n<p>\nCome per il compito precedente, stiamo passando una risorsa, ma ora si tratta di built-web-application-image (l'output del nostro compito precedente). E come output impostiamo di nuovo un'immagine. Poich\u00e9 questo compito deve essere eseguito dopo il precedente, aggiungiamo il campo runAfter:<\/p>\n<pre><code class=\"plaintext\">resources:\n        inputs:\n          - name: image\n            resource: built-web-application-image\n        outputs:\n          - name: image\n            resource: runtime-web-application-image\n        params:\n        - name: TLSVERIFY\n          value: \"false\"\n      runAfter:\n        - build-web-application\n<\/code><\/pre>\n<p>\nI prossimi due compiti sono responsabili dell'applicazione dei file YAML del servizio, del percorso e del deployment, che si trovano nella cartella k8s della nostra applicazione web, e anche di aggiornare questo deployment quando vengono creati nuovi modelli. Questi due compiti cluster li abbiamo definiti all'inizio dell'articolo.<\/p>\n<h4>Avvio della pipeline<\/h4>\n<p>\nQuindi, tutte le parti della nostra pipeline sono state create, e la avvieremo con il seguente comando:<\/p>\n<pre><code class=\"plaintext\">$ tkn pipeline start build-and-deploy-react\n<\/code><\/pre>\n<p>\nA questo punto, la riga di comando viene utilizzata in modalit\u00e0 interattiva e bisogna selezionare le risorse corrispondenti in risposta a ciascuna sua richiesta: per la risorsa git scegliamo web-application-repo, quindi per la risorsa della prima immagine \u2013 built-web-application-image, e infine per la risorsa della seconda immagine \u2013 runtime-web-application-image:<\/p>\n<pre><code class=\"plaintext\">? Choose the git resource to use for web-application-repo: web-application-repo (https:\/\/github.com\/nodeshift-starters\/react-pipeline-example)\n? Choose the image resource to use for built-web-application-image: built-web-application-image (image-registry.openshift-image-registry.svc:5000\/webapp-pipeline\/built-web-\napplication:latest)\n? Choose the image resource to use for runtime-web-application-image: runtime-web-application-image (image-registry.openshift-image-registry.svc:5000\/webapp-pipeline\/runtim\ne-web-application:latest)\nPipelinerun started: build-and-deploy-react-run-4xwsr\n<\/code><\/pre>\n<p>\nOra controlliamo lo stato della pipeline con il seguente comando:<\/p>\n<pre><code class=\"plaintext\">$ tkn pipeline logs -f\n<\/code><\/pre>\n<p>\nDopo che la pipeline \u00e8 stata avviata e l'applicazione \u00e8 stata distribuita, richiediamo il percorso pubblicato con il seguente comando:<\/p>\n<pre><code class=\"plaintext\">$ oc get route react-pipeline-example --template='http:\/\/{{.spec.host}}'\n<\/code><\/pre>\n<p>\nPer una maggiore visibilit\u00e0, possiamo visualizzare la nostra pipeline in modalit\u00e0 Developer nella web console nella sezione <b>Pipelines<\/b>, come mostrato nella Fig. 1.<\/p>\n<p><img decoding=\"async\" alt=\"Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e pipeline OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/ede9b076414e389c2cd212adeda08956.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Fig.1. Panoramica delle pipeline in esecuzione.<\/i><\/p>\n<p>Cliccando sulla pipeline in esecuzione si visualizzano ulteriori informazioni, come mostrato nella Fig.2.<\/p>\n<p><img decoding=\"async\" alt=\"Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e pipeline OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/64581b1f6d8ff91aedd963019ef29be5.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Fig. 2. Ulteriori informazioni sulla pipeline.<\/i><\/p>\n<p>Dopo ulteriori informazioni, possiamo visualizzare le applicazioni in esecuzione nella vista <b>Topology<\/b>, come mostrato nella Fig.3.<\/p>\n<p><img decoding=\"async\" alt=\"Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e pipeline OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/d23f723e14514ff60ecfddd8eb9bf752.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Fig 3. Pod in esecuzione.<\/i><\/p>\n<p>Cliccando sul cerchio nell'angolo in alto a destra dell'icona si apre la nostra applicazione, come mostrato nella Fig.4.<\/p>\n<p><img decoding=\"async\" alt=\"Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e pipeline OpenShift Pipelines\" src=\"\/wp-content\/uploads\/2020\/08\/aa8e09d9fd9f33d5faffc7f661d84ca4.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><i>Fig. 4. Applicazione React in esecuzione.<\/i><\/p>\n<h3>Conclusione<\/h3>\n<p>\nQuindi, abbiamo mostrato come avviare un server di sviluppo su OpenShift per la propria applicazione e sincronizzarlo con il sistema di file locale. Abbiamo anche esaminato come simulare un modello di chained-build utilizzando OpenShift Pipelines. Tutti i codici di esempio di questo articolo possono essere trovati <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/nodeshift\/webapp-pipeline-tutorial\">qui<\/a><\/noindex>.<\/p>\n<h3>Risorse aggiuntive (EN)<\/h3>\n<p><\/p>\n<ul>\n<li>Ebook gratuito <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/books\/deploying-openshift\/\">\u00abSviluppo su OpenShift: guida per chi ha fretta\u00bb<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/06\/11\/container-native-nodejs-istio-rhoar\/\">Costruzione di applicazioni container-oriented Node.js utilizzando Red Hat OpenShift Application Runtimes e Istio<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/05\/15\/debug-your-node-js-application-on-openshift-with-chrome-devtools\/\">Debugging delle applicazioni Node.js su OpenShift con Chrome DevTools<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/04\/16\/zero-express-openshift-3-commands\/\">Tre comandi per padroneggiare Express su OpenShift da zero<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/03\/12\/rhoar-nodejs-annoucement\/\">Annuncio della versione pubblica di Node.js in Red Hat OpenShift Application Runtimes<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/blog\/2018\/12\/21\/monitoring-node-js-applications-on-openshift-with-prometheus\/\">Monitoraggio delle applicazioni Node.js su OpenShift con Prometheus<\/a><\/noindex><\/li>\n<li>Altri articoli su <noindex><a rel=\"nofollow\" href=\"https:\/\/developers.redhat.com\/topics\/kubernetes\/\">OpenShift e Kubernetes<\/a><\/noindex> sul sito Red Hat<\/li>\n<\/ul>\n<h3>Annunci di prossimi webinar<\/h3>\n<p>\nIniziamo una serie di webinar del venerd\u00ec sull'esperienza nativa di utilizzo di Red Hat OpenShift Container Platform e Kubernetes:<\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232599abcd&amp;sc_cid=7013a000002gwqQAAQ\"><b>28 agosto, webinar Imperatore \u201cOperatore\u201d: Operatori in OpenShift e Kubernetes<\/b><\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232694abcd&amp;sc_cid=7013a000002gwrdAAA\"><b>11 settembre, DeploymentConfig vs Deployment \u2013 Cose magiche specifiche per OpenShift per costruire e dispiegare applicazioni<\/b><\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232789abcd&amp;sc_cid=7013a000002gws7AAA\"><b>25 settembre, Red Hat OpenShift e Machine API<\/b><\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232884abcd&amp;sc_cid=7013a000002gwsqAAA\"><b>9 ottobre, Come gestire un'improvvisa crescita del carico<\/b><\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/events.redhat.com\/profile\/form\/index.cfm?PKformID=0x232979abcd&amp;sc_cid=7013a000002gwumAAA\"><b>23 ottobre, Jenkins integrato, Pipeline-builds, Tekton in Red Hat OpenShift Container Platform<\/b><\/a><\/noindex><\/li>\n<\/ul>\n<p>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/redhatrussia\/blog\/515988\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435! \u0421 \u0432\u0430\u043c\u0438 \u0442\u0440\u0435\u0442\u0438\u0439 \u043f\u043e\u0441\u0442 \u0438\u0437 \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 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043d\u0430 Red Hat OpenShift. \u0412 \u0434\u0432\u0443\u0445 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u043f\u043e\u0441\u0442\u0430\u0445 \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043b\u0438, \u043a\u0430\u043a \u0440\u0430\u0437\u0432\u0435\u0440\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0433\u043e \u0437\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0448\u0430\u0433\u043e\u0432 \u0438 \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u0440\u0430\u0437 S2I \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0433\u043e\u0442\u043e\u0432\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c HTTP-\u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, NGINX \u0441 \u043f\u043e\u043c\u043e\u0449\u044c \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u0431\u043e\u0440\u043e\u043a chained [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":92049,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-92048","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.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435!\" \/>\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\/it\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\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 3: OpenShift \u043a\u0430\u043a \u0441\u0440\u0435\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u044b OpenShift Pipelines | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435!\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines\" \/>\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-22T05:42:57+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-08-22T05:42:57+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\udd47Applicazioni moderne su OpenShift, parte 3: OpenShift come ambiente di sviluppo e pipeline OpenShift Pipelines | ProHoster","description":"Ciao a tutti in questo blog!","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","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 3: OpenShift \u043a\u0430\u043a \u0441\u0440\u0435\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438 \u043a\u043e\u043d\u0432\u0435\u0439\u0435\u0440\u044b OpenShift Pipelines | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442 \u0432\u0441\u0435\u043c \u0432 \u044d\u0442\u043e\u043c \u0431\u043b\u043e\u0433\u0435!","og:url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/sovremennye-prilozheniya-na-openshift-chast-3-openshift-kak-sreda-razrabotki-i-konvejery-openshift-pipelines","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-22T05:42:57+00:00","article:modified_time":"2020-08-22T05:42:57+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"92048","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:16:43","updated":"2022-10-02 02:53:55","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/92048","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=92048"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/92048\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/92049"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=92048"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=92048"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=92048"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}