先说一下我为什么要做这个事情
最近手里的项目版本迭代非常多,然后每次都要重新部署,真的非常非常非常麻烦,所有想做一下这样的一些自动化部署功能,应该算是一个迫切的小需求。。。。。
Docker是什么
- 操作系统层面的虚拟化技术
- 是一个容器独立于宿主和其他进程
特点
- 比传统虚拟机占用更少的系统资源
- 比传统虚拟机启动速度快
- 持续交付和部署(这个是我主要想做的,因为我们的项目部署非常频繁)
- 更轻松的迁移
核心概念
- 镜像
- 容器
- 仓库
Docker安装(因为我们的服务是linux,这里的安装主要是linux,windows安装,mac安装教程)
1. 先查看CentOS版本,Docker要求内核版本高于 3.10
uname -r
2. 更新yum包
sudo yum update
3. 安装需要的包
// yum-utils提供yum-config-manager功能
// device-mapper-persistent-data lvm2是devicemapper驱动依赖的
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
4. 添加软件源信息
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
5. 查看可用版本的 Docker-ce
yum list docker-ce --showduplicates | sort -r
// 如果需要只显示table版本,可以关闭测试版本的list
sudo yum-config-manager --enable docker-ce-edge
sudo yum-config-manager --enable docker-ce-test
6. 安装指定版本的docker-ce
sudo yum install docker-ce-18.06.3.ce-3.el7
7. 设置开机启动
// 添加docker服务
sudo systemctl enable docker
// 启动docker服务
sudo systemctl start docker
8. 验证安装是否成功(有client和service两部分表示docker安装启动都成功了)
docker version
9. docker启动状态
systemctl status docker
10. 配置镜像加速
- Azure中国镜像 dockerhub.azk8s.cn
- 七牛云加速器 reg-mirror.qiniu.com
// 创建daemon.json
vi /etc/docker/daemon.json
// 配置/etc/docker/daemon.json
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://reg-mirror.qiniu.com"
]
}
// 重启docker服务,让它生效
sudo systemctl daemon-reload
sudo systemctl restart docker
11. 下载一个nginx测试一下快不快
docker pull nginx
======================= 安装就结束了 =======================
Nginx服务
1. 拉取官方镜像 - 面向docker的只读模板(之前测试docker镜像的时候已经做了就不需要了)
docker pull nginx
2. 查看安装结果
docker images nginx
3. 创建一个index.html并写入hello docker!!
mkdir www
echo 'hello docker!!' >> www/index.html
4. 查看index.html内容
cat www/index.html
5. 启动并映射端口
docker run -p 8000:80 -v $PWD/www:/usr/share/nginx/html nginx
6. 在页面输入ip和端口,就会显示index里面的内容。
7. 后台执行(这句执行后会给你一个uuid,关闭服务的时候可以使用)
docker run -p 8000:80 -v $PWD/www:/usr/share/nginx/html -d nginx
8. 停止服务
// 这个050是上面后台启动的时候返回的uuid的前三位
docker stop 050
// 如果想重新启动的话
docker start 050
9. 查看进程
//查看进程
docker ps
// 查看全部进程
docker ps -a
10. 伪终端 050容器的uuid
docker exec -it 050 /bin/bash
11. 在伪终端去查看之前创建的index.html
cd /usr/share/nginx/html
cat index.html
12. 退出伪终端
exit
12. 删除镜像
// 先关闭docker服务
docker stop 050
// 删除
docker rm 050
===================== 启动一个简单的nginx服务就完成了 ====================
Docker运行过程
1. 镜像(Image) -----面向Docker的只读模板
2. 容器(Container) ------镜像的运行实例
3. 仓库 (Registry) ------存储镜像的服务器
============================ 华丽的分割线 ============================
Dockerfile 定制镜像
1. 创建一个nginx
cd docker
mkdir nginx
2. 创建一个Dockerfile文件,写入配置
cd nginx
vi Dockerfile
// Dockerfile文件
FROM nginx:latest
RUN echo '<h1>Hello, candy!</h1>' > /usr/share/nginx/html/index.html
3. 定制镜像
// nginx镜像,版本为candy
// 注意: 最后面.的意思是当前目录下的文件,也就是Dockerfile文件
docker build -t nginx:candy .
4. 运行
// 指定candy这个版本
docker run -p 8000:80 nginx:candy
============================ 华丽的分割线 ============================
定制PM2镜像
Pm2 - 利用多核资源
1. 创建一个pm2文件夹
mkdir pm2
2. 创建package.json
npm init -y
3. 创建一个简单的程序---app.js
vi app.js
4. app.js随便写一点内容
const Koa = require('koa')
const app = new Koa()
app.use(ctx => {
Math.random() > 0.8 ? abc() : ''
ctx.body = 'Hello Docker'
})
app.listen(3000, () => {
console.log('app started at http://localhost:3000/')
})
5. 创建process.yml文件
vi process.yml
6. process.yml
apps:
- script : app.js
instances: 2
watch : true
env :
NODE_ENV: production
7. 定制Dockerfile
vi Dockerfile
8. 编辑Dockerfile
# 制定pm2镜像的版本
FROM keymetrics/pm2:latest-alpine
#进入到app目录下面,类似cd
WORKDIR /usr/src/app
#移动当前目录下面的文件到app目录下
ADD . /usr/src/app
#设置淘宝镜像并安装依赖
RUN npm config set registry https://registry.npm.taobao.org/ && \
npm i
#对外暴露的端口
EXPOSE 3000
#pm2在docker中使用命令为pm2-docker
CMD ["pm2-runtime", "start", "process.yml"]
9. 运行定制
docker build -t pm2 .
10. 运行docker
docker run -p 3000:3000 pm2
11. 后台启动
docker run -p 3000:3000 -d pm2
12. 关闭
docker stop a06
============================ 华丽的分割线 ============================
Docker Compose "批处理"
- 负责实现对 Docker 容器集群的快速编排(如果有好几个docker,想一起工作,这时候可以用Docker Compose)
- Docker Compose 是一个工具,命令行工具。
- 这个工具可以通过yml文件定义多容器的docker应用
- 通过一条命令就可以根据yml文件的定义去创建或者管理这多个容器
1. 安装docker-compose
yum install docker-compose
2. 新建一个文件夹
mkdir helloworld
cd helloworld
3. 新建docker-compose.yml
version: '3.1'
services:
hello-world:
image: hello-world
4. 启动
docker-compose up
5. 解析一下参数
# docker-compose.yml
# docker-compose的版本
version: '3.1'
# 有几个镜像要启动就配置到services下面
services:
mongo:
image: mongo
# 如果死机的话,会一直尝试重启
restart: always
# 映射端口
ports:
- 27017:27017
mongo-express:
image: mongo-express
restart: always
ports:
- 8000:8081
实战nginx----docker部署一个前后端分离的项目
1. 在根目录把本地代码同步到服务器上
-
我的编辑器是用的webstorm,所以使用了它自带的插件Deployment
-
编辑配置文件
!
-
编辑映射信息
-
编辑忽略文件(划重点,,一定要把node_modules忽略,否则极容易上传不成功,我最开始的时候就是这里没有配置,卡这里好一会)
-
选中需要的文件,右键就可以同步到服务器啦
2.在根目录nginx/conf.d/docker.conf,配置端口,路径,代理服务
server {
listen 80;
location / {
root /var/www/html;
index index.html index.htm;
}
location /cds {
proxy_pass http://192.168.0.210:9008/cds;
proxy_redirect off;
proxy_cookie_path / "/; httponly; SameSite=Lax";
}
}
3.在根目录创建docker-compose.yml对所有项目集群
version: '3.1'
services:
nginx:
restart: always
image: nginx
ports:
- 3000:80
volumes:
- ./nginx/conf.d/:/etc/nginx/conf.d
- ./hellowVue/dist:/var/www/html/
4. 对前端项目执行build并Deployment同步到服务商
5. 启动服务
docker-compose up -d
============================ 未完待续 ============================
到这里其实已经部署好项目了,明天会持续更新自动化执行的脚本文件让每次本地build的时候,自动更新代码并重启服务。
webhook实现持续集成
1. 概念
webhook与异步编程中"订阅-发布模型"非常类似,一端触发事件,一端监听执行。就是我本地代码更改,执行某些操作的时候,服务端代码也自动更新,并执行一些自定义脚本,比如我push的时候,服务器自动pull代码并更新重启
2. 线上配置
- 登录github,或者gitlab,我的项目是在gitlab上所以以这个为例
2. 本地根目录下新建一个webhooks.js
var http = require('http')
// 注意,如果你是github的话,应该是require('github-webhook-handler')
var createHandler = require('gitlab-webhook-handler')
var handler = createHandler({ path: '/webhooks', secret: 'zjcds123456' })
// 上面的 secret 保持和 GitHub 后台设置的一致
function run_cmd(cmd, args, callback) {
var spawn = require('child_process').spawn;
var child = spawn(cmd, args);
var resp = "";
child.stdout.on('data', function (buffer) { resp += buffer.toString(); });
child.stdout.on('end', function () { callback(resp) });
}
// debug用
// run_cmd('sh', ['./deploy-dev.sh'], function(text){ console.log(text) });
http.createServer(function (req, res) {
handler(req, res, function (err) {
res.statusCode = 404
res.end('no such location')
})
}).listen(3000,() =>{
console.log('WebHooks Listern at 3000');
})
handler.on('error', function (err) {
console.error('Error:', err.message)
})
// handler.on('*', function (event) {
// console.log('Received *', event.payload.action);
// // run_cmd('sh', ['./deploy-dev.sh'], function(text){ console.log(text) });
// })
handler.on('push', function (event) {
console.log('Received a push event for %s to %s',
event.payload.repository.name,
event.payload.ref);
// 分支判断
if(event.payload.ref === 'refs/heads/master'){
console.log('deploy master..')
run_cmd('sh', ['./deploy-dev.sh'], function(text){ console.log(text) });
}
})
// handler.on('issues', function (event) {
// console.log('Received an issue event for % action=%s: #%d %s',
// event.payload.repository.name,
// event.payload.action,
// event.payload.issue.number,
// event.payload.issue.title)
// })
4. 根目录下新建一个脚本文件deploy-dev.sh
echo Deploy Project
# docker-compose up -d --force-recreate --build
# 获取最新版代码
git pull
# 强制重新编译容器
docker-compose down
docker-compose up -d --force-recreate --build
# 定制镜像
# docker build -t myapp:pm2 ./backend
# 重启启动容器
# docker stop myapp
# docker rm myapp
# docker run --name myapp -p 3000:3000 -d myapp:pm2
5. 同样Deployment一下,发送到服务器
6. 起一个服务运行一下webhooks.js,这样就能监听到你每次的push操作啦
node webhooks.js
=============到这里每次push的时候就会自动更新服务部署啦==================