Kako zapakirati VueJS + NodeJS + MongoDB aplikaciju u Docker

Kako zapakirati VueJS + NodeJS + MongoDB aplikaciju u Docker
Kao što se može razumjeti iz prethodnog članka, radila sam na različitim projektima. Prvi dani u novom timu obično prolaze slično: backend programer se pridruži meni i izvodi magične radnje za instalaciju i implementaciju aplikacije. Docker je neizostavan za frontend programere, jer je backend često napisan na širokom spektru tehnologija PHP/Java/Python/C# te frontend ne mora stalno ometati backend da bi sve instalirao i postavio. Samo na jednom mjestu sam vidjela vezu Docker-Jenkins s transparentnom implementacijom, logovima i automatskim testovima.

O Dockera je napisano mnogo detaljnih članaka. U ovom članku bit će riječi o implementaciji Single Page Application koristeći VueJS/Vue Router, sa serverskom komponentom u obliku RESTful API s NodeJS, a kao baza podataka koristi se MongoDB. Za opis i pokretanje više aplikacija-kontejnera koristi se Docker Compose.

Zašto je Docker potreban

Docker omogućava automatizaciju procesa implementacije aplikacije. Razvijaču više nije potrebno samostalno instalirati programe, boriti se s nekompatibilnošću verzija na svom računalu. Dovoljno je instalirati Docker i unijeti 1-2 naredbe u konzolu. Najprikladnije je to činiti na Linuxu.

Uvod

Instaliramo Docker i Docker compose

Struktura mapa

Stvaramo 2 mape za klijentske i serverske aplikacije. Datoteka s ekstenzijom .yml je konfiguracija Docker Compose, u kojoj se definiraju i povezuju kontejneri aplikacije.
Docker-compose.yml:

version: "3"
services:
  mongo:
    container_name: mongo
    hostname: mongo
    image: mongo
    ports:
      - "27017:27017"
  server:
    build: server/
    #command: node ./server.js #ovdje se može prepisati CMD iz Dockerfile u /server
    ports:
      - "3000:3000"
    links:
      - mongo
  client:
    build: client/
    #command: http-server ./dist #ovdje se može prepisati CMD iz Dockerfile u /client
    network_mode: host
    ports:
      - "8089:8089"
    depends_on:
      - server

Stvaramo 3 servisa u Dockeru: za NodeJS, MongoDB i za statički sadržaj na Vue. Da bismo povezali klijenta sa serverom, dodano je depends on server. Za povezivanje MongoDB s serverskim API-jem koristi se links mongo. Server, client, mongo — nazivi servisa.

Klijent na VueJS

U mapi /client nalazi se aplikacija na VueJS. Aplikacija je stvorena pomoću Vue Cli. Tijekom izgradnje slike aplikacija se gradi u skup statičkih datoteka u mapi /dist. U Dockerfile-u opisane su naredbe za izgradnju slike:

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

Napomena: package.json se kopira i instalira odvojeno od ostalih datoteka projekta. Ovo se radi radi performansi, kako bi sadržaj mape /node_modules bio keširan prilikom ponovnog gradnje. Svaka linija komande se kešira odvojeno.

Na kraju, prilikom pokretanja kontejnera izvršava se komanda npm run dev. Ova komanda je opisana u package.json:


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

Da biste pokrenuli datoteke iz mape /dist, globalno se instalira http-server, a u dev-dependencies se dodaje paket spa-http-server, kako bi Vue Router pravilno radio. Zastavica —push-state preusmerava na index.html. Zastavica -c sa vrednošću 1 sekundu je dodata kako http-server ne bi keširala skripte. Ovo je testni primer; u realnom projektu je bolje koristiti nginx.

U Vuex store-u kreiramo polje apiHost: 'http://localhost:3000', gde se navodi port NodeJS API-a. Klijentska strana je spremna. Svi zahtevi sa klijenta ka baku sada idu na ovu URL.

NodeJS server API

U mapi /server kreiramo server.js i Dockerfile:


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

U server.js navodi se url za bazu podataka const url = 'mongodb://mongo:27017/';. Dozvoljavamo cross-domain zahteve sa klijenta:


const clientUrl = 'http://localhost:8081';
const corsOptions = {
  origin: clientUrl,
  optionsSuccessStatus: 200, // neki stariji pretraživači (IE11, razni SmartTV) se muče sa 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));
  });

Zaključak

Sada prelazimo u direktorij projekta i pokrećemo docker-compose build za izgradnju slika i docker-compose up za pokretanje kontejnera. Komanda će pokrenuti 3 kontejnera: server, client, mongo. Za server na NodeJS mogu se podesiti hot-reload, povezujući ga sa user mapom. Klijent se tokom razvoja može lokalno pokretati sa hot reload, pokrećući posebno Poslužitelj i mongo. Da biste pokrenuli poseban servis, dovoljno je navesti njegovo ime docker-compose up client. Ne zaboravite ponekad izvršiti prune i brisanje kontejnera (containers), mreža (networks) i slika (images), da biste oslobodili resurse.

Potpun kod možete pogledati ovdje. Projekat je još u fazi razvoja.

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster