Come si può capire dall'articolo precedente, ho lavorato su diversi progetti. I primi giorni in un nuovo team di solito si svolgono in modo simile: il backend si unisce a me e esegue azioni magiche per installare e distribuire l'applicazione. Docker è indispensabile per i frontend, poiché il backend è spesso scritto su un'ampia varietà di stack PHP/Java/Python/C# e il frontend non deve ogni volta distrarre il backend per installare e avviare tutto. Solo in un caso ho visto una combinazione di Docker-Jenkins con distribuzione trasparente, log e test automatici integrati.
Sono stati scritti molti articoli dettagliati su Docker. In questo articolo parleremo del deployment di un'applicazione Single Page con VueJS/Vue Router, la parte server come RESTful API con NodeJS e MongoDB come database. Per descrivere e avviare diverse applicazioni containerizzate, si utilizza Docker Compose.
A cosa serve Docker
Docker consente di automatizzare il processo di avvio dell'applicazione. Non è più necessario che lo sviluppatore installi manualmente i programmi e combatta con problemi di compatibilità delle versioni sulla propria macchina. Basta installare Docker e digitare 1-2 comandi nella console. È più facile farlo su Linux.
Iniziamo
Installiamo and
Struttura delle cartelle
Creiamo 2 cartelle per le applicazioni client e server. Un file con estensione .yml è un file di configurazione Docker Compose, dove sono definiti e collegati i container dell'applicazione.
Docker-compose.yml:
version: "3"
services:
mongo:
container_name: mongo
hostname: mongo
image: mongo
ports:
- "27017:27017"
server:
build: server/
#command: node ./server.js #qui è possibile sovrascrivere CMD dal Dockerfile in /server
ports:
- "3000:3000"
links:
- mongo
client:
build: client/
#command: http-server ./dist #qui è possibile sovrascrivere CMD dal Dockerfile in /client
network_mode: host
ports:
- "8089:8089"
depends_on:
- server
Creiamo 3 servizi in Docker: per NodeJS, MongoDB e per la statica su Vue. Per collegare il client al server è stato aggiunto depends on server. Per il collegamento di MongoDB con l'API server è utilizzato links mongo. Server, client, mongo sono i nomi dei servizi.
Client su VueJS
Nella cartella /client si trova l'applicazione su VueJS. L'applicazione è stata creata utilizzando . Durante la costruzione dell'immagine, l'applicazione client viene creata in un insieme di file statici nella cartella /dist. Nel Dockerfile è descritto un insieme di comandi per la costruzione dell'immagine:
FROM node:10
WORKDIR /client
COPY ./package*.json ./
RUN npm install
RUN npm install -g http-server
COPY . .
RUN npm run build
EXPOSE 8081
CMD ["npm", "test:dev"]
Si prega di notare che il package.json viene copiato e installato separatamente dagli altri file del progetto. Questo è stato fatto per motivi di prestazioni, affinché il contenuto della cartella /node_modules venga memorizzato nella cache durante la ricompilazione. Ogni riga di comando viene memorizzata nella cache separatamente.
Alla fine, quando viene avviato il contenitore, viene eseguita la comando npm run dev. Questo comando è descritto in package.json:
"scripts": {
"test:dev": "http-server dist -p 8081 -c 1 --push-state"
}
Per eseguire i file dalla cartella /dist, viene installato globalmente http-server, e nelle dipendenze di sviluppo il pacchetto spa-http-server, affinché Vue Router funzioni correttamente. Il flag —push-state effettua il redirect verso index.html. Il flag -c con valore 1 secondo è stato aggiunto per http-server non memorizzare nella cache gli script. Questo è un esempio di test, in un progetto reale è meglio utilizzare nginx.
Nel negozio Vuex creiamo il campo apiHost: 'http://localhost:3000', dove viene specificata la porta dell'API NodeJS. La parte client è pronta. Ora tutte le richieste dal client al backend vanno a questo URL.
API server NodeJS
Nella cartella /server creiamo server.js e Dockerfile:
FROM node:10
WORKDIR /server
COPY ./package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
In server.js viene specificato url per il database const url = 'mongodb://mongo:27017/';. Permettiamo richieste cross-domain dal client:
const clientUrl = 'http://localhost:8081';
const corsOptions = {
origin: clientUrl,
optionsSuccessStatus: 200, \\ alcuni browser legacy (IE11, vari SmartTV) si bloccano su 204
};
app.use(cors());
app.all('/*', (req, res, next) => {
res.header('Access-Control-Allow-Origin', clientUrl);
res.header('Access-Control-Allow-Headers', 'X-Requested-With');
next();
});
app.get('/getProducts', cors(corsOptions), (req, res) => {
products.getContent
.then(data => res.json(data), err => res.json(err));
});
app.get('/getUsers', cors(corsOptions), (req, res) => {
db.getUsers()
.then(data => res.json(data), err => res.json(err));
});
Conclusione
Ora passiamo alla directory del progetto e avviamo docker-compose build per costruire le immagini e docker-compose up per avviare i contenitori. Il comando solleverà 3 contenitori: server, client, mongo. Per il server su NodeJS è possibile configurare il hot-reload, collegandolo alla cartella user. E il client in fase di sviluppo deve essere avviato localmente con hot reload, eseguendo separatamente server e mongo. Per avviare un servizio separato, è sufficiente specificarne il nome docker-compose up client. Ricordate di fare occasionalmente prune e rimuovere contenitori (containers), reti (networks) e immagini (images) per liberare risorse.
Il codice completo può essere visualizzato . Il progetto è ancora in fase di sviluppo.
Fonte: habr.com
