Sei sulla pagina 1di 1

CHI SIAMO DEVTALKS ALGORITMI E STRUTTURE DATI DESIGN PATTERN INTELLIGENZA ARTIFICIALE LINGUAGGI&TECNOLOGIE EXTRA GOOGLE CLOUD PLATFORM

OGIE EXTRA GOOGLE CLOUD PLATFORM PARTNER 

Di Dario Frongillo
23 Agosto 2019
DOCKERIZZARE UNA
APPLICAZIONE ANGULAR

D
2 Comments / Di Dario Frongillo / In Angular, Javascript, Linguaggi & Tecnologie, Senza categoria / 23 Agosto 2019

2 Comments

    

In questo tutorial mostreremo come dockerizzare un applicazione Angular creata e buildata


con la Angular CLI, usando Docker sia per lo sviluppo che per eseguire gli unit test e per il
deploy nale in produzione.

PREMESSA
Prima di iniziare con il vero focus di questo articolo volevo fare una premessa sui vantaggi di
utilizzare Docker anche in fase di sviluppo; quando non conoscevo bene Docker pensavo che
quest’ultimo fosse utile solo in fase di deploy in produzione, per avere una build riproducibile
o per fornire un container per il ciclo di CI. Mi sbagliavo di molto: Docker e’ utilissimo anche
in fase di sviluppo!

AMBIENTE DI SVILUPPO PRONTO PER L USO

Sulla macchina di Marco funziona e sulla mia no!

Quante volte avete sentito colleghi imprecare sbattendo la testa sul pc per con gurare
l’ambiente di sviluppo ? Con gurare un ambiente di sviluppo Angular e’ abbastanza semplice,
ma in altri contesti ci può’ volere diverse ore per çon gurare il necessario per tirare su in
locale l ambiente di sviluppo. Se dockerizzate la vostra applicazione questo problema non
sussiste, un nuovo collega potrà’ essere produttivo in 5 minuti e iniziare a lavorare senza
perdere tempo.

VERIFICARE IL FUNZIONAMENTO IN AMBIENTE


SIMILE A QUELLO DI PRODUZIONE

Il giorno del go live in produzione ad un problema riscontrato:

Questa funzionalità’ l avevo testata sul mio computer e


funzionava!

Una situazione molto ricorrente  e’  la di erenza di OS o versione di servizi tra l’ambiente di
produzione e l’ambiente locale dove si sviluppa l’applicazione. Sviluppando su un container
docker questo problema viene pressoché’ annullato: il container che gira sulla tua macchina
avrà’ le stesse caratteristiche di quello che girerà’ in produzione.

AMBIENTE DI SVILUPPO ISOLATO

Prima di utilizzare Docker la mia macchina con cui sviluppavo aveva una miriade di servizi
installati: se dovevo sviluppare e fare supporto per diverse applicazioni che facevano uso di 
versioni di erenti di servizi, lib e framework implicava di installare quest’ultimi nella mia
macchina. Il risultato era una macchina di sviluppo caotica e pesante. Da quando uso Docker
installo un servizio solo se e’ strettamente necessario; quando devo sviluppare su un progetto
mi basterà’ tirare su i relativi container che avranno al loro interno lib e servizi necessari .

DOCKERIZZARE UN APPLICAZIONE
ANGULAR
Finita questa premessa iniziamo con il nostro esercizio di questo articolo: dockerizzare un
applicazione Angular.

PROJECT SETUP

Docker v19.3.1

Angular CLI v8.1.0 ( per creare il progetto)

Node xxx ( giusto per poter installare la cli)

Andiamo a creare una nuova applicazione Angular facendo uso della CLI

1. ng new demo

CONTAINER DI SVILUPPO
Andiamo quindi a creare un immagine per poter tirare su il container di sviluppo. Il nostro
container dovrà’  avere tutti i servizi necessari a tirare su un web service locale con hot
reloading facendo uso della cli di angular ( in particolare il comando ng serve)

1. Creiamo innanzitutto il le .dockerignore nella root del progetto.

1. node_modules
2. .git
3. .gitignore
4. dist

In questo modo siamo sicuri di non copiare nel container i le non necessari.

2) Creiamo quindi il docker le di sviluppo:

Docker le.dev

1. FROM node:12.9.0-alpine
2.
3. WORKDIR '/app'
4.
5. COPY package.json .
6. RUN npm install
7.
8. COPY . .
9. EXPOSE 4200
10.
11. CMD ["npm", "start"]

Come si puo’ vedere stiamo andando a creare un immagine minimale con lo stretto
necessario al nostro container di sviluppo:

immagine base: node:12.9.0-alpine

esplicitiamo che il container espone la porta 4200 la quale andra’ mappata in fase di run
con una porta della propria macchina per poter visualizzare nel browser della nostra
macchina l’anteprima della web app.

Il comando che viene eseguito dal container e’ quello speci cato dallo script start del
package json

Come si puo notare l’immagine e’ veramente minimale e non e’ stato installato


globalmente la cli di Angular. Per avviare e buildare l’applicazione utilizzeremo npx che
ci permetterà di utilizzare la cli utilizzando le dipendenze Angular locali del progetto e
senza quindi installare globalmente Angular.

3) npm start: andiamo a modi care nel package.json del nostro progetto l’istruzione eseguita
dallo script start:

1. "scripts": {
2. "ng": "ng",
3. "start": "npx ng serve --host 0.0.0.0 --poll=500",
4. "build": "npx ng build --prod demo",
5. "test": "npx ng test --browsers=ChromeHeadless",
6. "lint": "npx ng lint",
7. "e2e": "npx ng e2e"
8. },

L’opzione host e poll sono necessarie per poter visualizzare la web app nel nostro browser
con la feature di hot reloading. Maggiori info:

Volume file changes are not detected in container on Windows 10 host: it


seems that on Windows FS events don't work properly with host mounts, so you
should rather use polling to enable live-reload:

For those who are getting into the same troubles: To achieve this with
angular-cli, "poll": 1000 has to be inserted into the defaults-object in
angular-cli.json. Unfortunately, this is not well documented. see
angular/angular-cli#1814

4) Per poter tirare su il container più’ agevolmente faremo uso di docker-compose evitando di
dover speci care da shell ogni volte le opzioni necessarie. Creiamo quindi il le docker-
compose.yaml

1. version: '3'
2. services:
3. web:
4. build:
5. context: .
6. dockerfile: Dockerfile.dev
7. ports:
8. - "4200:4200"
9. volumes:
10. - /app/node_modules
11. - .:/app

Da notare:

il docker le da utilizzare ( quello creato al punto precedente)

il mapping di porta per mappare la porta 4200 della nostra macchina con quella 4200
del container

Abbiamo de nito due volumi


node_modules come bookmark il quale non e’ bindato all’esterno del container. In
questo modo i le delle dipendenze installate esisteranno solo all’interno del
container.

.:/app: Questo comando monta la directory corrente host ( quella del progetto
angular locale) nel contenitore  /app  . In questo modo se modi chiamo uno dei le
del nostro progetto la modi ca viene percepita all’interno del container il quale
grazie al hot reload di ng serve refreshera’ l anteprima dell applicazione

A questo punto possiamo lanciare il container de nito con la cli di docker-compose

1. docker-compose up --build

Potremmo accedere all’anteprima della web app mentre sviluppiamo accedendo all’ url
http://localhost:4200/ come facevamo di consueto senza container.

CONTAINER PER UNIT TEST


Per poter girare gli unit di test di Angular e’ necessario avere un browser. Headless Chrome
 e’ un tool molto utile per far girare automated test in environment dove non e’ pratico
lanciare un browser. In rete ho trovato una immagine docker ad hoc per eseguire unit test la
quale o re un container minimale con node js + headless chrome:
https://github.com/avatsaev/angular-chrome-headless-docker 

Non ho usato direttamente quella immagine perché non aveva un tag version con node 12.
Pertanto ho copiato parte del docker le di tale repository andando a modifare la versione di
node ( in futuro potrei fare una pull request al repo originale).  Ecco il docker le di test:
Docker le.test

