docker+webhooks持续集成

Docker

https://yeasy.gitbooks.io/docker_practice/introduction/what.html

概念

Docker是什么

  • 操作系统层面的虚拟化技术
  • 隔离的进程独立于宿主和其他的隔离进程-容器
  • go语言开发
  • 基于Linux的高效、敏捷、轻量级的容器(轻量虚拟)方案。
  • Build,Ship and Run Any App,Anywhere — 一次封装,到处执行。

特点

  • 高效的利用系统资源
  • 快速的启动时间
  • 一致的运行环境
  • 持续交付和部署
  • 更轻松的迁移

核心概念

  • 镜像
  • 容器
  • 仓库

安装docker

  1. apt升级
apt-get update
  1. 添加相关软件包
apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
  1. 下载软件包的合法性,需要添加软件源的 GPG 密钥
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
  1. source.list 中添加 Docker 软件源
add-apt-repository \
"deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
$(lsb_release -cs) \
stable"
  1. 安装 Docker CE
apt-get update
apt-get install docker-ce
  1. 启动 Docker CE
systemctl enable docker
systemctl start docker
  1. 建立 docker 用户组(附加)
groupadd docker
usermod -aG docker $USER
  1. Helloworld测试
docker run hello-world
  1. 查看与删除进程
// 查看进程
docker ps
// 查看全部进程(包括停止的进程)
docker ps -a
// 停止进程
docker stop 775bd130a7f2(CONTAINER ID 前三位即可)
// 删除进程
docker rm CONTAINER ID 

添加镜像加速

  1. 进入根目录
  2. 进入etc/docker目录
cd etc/docker
vi daemon.js
i
// 复制粘贴
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://reg-mirror.qiniu.com"
]
}
esc
:wq
  1. 重启docker
sudo systemctl daemon-reload
sudo systemctl restart docker

Dockerfile定制镜像

镜像的定制实际上就是定制每一层所添加的配置、文件。如果我们可以把每一层修改、安装、构建、操作的
命令都写入一个脚本,用这个脚本来构建、定制镜像,那么之前提及的无法重复的问题、镜像构建透明性的
问题、体积的问题就都会解决。这个脚本就是 Dockerfile。

例:定制一个node.js镜像

#Dockerfile
#制定node镜像的版本
FROM node:10-alpine
#移动当前目录下面的文件到app目录下
ADD . /app/
#进入到app目录下面,类似cd
WORKDIR /app
#安装依赖
RUN npm install
#对外暴露的端口
EXPOSE 3000
#程序启动脚本
CMD ["node", "app.js"]
# 定制镜像
docker build -t mynode .
# 运行
docker run -p 3000:3000 -d mynode

常用命令解释:

  • FROM:
    格式为FROM image或FROM image:tag,并且Dockerfile中第一条指令必须是FROM指令,且在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令
  • RUN:
    RUN命令,指定镜像中运行的命令,包含两种模式。
    格式为RUN command或 RUN ["EXECUTABLE","PARAM1","PARAM2".....],前者在shell终端中运行命令,/bin/sh -c command,例如:/bin/sh -c "echo hello";后者使用exec执行,指定其他运行终端使用RUN["/bin/bash","-c","echo hello"]
    每条RUN指令将当前的镜像基础上执行指令,并提交为新的镜像,命令较长的时候可以使用\来换行。组合指令可以使用&&进行组合
  • ADD & COPY
    COPY和ADD命令,将目录或文件复制镜像中,两者区别是ADD包含了类似tar的解压缩功能,如果只是目录或文件复制,推荐使用COPY。复制目录时需要’/‘结尾,目录不存在会自动创建。
    DOCKERFILECOPY
    ADD
    ++src表示来源地址,可以是本地或网络地址,如果是本地地址,必须是镜像的相对地址(dockerfile为参考路劲)。++
    ++dest表示将文件复制到镜像目标地址,必须是绝对路径。++
  • WORKDIR
    格式: WORKDIR /path
    为后续的RUN CMD ENTRYPOINT指定配置工作目录,可以使用多个WORKDIR指令,若后续指令用得是相对路径,则会基于之前的命令指定路径
  • CMD
    支持三种格式:
    CMD ["executable","param1","param2"],使用exec执行,这是推荐的方式。
    CMD command param1 param2 在/bin/sh中执行。
    CMD ["param1","param2"] 提供给ENTERYPOINT的默认参数。
    CMD用于指定容器启动时执行的命令,每个Dockerfile只能有一个CMD命令,多个CMD命令只执行最后一个。若容器启动时指定了运行的命令,则会覆盖掉CMD中指定的命令。

镜像的查看与删除

//查看镜像
docker images
//删除镜像
docker rmi IMAGE ID

pm2

https://www.cnblogs.com/wangcp-2014/p/10874417.html

PM2是node进程管理工具,可以利用它来简化很多node应用管理的繁琐任务,如性能监控、自动重启、负载均衡等,而且使用非常简单。

安装

全局安装npm install -g pm2

常用指令

  • 启动:pm2 start app.js --watch
    --watch:监听应用目录的变化,一旦发生变化,自动重启。如果要精确监听、不见听的目录,最好通过配置文件。
  • 重启:pm2 restart app.js
  • 停止:pm2 stop app_name|app_id
    停止特定的应用。可以先通过pm2 list获取应用的名字(--name指定的)或者进程id。
  • 停止所有应用:pm2 stop all
  • 删除:pm2 stop app_name|app_id
  • 删除全部:pm2 stop all
  • 查看进程状态:pm2 list

配置文件

  • 配置文件里的设置项,跟命令行参数基本是一一对应的。
  • 可以选择yaml或者json文件,就看个人洗好了。
  • json格式的配置文件,pm2当作普通的js文件来处理,所以可以在里面添加注释或者编写代码,这对于动态调整配置很有好处。
  • 如果启动的时候指定了配置文件,那么命令行参数会被忽略。(个别参数除外,比如--env)
    推荐使用yml格式
// json例子
{
 
    "name" : "fis-receiver", // 应用名称
     
    "script" : "./bin/www", // 实际启动脚本
     
    "cwd" : "./", // 当前工作路径
     
    "watch": [ // 监控变化的目录,一旦变化,自动重启
     
        "bin",
     
        "routers"
     
    ],
     
    "ignore_watch" : [ // 从监控目录中排除
     
        "node_modules",
         
        "logs",
         
        "public"
     
    ],
     
    "watch_options": {
     
        "followSymlinks": false
     
    },
     
    "error_file" : "./logs/app-err.log", // 错误日志路径
     
    "out_file" : "./logs/app-out.log", // 普通日志路径
     
    "env": {
     
        "NODE_ENV": "production" // 环境参数,当前指定为生产环境
     
    }
 
}

定制node的Dockerfile镜像配合pm2

// Dockerfile
FROM keymetrics/pm2:latest-alpine
WORKDIR /usr/src/app
ADD . /usr/src/app
RUN npm config set registry https://registry.npm.taobao.org/ && \  
    npm i
# RUN npm i
EXPOSE 3000
#pm2在docker中使用命令为pm2-docker
# CMD ["pm2-runtime", "start", "--json", "process.json"]
CMD ["pm2-runtime", "start",  "process.yml"]
// process.yml
apps:
  - script : server.js
    instances: 2
    watch  : true
    env    :
      NODE_ENV: production

docker-compose

Compose项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。

例:

#docker-compose.yml
version: '3.1'
services:
mongo:
    image: mongo
    restart: always
    ports:
        - 27017:27017
mongo-express:
    image: mongo-express
    restart: always
    ports:
        - 8000:8081

