Cum să împachetezi o aplicație VueJS + NodeJS + MongoDB în Docker

Cum să împachetezi o aplicație VueJS + NodeJS + MongoDB în Docker
Așa cum am menționat în articolul anterior, am lucrat cu diferite proiecte. Primele zile într-o echipă nouă decurg de obicei la fel: backend developer se alătură echipei mele și efectuează acțiuni magice pentru instalarea și desfășurarea aplicației. Docker este esențial pentru frontend-eri, deoarece backend-ul este adesea scris într-o gamă largă de stack-uri PHP/Java/Python/C#, iar frontend-ul nu trebuie să deranjeze constant backend-ul pentru a instala și desfășura totul. Doar într-un singur loc am văzut o combinație Docker-Jenkins cu desfășurare transparentă, jurnale și teste automate integrate.

Despre Docker s-au scris multe articole detaliate. În acest articol, vom discuta despre desfășurarea unei aplicații de tip Single Page Application folosind VueJS/Vue Router, cu partea server ca un API RESTful c NodeJS, iar MongoDB utilizându-se ca bază de date. Pentru descrierea și lansarea mai multor aplicații-container se folosește Docker Compose.

De ce este necesar Docker

Docker permite automatizarea procesului de desfășurare a aplicației. Dezvoltatorul nu mai trebuie să instaleze programele manual, să se lupte cu incompatibilitatea versiunilor pe mașina sa. Este suficient să instaleze Docker și să ruleze 1-2 comenzi în consolă. Cel mai simplu este să facă acest lucru pe Linux.

Începuturi

Instalăm Docker și Docker compose

Structura folderelor

Creăm 2 foldere pentru aplicațiile client și server. Fișierul cu extensia .yml reprezintă configurația Docker Compose, unde container-urile aplicației sunt definite și legate.
Docker-compose.yml:

version: "3"
services:
  mongo:
    container_name: mongo
    hostname: mongo
    image: mongo
    ports:
      - "27017:27017"
  server:
    build: server/
    #command: node ./server.js #aici se poate suprascrie CMD din Dockerfile în /server
    ports:
      - "3000:3000"
    links:
      - mongo
  client:
    build: client/
    #command: http-server ./dist #aici se poate suprascrie CMD din Dockerfile în /client
    network_mode: host
    ports:
      - "8089:8089"
    depends_on:
      - server

Creăm 3 servicii în Docker: pentru NodeJS, MongoDB și pentru statică pe Vue. Pentru a conecta clientul la server a fost adăugată depends on server. Pentru conectarea MongoDB cu API-ul serverului se folosește links mongo. Server, client, mongo - numele serviciilor.

Client pe VueJS

În folderul /client se află aplicația pe VueJS. Aplicația a fost creată cu ajutorul Vue Cli. La construirea imaginii, aplicația client este transformată într-un set de fișiere statice în folderul /dist. În Dockerfile este descris un set de comenzi pentru construirea imaginii:

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"]

Rețineți că package.json este copiat și instalat separat de celelalte fișiere ale proiectului. Aceasta se face pentru performanță, astfel încât conținutul folderului /node_modules să fie stocat în cache la o recompunere ulterioară. Fiecare linie-comandă este stocată în cache separat.

La final, la lansarea containerului se execută comanda npm run dev. Această comandă este descrisă în package.json:


"scripts": {
	 "test:dev": "http-server dist -p 8081 -c 1 --push-state"
}

Pentru a rula fișierele din folderul /dist, se instalează global http-server, iar în dev-dependencies pachetul spa-http-server, pentru ca Vue Router să funcționeze corect. Flagra —push-state redirecționează către index.html. Flagra -c cu valoarea de 1 secundă a fost adăugată pentru a http-server nu caching scripturile. Acesta este un exemplu de testare, pentru un proiect real ar fi mai bine să folosești nginx.

În store-ul Vuex, creăm un câmp apiHost: 'http://localhost:3000', unde se specifică portul NodeJS Api. Partea client este gata. Acum toate cererile de la client către backend merg la acest url.

API-ul serverului NodeJS

În folderul /server creăm server.js și Dockerfile:


FROM node:10
WORKDIR /server
COPY ./package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

În server.js este specificat url pentru baza de date const url = 'mongodb://mongo:27017/';. Permitem cererile cross-origin de la client:


const clientUrl = 'http://localhost:8081';
const corsOptions = {
  origin: clientUrl,
  optionsSuccessStatus: 200, // unele browsere mai vechi (IE11, diverse SmartTV-uri) se blochează la 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));
  });

Concluzie

Acum să trecem în directorul proiectului și să lansăm docker-compose build pentru a construi imaginile și docker-compose up pentru a lansa containerele. Comanda va ridica 3 containere: server, client, mongo. Pentru serverul pe NodeJS poți seta hot-reload, conectându-l cu folderul user. Iar clientul în stadiul de dezvoltare să fie lansat local cu hot reload, pornind separat server și mongo. Pentru a lansa un serviciu separat, este suficient să îi specifici numele docker-compose up client. Nu uita să faci din când în când prune și să ștergi containerele, rețelele (networks) și imaginile (images) pentru a elibera resursele.

Codul complet poate fi vizualizat aici. Proiectul este încă în stadiul de dezvoltare.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster