Как ΡƒΠΏΠ°ΠΊΠΎΠ²Π°Ρ‚ΡŒ VueJS + NodeJS + MongoDB ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² Docker

Как ΡƒΠΏΠ°ΠΊΠΎΠ²Π°Ρ‚ΡŒ VueJS + NodeJS + MongoDB ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² Docker
Как ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ½ΡΡ‚ΡŒ ΠΈΠ· ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΉ ΡΡ‚Π°Ρ‚ΡŒΠΈ, я Ρ€Π°Π±ΠΎΡ‚Π°Π»Π° с Ρ€Π°Π·Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°ΠΌΠΈ. ΠŸΠ΅Ρ€Π²Ρ‹Π΅ Π΄Π½ΠΈ Π² Π½ΠΎΠ²ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Π΅ ΠΎΠ±Ρ‹Ρ‡Π½ΠΎ проходят ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ: бэкСндСр подсаТиваСтся ΠΊΠΎ ΠΌΠ½Π΅ ΠΈ выполняСт магичСскиС дСйствия ΠΏΠΎ установкС ΠΈ дСплою прилоТСния. Π”ΠΎΠΊΠ΅Ρ€ Π½Π΅Π·Π°ΠΌΠ΅Π½ΠΈΠΌ для Ρ„Ρ€ΠΎΠ½Ρ‚Π΅Π½Π΄Π΅Ρ€ΠΎΠ², Ρ‚.ΠΊ. бэкСнд Π·Π°Ρ‡Π°ΡΡ‚ΡƒΡŽ написан Π½Π° ΡˆΠΈΡ€ΠΎΠΊΠΎΠΌ спСктрС стСков PHP/Java/Python/C# ΠΈ Ρ„Ρ€ΠΎΠ½Ρ‚Ρƒ Π½Π΅ Π½Π°Π΄ΠΎ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· ΠΎΡ‚Π²Π»Π΅ΠΊΠ°Ρ‚ΡŒ бэка, Ρ‡Ρ‚ΠΎΠ±Ρ‹ всС ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ ΠΈ Ρ€Π°Π·Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒ. Волько Π² ΠΎΠ΄Π½ΠΎΠΌ мСстС я Π²ΠΈΠ΄Π΅Π»Π° связку Docker-Jenkins с ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹ΠΌ Π΄Π΅ΠΏΠ»ΠΎΠ΅ΠΌ, Π»ΠΎΠ³Π°ΠΌΠΈ, ΠΏΡ€ΠΈΠΊΡ€ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΌΠΈ автотСстами.

ΠŸΡ€ΠΎ Π΄ΠΎΠΊΠ΅Ρ€ написано ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Ρ‹Ρ… статСй. Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ΠΉ Ρ€Π΅Ρ‡ΡŒ ΠΏΠΎΠΉΠ΄Π΅Ρ‚ ΠΎ Ρ€Π°Π·Π²Π΅Ρ€Ρ‚Ρ‹Π²Π°Π½ΠΈΠΈ Single Page Application с использованиСм VueJS/Vue Router, сСрвСрная Ρ‡Π°ΡΡ‚ΡŒ Π² Π²ΠΈΠ΄Π΅ RESTful API c NodeJS, Π° Π² качСствС Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ MongoDB. Для описания ΠΈ запуска Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ-ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Docker Compose.

Π—Π°Ρ‡Π΅ΠΌ Π½ΡƒΠΆΠ΅Π½ Π”ΠΎΠΊΠ΅Ρ€

Π”ΠΎΠΊΠ΅Ρ€ позволяСт Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ процСсс разворачивания прилоТСния. Π Π°Π·Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΡƒ большС Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Π±ΠΎΡ€ΠΎΡ‚ΡŒΡΡ с Π½Π΅ΡΠΎΠ²ΠΌΠ΅ΡΡ‚ΠΈΠΌΠΎΡΡ‚ΡŒΡŽ вСрсий Π½Π° своСй машинС. Достаточно ΡƒΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π”ΠΎΠΊΠ΅Ρ€ ΠΈ Π²Π±ΠΈΡ‚ΡŒ 1-2 ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π² консоль. Π£Π΄ΠΎΠ±Π½Π΅Π΅ всСго Π΄Π΅Π»Π°Ρ‚ΡŒ это Π½Π° Linux.

