Azure的ASE内部有ILB,其通过health check,其实就是Ping site,如果没有反应,会在5分钟后自动重启。
其实后来咨询MS的人,这个测试本身方向不对,因为azure 的ASE不会根据http status code进行重启,error code 是根据业务内容定下的,原先这个功能有,最新的version 中这个功能去掉了。对于200,500的错误会进行重启(LB)container,但仅仅处理health check 中ping 的URL部分,不会进行整个container的重启。(->要确认)
不过这个测试本身有关于nodejs 的container 的内容,所以想试一下,就继续下去。
server.js
'use strict';
// Constants
const PORT = 8080;
const HOST = '0.0.0.0';
const Joi = require('joi');
const express = require('express');
const app = express();
app.use(express.json());
const courses = [
{ id: 1, name: 'course1'},
{ id: 2, name: 'course2'},
{ id: 3, name: 'course3'}
];
app.get('/', (req, res) => {
res.send('Hello World!!!');
});
app.get('/api/courses', (req, res) => {
res.send(courses);
});
app.get('/api/courses/:id', (req,res) => {
//res.send(courses[req.params.id -1]);
const course = courses.find(c => c.id === parseInt(req.params.id));
if(!course) return res.status(404).send('The course with the id couldnot be found');
res.send(course);
});
app.post('/api/courses', (req, res) => {
const { error } = validateCourse(req.body);
if(error) {
res.status(400).send(error.details[0].message);
return;
}
if(!req.body.name || req.body.name.length < 3) {
res.status(400).send('Name is required and should be minimum 3 characters...');
return;
}
const course = {
id: courses.length + 1,
name: req.body.name
};
courses.push(course);
res.send(course);
});
app.put('/api/courses/:id', (req,res) => {
const course = courses.find(c => c.id === parseInt(req.params.id));
if(!course) return res.status(404).send('The course with the id couldnot be found.');
const { error } = validateCourse(req.body);
if(error) {
res.status(400).send(error.details[0].message);
return;
}
//update
course.name = req.body.name;
//return
res.send(course);
});
app.delete('/api/courses/:id',(req,res) => {
const course = courses.find(c => c.id === parseInt(req.params.id));
if(!course) return res.status(404).send('The course with the id couldnot be found.');
const index = courses.indexOf(course);
courses.splice(index, 1);
res.send(course);
});
// PORT
app.listen(PORT, HOST);
console.log(`Running on http://${HOST}:${PORT}`);
function validateCourse(course) {
const schema = {
name: Joi.string().min(3).required()
};
return Joi.validate(course, schema);
}
package.json:
{
"name": "docker_web_app",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "First Last <first.last@example.com>",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.17.1",
"joi": "^17.3.0"
}
}
Dockerfile:
FROM node:12
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./
RUN npm install
# If you are building your code for production
# RUN npm ci --only=production
# Bundle app source
COPY . .
EXPOSE 8080
CMD [ "node", "server.js" ]
创建docker image之前需要事先执行以下命令:
npm install
npm install express --save
npm install joi --save
以上install express, 和 joi 都需要加上save 的参数,这样docker image 中会保留这个package 依赖.
不过为了测试这里故意保留了joi 后面没有用--save,这样在postman做测试的时候产生500 error(Internal server error)
另外加上 .dockerignore:
node_modules
npm-debug.log
执行:
docker build -t <your acr server>/<node app image name>:<tag> .
这里要注意的是,因为是要deploy到azure上,所以image的name 是一定要用ACR server name,并且要提前login 到你的ACRserver上。
image 做好后,本地run 一下,确认正确:
docker run -p 49160:8080 -d <your acr server>/<node app image name>:<tag>
然后push到ACR上,然后是从ACR的image 开始create web app container
在deploy的时候startup command 什么都不需要填写,Azure 会自动分配,而且deploy之后也不需要指定port, 就和所有的website一样access
测试
- chrome 端 install postman 的plugin 插件,查看http status code
- 设置好log,观察一下是否有重启的log
网友评论