docker-compose基本指令

  1. docker-compose的使用非常类似于docker命令的使用,但是需要注意的是大部分的compose命令都需要到docker-compose.yml文件所在的目录下才能执行。

  2. docker-compose up: 命令聚合每个容器的输出,命令退出时,所有容器都将停止。

  3. docker-compose up -d: 在后台启动容器并使它们保持运行。

  4. docker-compose logs -f: 查看该容器的启动的日志打印(日志从头打印)。

  5. docker logs -f container_id: 查看某一容器的启动的日志打印(日志从头打印)。

  6. docker logs -f --tail 数量词 container_id: 查看某一容器的启动的日志打印(查看最后n条日志打印)。 例:docker logs -f --tail 50 44b

  7. docker-compose stop: 停止compose服务。

  8. docker-compose restart: 重启compose服务。

  9. docker-compose kill: kill compose服务。

  10. docker-compose ps:查看compose服务状态。

  11. docker-compose rm:删除compose服务。

docker-compose.yml配置文件

https://blog.csdn.net/qq_36148847/article/details/79427878

compose集群 nginx + 后端(node)+ 数据库 + vue

  1. nginx(nginx/conf/docker.conf)
server {
    listen 80;
    location / {
        root /var/www/html;
        index index.html index.htm;
    }
    location ~ \.(gif|jpg|png)$ {
        root /static;
        index index.html index.htm;
    }
}
  1. node配置Dockerfile+pm2
    (backend/Dockerfile)
FROM keymetrics/pm2:latest-alpine
WORKDIR /usr/src/app
ADD . /usr/src/app
RUN npm config set registry https://registry.npm.taobao.org/ && \  
    npm i
# RUN npm i
EXPOSE 3000
#pm2在docker中使用命令为pm2-docker
# CMD ["pm2-runtime", "start", "--json", "process.json"]
CMD ["pm2-runtime", "start",  "process.yml"]

构建进项中忽略文件夹或文件的配置文件(backend/.dockerignore)

node_modules

(backend/process.yml)

apps:
  - script : server.js
    instances: 2
    watch  : true
    env    :
      NODE_ENV: production
  1. vue配置Dockerfile(web/Dockerfile)
FROM node:10-alpine
WORKDIR /usr/src/app
ADD . /usr/src/app
# Npm
RUN npm config set registry https://registry.npm.taobao.org/ &&  \
   npm i
#执行构建
CMD ["npm", "run", "build"]


  1. compose(docker-compose.yml)
version: '3.1'
services:
    nginx:
    restart: always
    image: nginx
    ports:
        - 8091:80
    volumes:
        - ./nginx/conf.d/:/etc/nginx/conf.d
        - ./frontend/dist:/var/www/html/
        - ./static/:/static/
    app-pm2:
        container_name: app-pm2
        #构建容器
        build: ./backend
        ports:
            - "3000:3000"
    web:
        container_name: web
        #构建容器
        build: ./web
        volumes:
            - ./web/dist:/usr/src/app/dist
        depends_on:
            - app-pm2
    mongo:
        image: mongo
        restart: always
        ports:
            - 27017:27017
    mongo-express:
        image: mongo-express
        restart: always
        ports:
            - 8000:8081

Github WebHook实现CI持续集成

在服务器上开放一个接口,当github接收到push请求后,请求这个接口,接口响应到以后,执行docker-compose

启动node监听

const http = require('http')
const createHandler = require('github-webhook-handler')
// path和secret要和github的webhooks配置一致
const handler = createHandler({
    path:'/docker_deploy',
    secret:'myHashSecret'
})

const { spawn } = require('child_process')
function run_cmd(cmd, args, callback) {
    const child = spawn(cmd, args)
    let resp = ''
    child.stdout.on('data', function (buffer) {
        resp+=buffer.toString()
    })
    child.stdout.on('end', function () {
        callback(resp)
    })
}

http.createServer((req,res) => {
    handler(req,res,err => {
    res.statusCode = 404
res.end('no such location')
})
}).listen(7777, () => {
    console.log('Webhook listen at 7777')
})
handler.on('error',err => {
    console.error('Error',err.message)
})
handler.on('push',event => {
    console.log('Received * ',event.payload.ref)
// console.log('Received * ')
if (event.payload.ref === 'refs/heads/master') {
    console.log('Receive push')
    run_cmd('sh', ['./deploy-dev.sh'], function (text) {
        console.log(text)
    })
}
})

你可能感兴趣的:(docker+webhooks持续集成)