Як можна зразумець з папярэдняга артыкула, я працавала з рознымі праектамі. Першыя дні ў новай камандзе звычайна праходзяць аднолькава: бэкендэр падсаджваецца да мяне і выконвае магічныя дзеянні па ўстаноўцы і дэплою прыкладання. Докер незаменны для франтэндэраў, т.я. бэкэнд часцяком напісаны на шырокім спектры стэкаў PHP/Java/Python/C# і фронту не трэба кожны раз адцягваць бэка, каб усё ўсталяваць і разгарнуць. Толькі ў адным месцы я бачыла звязку Docker-Jenkins з празрыстым дэплоем, логамі, прыкручанымі аўтатэстамі.
Пра докер напісана шмат падрабязных артыкулаў. У гэтым артыкуле прамова пайдзе аб разгортванні Single Page Application з выкарыстаннем VueJS/Vue Router, серверная частка ў выглядзе RESTful API c NodeJS, а ў якасці базы дадзеных выкарыстоўваецца MongoDB. Для апісання і запуску некалькіх прыкладанняў-кантэйнераў выкарыстоўваецца Docker Compose.
Навошта патрэбен Докер
Докер дазваляе аўтаматызаваць працэс разгортвання прыкладання. Распрацоўніку больш не трэба самастойна ўсталёўваць праграмы, дужацца з несумяшчальнасцю версій на сваёй машыне. Дастаткова ўсталяваць Докер і ўбіць 1/2 каманды ў кансоль. Зручней за ўсё рабіць гэта на Linux.
Прыступаючы да працы
Усталёўваны
Структура тэчак
Ствараем 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. Прыкладанне створана з дапамогай
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, запусціўшы асобна сервер и Монго. Каб запусціць асобны сэрвіс, дастаткова пазначыць яго імя docker-compose up client
. Не забывайце часам рабіць prune
і выдаленне кантэйнераў (containers), сетак (networks) і вобразаў (images), каб вызваліць рэсурсы.
Поўны код можна паглядзець
Крыніца: habr.com