1. FROM debian:stable-slim
2.
3. RUN apt-get update
4. RUN apt-get install -yy wget curl gnupg
5. RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - && \
6. apt-get update && apt-get install -y nodejs && \
7. npm i -g npm@6
8.
9. RUN node -v && npm -v
10.
11. RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - &&
\
12. echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >
/etc/apt/sources.list.d/google.list && \
13. apt-get update && \
14. apt-get install -y google-chrome-stable xvfb
15. RUN npm -v
16. RUN apt update && apt install -y procps
17. RUN apt clean
18. RUN rm -rf /var/lib/apt/lists/*
19.
20.
21. WORKDIR '/app'
22.
23.
24. COPY package.json .
25. RUN npm install
26.
27. COPY . .
28.
29. CMD ["npm", "test"]

Per poter usare la versione headless di chrome ho dovuto modi care lo script test e il le
con gurazione di karma.

1. "test": "npx ng test --browsers=ChromeHeadless",

karma.conf.js

1. // Karma configuration file, see link for more information


2. // https://karma-runner.github.io/1.0/config/configuration-file.html
3.
4. module.exports = function (config) {
5. config.set({
6. basePath: '',
7. frameworks: ['jasmine', '@angular-devkit/build-angular'],
8. plugins: [
9. require('karma-jasmine'),
10. require('karma-chrome-launcher'),
11. require('karma-jasmine-html-reporter'),
12. require('karma-coverage-istanbul-reporter'),
13. require('@angular-devkit/build-angular/plugins/karma')
14. ],
15. client: {
16. clearContext: false // leave Jasmine Spec Runner output visible in browser
17. },
18. coverageIstanbulReporter: {
19. dir: require('path').join(__dirname, './coverage/demo'),
20. reports: ['html', 'lcovonly', 'text-summary'],
21. fixWebpackSourcePaths: true
22. },
23. reporters: ['progress', 'kjhtml'],
24. port: 9876,
25. colors: true,
26. logLevel: config.LOG_INFO,
27. autoWatch: true,
28. browsers: ['ChromeHeadless', 'Chrome'],
29. customLaunchers: {
30. ChromeHeadless: {
31. base: 'Chrome',
32. flags: [
33. '--headless',
34. '--disable-gpu',
35. '--no-sandbox',
36. '--remote-debugging-port=9222'
37. ]
38. }
39. },
40. singleRun: false,
41. restartOnFileChange: true
42. });
43. };

A questo punto ho editato il le docker-compose.yaml per aggiungere il descrittore per il


container di test. Ecco la versione de nitiva del le docker-compose.yaml:

1. version: '3'
2. services:
3. web:
4. build:
5. context: .
6. dockerfile: Dockerfile.dev
7. ports:
8. - "4200:4200"
9. volumes:
10. - /app/node_modules
11. - .:/app
12.
13. tests:
14. build:
15. context: .
16. dockerfile: Dockerfile.test
17. volumes:
18. - /app/node_modules
19. - .:/app

A questo punto e’ possibile lanciare in un solo colpo i due container ( sviluppo e test) con il
comando della cli di docker-compose:

1. docker-compose up --build

CONTAINER PER DEPLOY


Durante lo sviluppo, in genere si utilizza il comando ng serve per creare, controllare e servire
l’applicazione dalla memoria locale, utilizzando webpack-dev-server. Quando sei pronto per il
deploy, tuttavia, devi utilizzare il comando ng build per creare l’app e distribuire gli artefatti di
compilazione tramite un webserver come nginx  o haproxy. In questo paragrafo mostreremo
come servire la build di angular da nginx. Creiamo quindi il le Docker le ( nb e’ una
bestpractices chiamare Docker le l’immagine di produzione mentre quello di sviluppo con il
su sso .dev)

1. FROM node:12.9.0-alpine as builder


2. WORKDIR '/app'
3. COPY package*.json ./
4. RUN npm ci
5. COPY . .
6. RUN npx ng build --prod demo
7.
8. FROM nginx
9. EXPOSE 80
10. COPY --from=builder /app/dist/demo /usr/share/nginx/html

Come si puo’ notare abbiamo creato una pipeline dove in primis andiamo a buildare la
webapp e copiamo il risultato della build nell’apposita folder di nginx. A questo possiamo
buildare l’immagine e eseguire il run andando a mappare una porta della nostra macchina
con la porta 80 del container che espone nginx.

1. docker build -t italiancoders/angular-demo-app .


2.
3. docker run -p 8081:80 italiancoders/angular-demo-app

angular docker

    

A PROPOSITO DI ME

DARIO FRONGILLO

Uno degli admin di Italiancoders e dell iniziativa devtalks.


Dario Frongillo è un software engineer e architect, specializzato in Web
API, Middleware e Backend in ambito cloud native. Attualmente lavora
presso NTT DATA, realtà di consulenza internazionale.
E' membro e contributor in diverse community italiane per developers;
Nel 2017 fonda italiancoders.it, una community di blogger italiani che
divulga articoli, video e contenuti per developers.

ALTRO 

Sponsored

Pil, guerra, sanzioni e Vedere come è diventata Alessia Ricomincio dal mio lavoro,
commercio: la mappa dei rischi Merz a 47 anni ti farà venire i Claudio Narduzzi: "La mia vita è
2022 brividi ripartita quando sono tornato n…
La Repubblica HollywoodTale In collaborazione con INAIL Reinserimento

Questa foto ci ha fatto venire la 43 rare foto che mostrano quanto Play Now In Your Browser
pelle d'oca. Osservatela bene e fosse veramente folle Woodstock Hero Wars
capirete! History 10
People-Today

I NOSTRI PARTNER

Privacy Policy

Potrebbero piacerti anche