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 i
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 . 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 . Projekat je još u fazi razvoja.
Izvor: habr.com
