Hvordan pakke et VueJS + NodeJS + MongoDB-applikasjon inn i Docker

Hvordan pakke et VueJS + NodeJS + MongoDB-applikasjon inn i Docker
Som du kan forstå fra den forrige artikkelen, har jeg jobbet med ulike prosjekter. De første dagene i det nye teamet pleier å være ganske like: backend-utvikleren setter seg ved siden av meg og utfører magiske handlinger for installasjon og deployering av applikasjonen. Docker er uunnværlig for frontend-utviklere, siden backend ofte er skrevet i et bredt spekter av stakker som PHP/Java/Python/C#, og frontend trenger ikke å avbryte backend hver gang for å installere og starte opp alt. Bare ett sted har jeg sett en kombinasjon av Docker-Jenkins med transparent deployering, logger og automatiserte tester.

Det er skrevet mange detaljerte artikler om Docker. I denne artikkelen skal vi snakke om deployering av en Single Page Application ved bruk av VueJS/Vue Router, med serverdelen som en RESTful API med NodeJS, og MongoDB som database. Docker Compose brukes til å beskrive og starte flere applikasjonscontainere.

Hvorfor trenger vi Docker

Docker gjør det mulig å automatisere prosessen med å sette opp applikasjonen. Utvikleren trenger ikke lenger å installere programmer selv, eller slite med versjonskompatibilitet på sin maskin. Det er nok å installere Docker og skrive inn 1-2 kommandoer i konsollen. Det er enklest å gjøre dette på Linux.

Kom i gang

Installerer Docker og Docker compose

Mappestruktur

Vi lager to mapper for klient- og serverapplikasjonene. Filen med .yml-utvidelse er konfigurasjonen. Docker Compose, der containere for applikasjonen defineres og kobles sammen.
docker-compose.yml:

version: "3"
services:
  mongo:
    container_name: mongo
    hostname: mongo
    image: mongo
    ports:
      - "27017:27017"
  server:
    build: server/
    #command: node ./server.js #her kan CMD fra Dockerfile i /server overskrives
    ports:
      - "3000:3000"
    links:
      - mongo
  client:
    build: client/
    #command: http-server ./dist #her kan CMD fra Dockerfile i /client overskrives
    network_mode: host
    ports:
      - "8089:8089"
    depends_on:
      - server

Vi lager tre tjenester i Docker: for NodeJS, MongoDB og for statikken på Vue. For å knytte klient til serveren, er det lagt til depends on server. For å koble MongoDB til serverens API brukes links mongo. Server, klient, mongo – navnene på tjenestene.

Klienten på VueJS

I mappen /client applikasjonen er plassert på VueJS. Applikasjonen er laget med hjelp av Vue Cli. Når bildet bygges, bygges klientapplikasjonen til en samling statiske filer i mappen /dist. I Dockerfile er det beskrevet et sett med kommandoer for å bygge bildet:

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

Merk at package.json blir kopiert og installert separat fra de andre filene i prosjektet. Dette gjøres for ytelsen, slik at innholdet i mappen /node_modules blir cached ved gjentatt bygging. Hver kommandolinje caches separat.

Til slutt, ved oppstart av containeren, kjøres kommandoen npm run dev. Denne kommandoen er beskrevet i package.json:


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

For å kjøre filene fra mappen /dist, installeres globalt http-server, og i dev-dependencies pakken spa-http-server, slik at Vue Router fungerer korrekt. Flagget —push-state gjør en redirect til index.html. Flagget -c med verdien 1 sekund er lagt til for å http-server ikke cache skriptene. Dette er et testeksempel, i et reelt prosjekt er det bedre å bruke nginx.

I Vuex store oppretter vi feltet apiHost: 'http://localhost:3000', hvor porten for NodeJS Api er spesifisert. Klientsiden er klar. Nå går alle forespørslene fra klienten til baksiden til denne url-en.

NodeJS server API

I mappen /server oppretter vi server.js og Dockerfile:


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

I server.js angitt url for databasen const url = 'mongodb://mongo:27017/';. Vi tillater kryssdomene forespørslene fra klienten:


const clientUrl = 'http://localhost:8081';
const corsOptions = {
  origin: clientUrl,
  optionsSuccessStatus: 200, // noen eldre nettlesere (IE11, forskjellige SmartTV-er) henger seg opp på 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));
  });

Konklusjon

Nå går vi til prosjektmappen og kjører docker-compose build for å bygge bilder og docker-compose up for å starte containerne. Kommandoen vil løfte 3 containere: server, client, mongo. For serveren på NodeJS kan hot-reload konfigureres ved å knytte den til brukerens mappe. Klienten kan under utvikling kjøres lokalt med hot reload, ved å starte server og mongo. For å starte en separat tjeneste, er det nok å angi navnet docker-compose up client. Ikke glem å av og til kjøre prune og fjerne containere, nettverk og bilder for å frigjøre ressurser.

Du kan se den fullstendige koden here. Prosjektet er fortsatt under utvikling.

Kilde: habr.com

Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere 🔥 Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster