ΠΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ½ΡΡΡ ΠΈΠ· ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΉ ΡΡΠ°ΡΡΠΈ, Ρ ΡΠ°Π±ΠΎΡΠ°Π»Π° Ρ ΡΠ°Π·Π½ΡΠΌΠΈ ΠΏΡΠΎΠ΅ΠΊΡΠ°ΠΌΠΈ. ΠΠ΅ΡΠ²ΡΠ΅ Π΄Π½ΠΈ Π² Π½ΠΎΠ²ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Π΅ ΠΎΠ±ΡΡΠ½ΠΎ ΠΏΡΠΎΡ
ΠΎΠ΄ΡΡ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ: Π±ΡΠΊΠ΅Π½Π΄Π΅Ρ ΠΏΠΎΠ΄ΡΠ°ΠΆΠΈΠ²Π°Π΅ΡΡΡ ΠΊΠΎ ΠΌΠ½Π΅ ΠΈ Π²ΡΠΏΠΎΠ»Π½ΡΠ΅Ρ ΠΌΠ°Π³ΠΈΡΠ΅ΡΠΊΠΈΠ΅ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ ΠΏΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ΅ ΠΈ Π΄Π΅ΠΏΠ»ΠΎΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΠΎΠΊΠ΅Ρ Π½Π΅Π·Π°ΠΌΠ΅Π½ΠΈΠΌ Π΄Π»Ρ ΡΡΠΎΠ½ΡΠ΅Π½Π΄Π΅ΡΠΎΠ², Ρ.ΠΊ. Π±ΡΠΊΠ΅Π½Π΄ Π·Π°ΡΠ°ΡΡΡΡ Π½Π°ΠΏΠΈΡΠ°Π½ Π½Π° ΡΠΈΡΠΎΠΊΠΎΠΌ ΡΠΏΠ΅ΠΊΡΡΠ΅ ΡΡΠ΅ΠΊΠΎΠ² PHP/Java/Python/C# ΠΈ ΡΡΠΎΠ½ΡΡ Π½Π΅ Π½Π°Π΄ΠΎ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π· ΠΎΡΠ²Π»Π΅ΠΊΠ°ΡΡ Π±ΡΠΊΠ°, ΡΡΠΎΠ±Ρ Π²ΡΠ΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΈ ΡΠ°Π·Π²Π΅ΡΠ½ΡΡΡ. Π’ΠΎΠ»ΡΠΊΠΎ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΌΠ΅ΡΡΠ΅ Ρ Π²ΠΈΠ΄Π΅Π»Π° ΡΠ²ΡΠ·ΠΊΡ Docker-Jenkins Ρ ΠΏΡΠΎΠ·ΡΠ°ΡΠ½ΡΠΌ Π΄Π΅ΠΏΠ»ΠΎΠ΅ΠΌ, Π»ΠΎΠ³Π°ΠΌΠΈ, ΠΏΡΠΈΠΊΡΡΡΠ΅Π½Π½ΡΠΌΠΈ Π°Π²ΡΠΎΡΠ΅ΡΡΠ°ΠΌΠΈ.
ΠΡΠΎ Π΄ΠΎΠΊΠ΅Ρ Π½Π°ΠΏΠΈΡΠ°Π½ΠΎ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΡΡ
ΡΡΠ°ΡΠ΅ΠΉ. Π ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ΠΉ ΡΠ΅ΡΡ ΠΏΠΎΠΉΠ΄Π΅Ρ ΠΎ ΡΠ°Π·Π²Π΅ΡΡΡΠ²Π°Π½ΠΈΠΈ Single Page Application Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ VueJS/Vue Router, ΡΠ΅ΡΠ²Π΅ΡΠ½Π°Ρ ΡΠ°ΡΡΡ Π² Π²ΠΈΠ΄Π΅ RESTful API c NodeJS, Π° Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π±Π°Π·Ρ Π΄Π°Π½Π½ΡΡ
ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ MongoDB. ΠΠ»Ρ ΠΎΠΏΠΈΡΠ°Π½ΠΈΡ ΠΈ Π·Π°ΠΏΡΡΠΊΠ° Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΈΡ
ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ-ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Docker Compose.
ΠΠ°ΡΠ΅ΠΌ Π½ΡΠΆΠ΅Π½ ΠΠΎΠΊΠ΅Ρ
ΠΠΎΠΊΠ΅Ρ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΠ·ΠΈΡΠΎΠ²Π°ΡΡ ΠΏΡΠΎΡΠ΅ΡΡ ΡΠ°Π·Π²ΠΎΡΠ°ΡΠΈΠ²Π°Π½ΠΈΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. Π Π°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΡ Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ Π½ΡΠΆΠ½ΠΎ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°ΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, Π±ΠΎΡΠΎΡΡΡΡ Ρ Π½Π΅ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΠΎΡΡΡΡ Π²Π΅ΡΡΠΈΠΉ Π½Π° ΡΠ²ΠΎΠ΅ΠΉ ΠΌΠ°ΡΠΈΠ½Π΅. ΠΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΠΎΠΊΠ΅Ρ ΠΈ Π²Π±ΠΈΡΡ 1-2 ΠΊΠΎΠΌΠ°Π½Π΄Ρ Π² ΠΊΠΎΠ½ΡΠΎΠ»Ρ. Π£Π΄ΠΎΠ±Π½Π΅Π΅ Π²ΡΠ΅Π³ΠΎ Π΄Π΅Π»Π°ΡΡ ΡΡΠΎ Π½Π° Linux.
Getting started
Π£ΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ
Π‘ΡΡΡΠΊΡΡΡΠ° ΠΏΠ°ΠΏΠΎΠΊ
Π‘ΠΎΠ·Π΄Π°Π΅ΠΌ 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, Π·Π°ΠΏΡΡΡΠΈΠ² ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎ server ΠΈ mongo. Π§ΡΠΎΠ±Ρ Π·Π°ΠΏΡΡΡΠΈΡΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΉ ΡΠ΅ΡΠ²ΠΈΡ, Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π΅Π³ΠΎ ΠΈΠΌΡ docker-compose up client
. ΠΠ΅ Π·Π°Π±ΡΠ²Π°ΠΉΡΠ΅ ΠΈΠ½ΠΎΠ³Π΄Π° Π΄Π΅Π»Π°ΡΡ prune
ΠΈ ΡΠ΄Π°Π»Π΅Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠΎΠ² (containers), ΡΠ΅ΡΠ΅ΠΉ (networks) ΠΈ ΠΎΠ±ΡΠ°Π·ΠΎΠ² (images), ΡΡΠΎΠ±Ρ Π²ΡΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡΡ ΡΠ΅ΡΡΡΡΡ.
ΠΠΎΠ»Π½ΡΠΉ ΠΊΠΎΠ΄ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡΡΠ΅ΡΡ
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com