Getting started

УстанавливаСм Docker and Docker compose

Π‘Ρ‚Ρ€ΡƒΠΊΡ‚ΡƒΡ€Π° ΠΏΠ°ΠΏΠΎΠΊ

Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ 2 ΠΏΠ°ΠΏΠΊΠΈ для клиСнтского ΠΈ сСрвСрного ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. Π€Π°ΠΉΠ» с Ρ€Π°ΡΡˆΠΈΡ€Π΅Π½ΠΈΠ΅ΠΌ .yml β€” это ΠΊΠΎΠ½Ρ„ΠΈΠ³ Docker Compose, Π³Π΄Π΅ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ΡΡ ΠΈ ΡΠ²ΡΠ·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Ρ‹ прилоТСния.
Docker-compose.yml:

version: "3"
services:
  mongo:
    container_name: mongo
    hostname: mongo
    image: mongo
    ports:
      - "27017:27017"
  server:
    build: server/
    #command: node ./server.js #здСсь ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ CMD ΠΈΠ· Dockerfile Π² /server
    ports:
      - "3000:3000"
    links:
      - mongo
  client:
    build: client/
    #command: http-server ./dist #здСсь ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ CMD ΠΈΠ· Dockerfile Π² /client
    network_mode: host
    ports:
      - "8089:8089"
    depends_on:
      - server

Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ 3 сСрвиса Π² Π΄ΠΎΠΊΠ΅Ρ€Π΅: для NodeJS, MongoDB ΠΈ для статики Π½Π° Vue. Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠ²ΡΠ·Π°Ρ‚ΡŒ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ с сСрвСром Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ depends on server. Для Π»ΠΈΠ½ΠΊΠΎΠ²ΠΊΠΈ MongoDB с сСрвСрным API ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ links mongo. Server, client, mongo β€” названия сСрвисов.

ΠšΠ»ΠΈΠ΅Π½Ρ‚ Π½Π° VueJS

Π’ ΠΏΠ°ΠΏΠΊΠ΅ /client располоТСно ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° VueJS. ΠŸΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ создано с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Vue Cli. ΠŸΡ€ΠΈ построСнии ΠΎΠ±Ρ€Π°Π·Π° клиСнтскоС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ билдится Π² Π½Π°Π±ΠΎΡ€ статичСских Ρ„Π°ΠΉΠ»ΠΎΠ² Π² ΠΏΠ°ΠΏΠΊΠ΅ /dist. Π’ Dockerfile описан Π½Π°Π±ΠΎΡ€ ΠΊΠΎΠΌΠ°Π½Π΄ для построСния ΠΎΠ±Ρ€Π°Π·Π°:

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

ΠžΠ±Ρ€Π°Ρ‚ΠΈΡ‚Π΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Ρ‡Ρ‚ΠΎ package.json копируСтся ΠΈ устанавливаСтся ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ ΠΎΡ‚ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Ρ„Π°ΠΉΠ»ΠΎΠ² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. Π­Ρ‚ΠΎ сдСлано для ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ содСрТимоС ΠΏΠ°ΠΏΠΊΠΈ /node_modules Π·Π°ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π»ΠΎΡΡŒ ΠΏΡ€ΠΈ ΠΏΠΎΠ²Ρ‚ΠΎΡ€Π½ΠΎΠΌ Π±ΠΈΠ»Π΄Π΅. КаТдая строчка-ΠΊΠΎΠΌΠ°Π½Π΄Π° ΠΊΠ΅ΡˆΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ.

Π’ ΠΊΠΎΠ½Ρ†Π΅, ΠΏΡ€ΠΈ запускС ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° выполняСтся ΠΊΠΎΠΌΠ°Π½Π΄Π° npm run dev. Π­Ρ‚Π° ΠΊΠΎΠΌΠ°Π½Π΄Π° описана Π² package.json:


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

Π§Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈΠ· ΠΏΠ°ΠΏΠΊΠΈ /dist, глобально устанавливаСтся http-server, Π° Π² dev-dependencies ΠΏΠ°ΠΊΠ΅Ρ‚ spa-http-server, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Vue Router Ρ€Π°Π±ΠΎΡ‚Π°Π» ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚Π½ΠΎ. Π€Π»Π°Π³ β€”push-state Π΄Π΅Π»Π°Π΅Ρ‚ Ρ€Π΅Π΄ΠΈΡ€Π΅ΠΊΡ‚ Π½Π° index.html. Π€Π»Π°Π³ -c со Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ΠΌ 1 сСкунда Π΄ΠΎΠ±Π°Π²Π»Π΅Π½, Ρ‡Ρ‚ΠΎΠ±Ρ‹ http-server Π½Π΅ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π» скрипты. Π­Ρ‚ΠΎ тСстовый ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Π½Π° Ρ€Π΅Π°Π»ΡŒΠ½ΠΎΠΌ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ nginx.

Π’ΠΎ Vuex store создаСм ΠΏΠΎΠ»Π΅ apiHost: 'http://localhost:3000', Π³Π΄Π΅ прописываСтся ΠΏΠΎΡ€Ρ‚ NodeJS Api. ΠšΠ»ΠΈΠ΅Π½Ρ‚ΡΠΊΠ°Ρ Ρ‡Π°ΡΡ‚ΡŒ Π³ΠΎΡ‚ΠΎΠ²Π°. Π’Π΅ΠΏΠ΅Ρ€ΡŒ всС запросы с ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° Π½Π° бэк ΠΈΠ΄ΡƒΡ‚ Π½Π° этот url.

NodeJS server API

Π’ ΠΏΠ°ΠΏΠΊΠ΅ /server создаСм server.js ΠΈ Dockerfile:


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

Π’ server.js указываСтся url для Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ… const url = 'mongodb://mongo:27017/';. Π Π°Π·Ρ€Π΅ΡˆΠ°Π΅ΠΌ кроссдомСнныС запросы с ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°:


const clientUrl = 'http://localhost:8081';
const corsOptions = {
  origin: clientUrl,
  optionsSuccessStatus: 200, // some legacy browsers (IE11, various SmartTVs) choke on 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));
  });

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΠ΅Ρ€Π΅ΠΉΠ΄Π΅ΠΌ Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π° ΠΈ запустим docker-compose build Π΄Π»ΠΈ построСния ΠΎΠ±Ρ€Π°Π·ΠΎΠ² ΠΈ docker-compose up для запуска ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ². Команда ΠΏΠΎΠ΄Π½ΠΈΠΌΠ΅Ρ‚ 3 ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°: server, client, mongo. Для сСрвСра Π½Π° NodeJS ΠΌΠΎΠΆΠ½ΠΎ Π½Π°ΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ hot-reload, связав Π΅Π³ΠΎ с user ΠΏΠ°ΠΏΠΊΠΎΠΉ. А ΠΊΠ»ΠΈΠ΅Π½Ρ‚ Π² стадии Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ Π·Π°ΠΏΡƒΡΠΊΠ°Ρ‚ΡŒ локально с hot reload, запустив ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎ server ΠΈ mongo. Π§Ρ‚ΠΎΠ±Ρ‹ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ сСрвис, достаточно ΡƒΠΊΠ°Π·Π°Ρ‚ΡŒ Π΅Π³ΠΎ имя docker-compose up client. НС Π·Π°Π±Ρ‹Π²Π°ΠΉΡ‚Π΅ ΠΈΠ½ΠΎΠ³Π΄Π° Π΄Π΅Π»Π°Ρ‚ΡŒ prune ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ² (containers), сСтСй (networks) ΠΈ ΠΎΠ±Ρ€Π°Π·ΠΎΠ² (images), Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹ΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ рСсурсы.

ΠŸΠΎΠ»Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Ρ‚ΡƒΡ‚. ΠŸΡ€ΠΎΠ΅ΠΊΡ‚ Π΅Ρ‰Π΅ Π² стадии Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ.

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com