Docker
https://yeasy.gitbooks.io/docker_practice/introduction/what.html
概念
Docker是什么
- 操作系统层面的虚拟化技术
- 隔离的进程独立于宿主和其他的隔离进程-容器
- go语言开发
- 基于Linux的高效、敏捷、轻量级的容器(轻量虚拟)方案。
- Build,Ship and Run Any App,Anywhere — 一次封装,到处执行。
特点
- 高效的利用系统资源
- 快速的启动时间
- 一致的运行环境
- 持续交付和部署
- 更轻松的迁移
核心概念
- 镜像
- 容器
- 仓库
安装docker
- apt升级
apt-get update
- 添加相关软件包
apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
- 下载软件包的合法性,需要添加软件源的 GPG 密钥
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
- source.list 中添加 Docker 软件源
add-apt-repository \
"deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
$(lsb_release -cs) \
stable"
- 安装 Docker CE
apt-get update
apt-get install docker-ce
- 启动 Docker CE
systemctl enable docker
systemctl start docker
- 建立 docker 用户组(附加)
groupadd docker
usermod -aG docker $USER
- Helloworld测试
docker run hello-world
- 查看与删除进程
// 查看进程
docker ps
// 查看全部进程(包括停止的进程)
docker ps -a
// 停止进程
docker stop 775bd130a7f2(CONTAINER ID 前三位即可)
// 删除进程
docker rm CONTAINER ID
添加镜像加速
- 进入根目录
- 进入etc/docker目录
cd etc/docker
vi daemon.js
i
// 复制粘贴
{
"registry-mirrors": [
"https://dockerhub.azk8s.cn",
"https://reg-mirror.qiniu.com"
]
}
esc
:wq
- 重启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基本指令
docker-compose的使用非常类似于docker命令的使用,但是需要注意的是大部分的compose命令都需要到docker-compose.yml文件所在的目录下才能执行。
docker-compose up: 命令聚合每个容器的输出,命令退出时,所有容器都将停止。
docker-compose up -d: 在后台启动容器并使它们保持运行。
docker-compose logs -f: 查看该容器的启动的日志打印(日志从头打印)。
docker logs -f container_id: 查看某一容器的启动的日志打印(日志从头打印)。
docker logs -f --tail 数量词 container_id: 查看某一容器的启动的日志打印(查看最后n条日志打印)。 例:docker logs -f --tail 50 44b
docker-compose stop: 停止compose服务。
docker-compose restart: 重启compose服务。
docker-compose kill: kill compose服务。
docker-compose ps:查看compose服务状态。
docker-compose rm:删除compose服务。
docker-compose.yml配置文件
https://blog.csdn.net/qq_36148847/article/details/79427878
compose集群 nginx + 后端(node)+ 数据库 + vue
- 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;
}
}
- 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
- 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"]
- 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)
})
}
})