Hoe een VueJS + NodeJS + MongoDB-applicatie in Docker te verpakken

Hoe een VueJS + NodeJS + MongoDB-applicatie in Docker te verpakken
Zoals uit het vorige artikel blijkt, heb ik aan verschillende projecten gewerkt. De eerste dagen in een nieuw team verlopen meestal hetzelfde: de backend-ontwikkelaar komt bij me zitten en voert magische handelingen uit om de applicatie te installeren en te deployen. Docker is onmisbaar voor frontend-ontwikkelaars, omdat de backend vaak op een breed scala aan stacks is geschreven, zoals PHP/Java/Python/C#, en de frontend niet elke keer de backend moet onderbreken om alles te installeren en uit te rollen. Slechts op één plek heb ik de combinatie Docker-Jenkins gezien met transparante deployments, logs en geïntegreerde automatiseringstests.

Er zijn veel gedetailleerde artikelen over Docker geschreven. In dit artikel gaat het over het uitrollen van een Single Page Application met VueJS/Vue Router, de serverzijde in de vorm van een RESTful API met NodeJS, en als database wordt MongoDB gebruikt. Voor het beschrijven en opstarten van meerdere applicatie-containers wordt Docker Compose gebruikt.

Waarom is Docker nodig

Docker maakt het mogelijk om het proces van het uitrollen van applicaties te automatiseren. Een ontwikkelaar hoeft niet langer zelf programma's te installeren of te worstelen met versie-incompatibiliteit op zijn machine. Het is voldoende om Docker te installeren en 1-2 commando's in de console in te voeren. Het handigst is dit te doen op Linux.

Aan de slag

Instellen Docker en Docker Compose

Structuur van de mappen

We maken 2 mappen aan voor de client- en serverapplicaties. Het bestand met de extensie .yml is de configuratie Docker Compose, waar de containers van de applicatie worden gedefinieerd en aan elkaar gekoppeld.
Docker-compose.yml:

version: "3"
services:
  mongo:
    container_name: mongo
    hostname: mongo
    image: mongo
    ports:
      - "27017:27017"
  server:
    build: server/
    #command: node ./server.js #hier kan de CMD uit de Dockerfile in /server worden overschreven
    ports:
      - "3000:3000"
    links:
      - mongo
  client:
    build: client/
    #command: http-server ./dist #hier kan de CMD uit de Dockerfile in /client worden overschreven
    network_mode: host
    ports:
      - "8089:8089"
    depends_on:
      - server

We maken 3 services in Docker: voor NodeJS, MongoDB en voor statische bestanden op Vue. Om de client met de server te verbinden is toegevoegd depends on server. Voor de koppeling van MongoDB met de server-API wordt gebruikt links mongo. Server, client, mongo - namen van de services.

Client op VueJS

In de map /client bevindt zich de applicatie op VueJS. De applicatie is gemaakt met behulp van Vue Cli. Tijdens het bouwen van de afbeelding wordt de clientapplicatie omgezet in een set statische bestanden in de map /dist. In de Dockerfile staat een set commando's voor het bouwen van de afbeelding:

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

Houd er rekening mee dat package.json apart wordt gekopieerd en geĆÆnstalleerd van de andere projectbestanden. Dit is gedaan voor de prestaties, zodat de inhoud van de map /node_modules wordt opgeslagen bij een herbouw. Elke regel-opdracht wordt afzonderlijk gecached.

Aan het einde, bij het opstarten van de container, wordt de opdracht uitgevoerd npm run dev. Deze opdracht is beschreven in package.json:


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

Om bestanden uit de map /dist, wordt global geĆÆnstalleerd http-server, en in dev-dependencies wordt het pakket spa-http-server, zodat Vue Router goed werkt. De vlag —push-state maakt een omleiding naar index.html. De vlag -c met een waarde van 1 seconde is toegevoegd om http-server scripts niet te cachen. Dit is een testvoorbeeld; in een echt project is het beter om nginx te gebruiken.

In de Vuex store maken we een veld apiHost: 'http://localhost:3000', waar de poort van de NodeJS API wordt vastgelegd. De clientzijde is klaar. Nu gaan alle verzoeken van de client naar de back-end naar deze url.

NodeJS server API

In de map /server maken we server.js en Dockerfile:


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

In server.js wordt aangegeven url voor de database const url = 'mongodb://mongo:27017/';. We staan cross-origin verzoeken van de client toe:


const clientUrl = 'http://localhost:8081';
const corsOptions = {
  origin: clientUrl,
  optionsSuccessStatus: 200, // sommige oudere browsers (IE11, verschillende SmartTV's) hebben problemen met 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));
  });

Conclusie

Laten we nu naar de projectdirectory gaan en docker-compose build uitvoeren om de afbeeldingen te bouwen en docker-compose up de containers te starten. De opdracht zal 3 containers opstarten: server, client, mongo. Voor de server op NodeJS kan hot-reload worden ingesteld door deze te koppelen aan de user-map. En de client in de ontwikkelingsfase lokaal te starten met hot reload door deze apart te starten server en mongo. Om een afzonderlijke service te starten, hoef je alleen de naam op te geven docker-compose up client. Vergeet niet af en toe te doen prune en verwijder containers (containers), netwerken (networks) en afbeeldingen (images) om middelen vrij te maken.

De volledige code is beschikbaar here. Het project is nog in ontwikkeling.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers šŸ”„ Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster