Zeno Tian


  • 首页

  • 归档

  • 标签

docker中运行mongoDB

发表于 2017-09-11

在docker中使用MongoDB

通过Docker运行Mongo

1
docker run --name [name] -p 27017:27017 -v /data/db:/data/db -d mongo
  • -v/data/db:/data/db 将主机的/data/db文件夹挂载在容器内的/data/db

    在docker容器中运行MongoDB所产生的数据会保存在容器内部,容器停止后数据也将随之消失无法得到保存。所以为了将容器中的数据持久化,需要使用docker的数据卷,将主机上的文件夹映射到容器内部。这样容器运行时所产生的数据将会保存在主机的文件中。

    NOTE: mac os 需要在Docker -> Preferences… -> File Sharing中添加共享的目录
  • -p 27017:27017将容器内mongo的默认27017端口映射至主机的27017端口

  • -d后台运行

  • —auth开启Mongo的验证

进入Mongo shell

在主机上进入

1
docker exec -it <YOUR-NAME> mongo

设置管理员/用户

1
2
3
4
5
{
user:'testUser
pwd:'testPass',
roles:[{role:'readWrite',db:'test'}]
}

验证

通过本地mongo shell 连接远程服务器的mongoDB

1
mongo xx.xx.xx.xx:xxx/test -u "admin" -p "adminPass"
问题

在阿里云上通过docker运行mongo,在本地使用mongo尝试连接,连接不上

1
2
3
4
5
6
7
MongoDB shell version v3.4.0
connecting to: mongodb://xx.xx.xx.xx:xxxx
2017-09-08T16:16:28.584+0800 W NETWORK [main] Failed to connect to 47.52.30.225:25714 after 5000 milliseconds, giving up.
2017-09-08T16:16:28.587+0800 E QUERY [main] Error: couldn't connect to server xx.xx.xx.xx:xxxx, connection attempt failed :
connect@src/mongo/shell/mongo.js:234:13
@(connect):1:6
exception: connect failed
解决

在本地连接不上远程的数据库是因为我将docker端口和服务器端口映射写反了。

出现类似的问题应该如何排查

  1. 检查端口号配置
  2. 检查账号密码设置
  3. 检查阿里云安全组设置

购买的云主机服务,初始的时候除了ssh外的端口,所有对外的端口都是被屏蔽的。需要去手动去阿里云的安全组中将需要用到的端口配置打开,在外网才能访问

未命名

发表于 2017-09-07

Docker中的数据管理

数据卷

特性:

  • 数据卷可以在容器之间共享和重用
  • 对数据卷的修改会立马生效
  • 对数据卷的更新,不会影响镜像
  • 数据卷默认会一直存在,即使容器被删除

作用:持久化数据

创建与挂载:

通过docker run的-v参数

示例:

创建一个数据卷
1
docker run -d -P --name web -v /webapp

加载一个数据卷到容器的 /webapp 目录

挂载主机目录作为数据卷
1
2
docker run -d -P --name web -v /src/webapp:/opt/webapp
#挂载主机目录作为数据卷

加载主机的src/webapp目录到容器的opt/webapp

Note:Dockerfile中不支持这种写法,因为不同系统路径格式不一样
挂载本地文件作为数据卷
1
sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash

删除数据卷

删除容器的时候使用 docker rm -v

查看数据卷具体信息

1
docker inspect [name]

默认数据卷创建在/var/lib/docker/volumes/下面

数据卷容器

作用:

持续更新的数据在容器之间共享

本质上就是一个容器,专门用来提供数据卷供其他容器挂载

​

未命名

发表于 2017-09-07

当你的MongoDB数据库在本地使用时不需要账号密码没问题,但是当部署到服务器时是不能没有身份验证的。今天学习MongoDB用户配置,在此稍作记录。

MongoDB中的用户类型/user

常用MongDB的用户类型

  • 超级管理员:拥有最高权限,可以对任何数据库进行任意操作
  • 管理员用户:拥有当前数据库最高权限,可以对当前库进行任意操作
  • 数据库用户:只拥有对当前数据库数据的读写权利

MongoDB中的角色/权限/role

创建用户的时候需要指定用户的对于某个数据库是什么角色

可以理解为对某个数据库的权限设置

Read:允许用户读取指定数据库

readWrite:允许用户读写指定数据库

dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile

userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户

clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。

readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限

readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限

userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限

dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。

root:只在admin数据库中可用。超级账号,超级权限

用户相关的方法

https://docs.mongodb.com/manual/core/security-users/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#添加用户:
db.createUser({
user: "<name>", //用户名
pwd: "<cleartext password>",
customData: { <any information> }, //可选的,备注信息。
roles: [
{ role: "<role>", db: "<database>" } | "<role>", //指定角色
...
]},
writeConcern: { <write concern> }
)
#更改用户信息:将会覆盖掉原先的用户信息
root(
"<username>",
{
customData : { <any information> },
roles : [
{ role: "<role>", db: "<database>" } | "<role>",
...
],
pwd: "<cleartext password>"
},
writeConcern: { <write concern> }
)

用户验证登陆的两种方式

注意点:验证的用户的时候,必须在该用户创建的数据库验证
1
2
mongod --auth
#开启验证
1.连接数据库时验证

权限验证一定要在建立该账户的数据库上进行

1
mongo xx.xx.xx.xx:xxx/test -u "admin" -p "adminPass"
2.连接之后再进行验证
1
2
3
4
mongo --port 27017
use admin
db.auth("admin", "adminPass")

实践

1.创建超级管理员用户

1
sudo mongod --logpath=./log/log.log # 启动mongoDB
1
2
3
4
5
6
7
8
9
10
11
12
mongo
#进入mongo shell
use admin
#切换到admin数据库
db.system.users.find()
#可以查看下admin下用户,默认应该是没有数据的
db.createUser({
user:'admin',
pwd:'adminPass',
roles:['root']
})
Successfully added user: { "user" : "admin", "roles" : [ "root" ] }

###

docker基本使用

发表于 2017-09-06

以下的命令有的需要root权限,如果报错请使用root,或加sudo

1、添加yum源。

1
2
yum install epel-release –y
yum clean all# yum list

2、安装并运行Docker。

1
2
yum install docker-io –y
systemctl start docker

3、检查安装结果。

1
docker info

出现以下xin说明信息则表明安装成功。

2

docker基本用法

1、Docker守护进程管理。

1
2
3
systemctl start docker #运行Docker守护进程
systemctl stop docker #停止Docker守护进程
systemctl restart docker #重启Docker守护进程

2、镜像管理。

下载基础镜像,具体操作可参考如何下载docker镜像,本文使用的是来自阿里云仓库的Apache镜像。您可在阿里云docker市场搜索更多镜像。

1
# docker pull registry.cn-hangzhou.aliyuncs.com/lxepoo/apache-php5

修改标签,由于阿里云仓库镜像的镜像名称很长,可以修改镜像标签以便记忆区分。

1
# docker tag registry.cn-hangzhou.aliyuncs.com/lxepoo/apache-php5:latest aliweb:v1

查看已有镜像。

1
# docker images

强制删除镜像。

1
# docker rmi –f registry.cn-hangzhou.aliyuncs.com/lxepoo/apache-php5

3、容器管理。e121d5f99e1e是执行docker images命令查询到的IMAGE ID,使用docker run命令进入容器。

1
# docker run –ti e121d5f99e1e /bin/bash

使用exit可以退出当前容器。run命令加上–d参数可以在后台运行容器,—name指定容器命名为apache。

1
# docker run -d --name apache e121d5f99e1e

进入后台运行的容器。

1
# docker exec -ti apache /bin/bash

将容器做成镜像。

1
# docker commit containerID/containerName newImageName:tag

为了方便测试和恢复,先将源镜像运行起来后再做一个命名简单的镜像做测试。

1
# docker commit 4c8066cd8c01 apachephp:v1

运行容器并将宿主机的8080端口映射到容器里去。

1
# docker run -d -p 8080:80 apachephp:v1

在浏览器输入宿主机ip加8080端口访问测试,出现以下内容则说明运行成功。

1

镜像制作

1、准备dockerfile内容。

1
# vim Dockerfile FROM apachephp:v1 #声明基础镜像来源MAINTAINER DTSTACK #声明镜像拥有者RUN mkdir /dtstact #RUN后面接容器运行前需要执行的命令,由于Dockerfile文件不能超过127行,因此当命令较多时建议写到脚本中执行ENTRYPOINT ping www.aliyun.com #开机启动命令,此处最后一个命令需要是可在前台持续执行的命令,否则容器后台运行时会因为命令执行完而退出。

2、构建镜像。

1
docker build -t webcentos:v1 . # . 是Dockerfile文件的路径,不能忽略docker images #查看是否创建成功docker run –d webcentos:v1 #后台运行容器docker ps #查看当前运行中的容器docker ps –a #查看所有容器,包括未运行中的docker logs CONTAINER ID/IMAGE #如未查看到刚才运行的容器,则用容器id或者名字查看启动日志排错docker commit fb2844b6c070 dtstackweb:v1 #commit 后接容器id 和构建新镜像的名称和版本号。docker images #列出本地(已下载的和本地创建的)镜像docker push #将镜像推送至远程仓库,默认为 Docker Hub

3、将镜像推送到registry。

1
docker login --username=dtstack_plus registry.cn-shanghai.aliyuncs.com #执行后输入镜像仓库密码docker tag [ImageId] registry.cn-shanghai.aliyuncs.com/dtstack123/test:[镜像版本号]docker push registry.cn-shanghai.aliyuncs.com/dtstack123/test:[镜像版本号]

在镜像仓库能查看到镜像版本信息则说明push成功

其中[ImageId],[镜像版本号]请您根据自己的镜像信息进行填写。

1
Cannot connect to the Docker daemon. Is the docker daemon running on this host?

未命名

发表于 2017-09-06
ssh连接阿里云
  1. 设置root账户密码
    刚刚购买过后的服务器实例是没有密码的。
    需要在—实力详情—基本详情一更多设置一下root账号的密码
  2. 通过ssh连接云服务器
    1
    2
    3
    4
    $ssh root@xxx.xxx.xxx.xxx #服务器的公网ip
    $root@xxx.xxx.xxx.xxx's password: #输入设置过的root密码
    $Welcome to Alibaba Cloud Elastic Compute Service ! #连接成功
添加新用户

root权限是服务器的最高权限,平时尽量避免使用root权限直接操作。
可以通过新建用户并赋予root的权限。平时使用这个用户使用服务器,在有需要root权限的操作时通过添加sudo来获取root权限

1
2
3
4
5
6
7
8
$ useradd 新用户名 #添加新用户
$ passwd 新用户名 #设置密码
Changing password for user 新用户名.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
$ gpasswd -a 用户名 wheel #分配用户到wheel用户组 centOS wheel用户组默认有root权限

用户相关其他操作

1
2
$ ls –l /home #查看用户
$ userdel -rf name #删除名称为name的用户。
禁止root远程登录
1
2
3
sudo vi /etc/ssh/sshd_config
/PermitRootLogin #Yes改为No
sudo systemctl reload sshd #重载文件

koa-router 7中文

发表于 2017-08-31

Koa-router 7

  • Express风格的路由 app.get, app.put, app.post, 等等
  • 命名URL参数
  • 命名路由由URL生成
  • Responds to OPTIONS requests with allowed methods.
  • 支持 405 Method Not Allowed 和 501 Not Implemented.
  • 多路由中间件
  • 多路由
  • 嵌套路由
  • ES7 async/await 支持

API Reference

  • koa-router

    • Router

      ⏏

      • new Router([opts])
      • instance
        • .get|put|post|patch|delete|del ⇒ Router
        • .routes ⇒ function
        • .use([path], middleware) ⇒ Router
        • .prefix(prefix) ⇒ Router
        • .allowedMethods([options]) ⇒ function
        • .redirect(source, destination, code) ⇒ Router
        • .route(name) ⇒ Layer | false
        • .url(name, params) ⇒ String | Error
        • .param(param, middleware) ⇒ Router
      • static
        • .url(path, params) ⇒ String

Router ⏏

类型: 导出类

new Router([opts])

创建一个新的路由

Param参数 Type类型 Description描述
[opts] Object
[opts.prefix] String prefix router paths 路由前缀路径

Example
Basic usage:

1
2
3
4
5
6
7
8
9
10
11
12
13
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
router.get('/', function (ctx, next) {
// ctx.router available
});
app
.use(router.routes())
.use(router.allowedMethods())

router.get|put|post|patch|delete|del ⇒ Router

verb:动词

创建 router.verb() 方法, 其中动词是诸如router.get() or router.post()之类的HTTP动词之一。

使用router.verb()将URL与回调函数或控制器进行匹配,其中动词是诸如router.get()或router.post()之类的HTTP动词之一。

另外, router.all() 可以匹配所有路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
router
.get('/', function (ctx, next) {
ctx.body = 'Hello World!';
})
.post('/users', function (ctx, next) {
// ...
})
.put('/users/:id', function (ctx, next) {
// ...
})
.del('/users/:id', function (ctx, next) {
// ...
})
.all('/users/:id', function (ctx, next) {
// ...
});

当一个路由匹配时,其路径在ctx._matchedRoute可用,如果命名,则名称可在ctx._matchedRouteName

路由路径将使用 path-to-regexp.转换为正则表达式

匹配请求时不会考虑查询字符串

Named routes 命名路由

路由可以配置名称。这样可以在开发过程中轻松生成URL或重命名URL。

1
2
3
4
5
6
router.get('user', '/users/:id', function (ctx, next) {
// ...
});
router.url('user', 3);
// => "/users/3"

Multiple middleware 多中间件

一个路由可以给多个中间件

1
2
3
4
5
6
7
8
9
10
11
12
13
router.get(
'/users/:id',
function (ctx, next) {
return User.findOne(ctx.params.id).then(function(user) {
ctx.user = user;
next();
});
},
function (ctx) {
console.log(ctx.user);
// => { id: 17, name: "Alex" }
}
);

Nested routers

支持嵌套路由

1
2
3
4
5
6
7
8
9
const forums = new Router();
const posts = new Router();
posts.get('/', function (ctx, next) {...});
posts.get('/:pid', function (ctx, next) {...});
forums.use('/forums/:fid/posts', posts.routes(), posts.allowedMethods());
// responds to "/forums/123/posts" and "/forums/123/posts/123"
app.use(forums.routes());

Router prefixes

路由路径可以在路由器级别设置前缀:

1
2
3
4
5
6
var router = new Router({
prefix: '/users'
});
router.get('/', ...); // responds to "/users"
router.get('/:id', ...); // responds to "/users/:id"

URL parameters

路由参数被捕获并添加到ctx.params.

1
2
3
4
router.get('/:category/:title', function (ctx, next) {
console.log(ctx.params);
// => { category: 'programming', title: 'how-to-node' }
});

The path-to-regexp module is used to convert paths to regular expressions.

Kind: Router的实例属性

Param Type Description
path String
[middleware] function route middleware(s)
callback function route callback

router.routes ⇒ function

返回匹配到的路由所调用的中间件

Kind: Router的实例属性

router.use([path], middleware) ⇒ Router

Use given middleware.

使用指定的中间件

中间件按照由.use()定义的顺序运行。它们被按顺序调用,第一个中间件开始,以中间件堆栈的方式依次向下执行。

Kind: Router的实例方法

Param Type
[path] String
middleware function
[…] function

Example

1
2
3
4
5
6
7
8
9
10
11
12
// session middleware will run before authorize
router
.use(session())
.use(authorize());
// use middleware only with given path
router.use('/users', userAuth());
// or with an array of paths
router.use(['/users', '/admin'], userAuth());
app.use(router.routes());

router.prefix(prefix) ⇒ Router

设置已经初始化的路由器实例的路径前缀。

Kind: Router的实例方法

Param Type
prefix String

Example

1
router.prefix('/things/:thing_id')

router.allowedMethods([options]) ⇒ function

Returns separate middleware for responding to OPTIONS requests with an Allow header containing the allowed methods, as well as responding with 405 Method Not Allowed and 501 Not Implemented as appropriate.

Kind: instance method of Router

Param Type Description
[options] Object
[options.throw] Boolean throw error instead of setting status and header 抛出错误而不是设置status和header
[options.notImplemented] function throw the returned value in place of the default NotImplemented error 抛出返回值代替默认NotImplemented error
[options.methodNotAllowed] function throw the returned value in place of the default MethodNotAllowed error 抛出返回值代替默认NotImplemented error

Example

1
2
3
4
5
6
7
8
const Koa = require('koa');
const Router = require('koa-router');
const app = new Koa();
const router = new Router();
app.use(router.routes());
app.use(router.allowedMethods());

Example with Boom

1
2
3
4
5
6
7
8
9
10
11
12
13
const Koa = require('koa');
const Router = require('koa-router');
const Boom = require('boom');
const app = new Koa();
const router = new Router();
app.use(router.routes());
app.use(router.allowedMethods({
throw: true,
notImplemented: () => new Boom.notImplemented(),
methodNotAllowed: () => new Boom.methodNotAllowed()
}));

router.redirect(source, destination, code) ⇒ Router

Redirect source to destination URL with optional 30x status code.

Both source and destination can be route names.

1
router.redirect('/login', 'sign-in');

This is equivalent to:

1
2
3
4
router.all('/login', function (ctx) {
ctx.redirect('/sign-in');
ctx.status = 301;
});

Kind: instance method of Router

Param Type Description
source String URL or route name.
destination String URL or route name.
code Number HTTP status code (default: 301).

router.route(name) ⇒ Layer | false

Lookup route with given name.

Kind: instance method of Router

Param Type
name String

router.url(name, params) ⇒ String | Error

Generate URL for route. Takes a route name and map of named params.

Kind: instance method of Router

Param Type Description
name String route name
params Object url parameters

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
router.get('user', '/users/:id', function (ctx, next) {
// ...
});
router.url('user', 3);
// => "/users/3"
router.url('user', { id: 3 });
// => "/users/3"
router.use(function (ctx, next) {
// redirect to named route
ctx.redirect(ctx.router.url('sign-in'));
})

router.param(param, middleware) ⇒ Router

Run middleware for named route parameters. Useful for auto-loading or validation.

Kind: instance method of Router

Param Type
param String
middleware function

Example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
router
.param('user', function (id, ctx, next) {
ctx.user = users[id];
if (!ctx.user) return ctx.status = 404;
return next();
})
.get('/users/:user', function (ctx) {
ctx.body = ctx.user;
})
.get('/users/:user/friends', function (ctx) {
return ctx.user.getFriends().then(function(friends) {
ctx.body = friends;
});
})
// /users/3 => {"id": 3, "name": "Alex"}
// /users/3/friends => [{"id": 4, "name": "TJ"}]

Router.url(path, params) ⇒ String

Generate URL from url pattern and given params.

Kind: static method of Router

Param Type Description
path String url pattern
params Object url parameters

Example

1
2
const url = Router.url('/users/:id', {id: 1});
// => "/users/1"

Contributing

Please submit all issues and pull requests to the alexmingoia/koa-router repository!

Tests

Run tests using npm test.

Support

If you have any problem or suggestion please open an issue here.

未命名

发表于 2017-08-23

require和import的区别

1.规范不同

模块化规范:即为 JavaScript 提供一种模块编写、模块依赖和模块运行的方案。

  • require方法是JavaScript 社区中的开发者自己草拟的规则CommonJs推出的。
  • import/export 则是TC39 制定的新的 ECMAScript 版本,即 ES6(ES2015)中包含进来。

CommonJS是Node.js中模块化的规范,Node.js无法直接兼容es6语法。现在在Node中使用的 import语法都是由babel编译成 require/exports 来执行的

2.书写方式不同

require/exports :

1
2
3
const fs = require('fs')
exports.fs = fs
module.exports = fs

import/export :

1
2
3
4
5
6
7
8
9
10
11
12
import fs from 'fs'
import {default as fs} from 'fs'
import * as fs from 'fs'
import {readFile} from 'fs'
import {readFile as read} from 'fs'
import fs, {readFile} from 'fs'
export default fs
export const fs
export function readFile
export {readFile, read}
export * from 'fs'

3.本质不同

require 运行时加载

1
2
3
4
5
6
7
8
// CommonJS模块
let { stat, exists, readFile } = require('fs')
// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;

上面代码的实质是整体加载fs模块(即加载fs的所有方法),生成一个对象(_fs),然后再从这个对象上面读取3个方法。这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”。

Import 编译时加载

1
2
// ES6模块
import { stat, exists, readFile } from 'fs';

上面代码的实质是从fs模块加载3个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。

MongoDB指令整理

发表于 2017-08-21

启动mongoDB

运行 MongoDB

1、首先我们创建一个数据库存储目录 /data/db:

1
sudo mkdir -p /data/db

启动 mongodb,默认数据库目录即为 /data/db:

1
2
3
4
5
6
sudo mongod #启动mongo
#参数
--dbpath [数据存放path] #指定数据库path
-auth #开启授权启动
--logpath [数据存放path] #指定日志路径
--port [端口号]

开启一个新的终端进入MongoDB shell

1
mongo

MongoDB配置

  • 端口

    • 默认端口 27017

    • Mongo shell 获取端口 db.getMongo()

      ​

数据库操作

创建数据库
1
use DATABASE_NAME

如果数据库不存在,则创建数据库,否则切换到指定数据库。

查看当前数据库
1
2
db
db.getName()
查看所有数据库
1
show dbs
删除数据库
1
db.dropDatabase()
拷贝数据库
1
2
3
db.cloneDatabase("127.0.0.1") #将指定机器上的数据库的数据克隆到当前数据库
db.copyDatabase("mydb", "temp", "127.0.0.1") #将本机的mydb的数据复制到temp数据库中
连接数据库
1
mongo://[host:port/database] -u [user] -p [password] 192.168.1.200:27017/test -u user -p password

db.dropDatabase() #删除当前使用数据库
db.cloneDatabase(“127.0.0.1”) #将指定机器上的数据库的数据克隆到当前数据库
db.copyDatabase(“mydb”, “temp”, “127.0.0.1”) #将本机的mydb的数据复制到temp数据库中
db.repairDatabase() #修复当前数据库
db.getName() #查看当前使用的数据库,也可以直接用db
db.stats() #显示当前db状态
db.version() #当前db版本
db.getMongo() #查看当前db的链接机器地址
db.serverStatus() #查看数据库服务器的状态CRUD

用户管理

查看用户
1
db.system.find()
添加用户
1
2
3
4
5
6
7
8
9
10
11
#添加用户:
db.createUser({
user: "<name>", //用户名
pwd: "<cleartext password>",
customData: { <any information> }, //可选的,备注信息。
roles: [
{ role: "<role>", db: "<database>" } | "<role>", //指定角色
...
]},
writeConcern: { <write concern> }
)
更新用户
1
2
3
4
5
6
7
8
9
10
11
12
13
#更改用户信息:将会覆盖掉原先的用户信息
root(
"<username>",
{
customData : { <any information> },
roles : [
{ role: "<role>", db: "<database>" } | "<role>",
...
],
pwd: "<cleartext password>"
},
writeConcern: { <write concern> }
)
删除用户
1
db.dropUser('test') #必须在该用户创建的库中删除

数据操作/CRUD

Create 插入数据
1
2
3
4
db.collection.insert() # 插入数据
db.collection.save() # 不传Id会插入一条新的数据,传id此操作变为更新数据
db.collection.insertOne() # 向指定集合中插入一条文档数据
db.collection.insertMany() # 向指定集合中插入多条文档数据,传入数组
Retrieve读取数据
1
2
db.collection.find(query, projection)
db.col.find().pretty() # pretty
Update更新数据
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
db.collection.update( # 更新已存在的文档
<query>, # update的查询条件
<update>, # update的对象和一些更新的操作符(如$,$inc...)等
{
upsert: <boolean>, # 可选,如果不存在update的记录,是否插入一条新的,默认是false,不插入。
multi: <boolean>, # 可选,默认是false,只更新找到的第一条记录,否则更新全部
writeConcern: <document> # 可选,抛出异常的级别。
}
)
db.collection.save( # 通过传入的文档来替换已有文档
<document>,
{
writeConcern: <document>
}
)
1
2
3
4
5
6
7
8
9
10
11
12
# 只更新第一条记录:
db.col.update( { "count" : { $gt : 1 } } , { $set : { "test2" : "OK"} } );
# 全部更新:
db.col.update( { "count" : { $gt : 3 } } , { $set : { "test2" : "OK"} },false,true );
# 只添加第一条:
db.col.update( { "count" : { $gt : 4 } } , { $set : { "test5" : "OK"} },true,false );
# 全部添加加进去:
db.col.update( { "count" : { $gt : 5 } } , { $set : { "test5" : "OK"} },true,true );
# 全部更新:
db.col.update( { "count" : { $gt : 15 } } , { $inc : { "count" : 1} },false,true );
# 只更新第一条记录:
db.col.update( { "count" : { $gt : 10 } } , { $inc : { "count" : 1} },false,false );
Delete删除数据
1
2
3
4
5
6
7
db.collection.remove( # 移除集合中的数据。
<query>,
{
justOne: <boolean>,
writeConcern: <document>
}
)

数据表操作

1
show collections
1
db.collections.help(); user为表名

http://www.cnblogs.com/ontheroad_lee/p/3684280.html

git合并与提交

发表于 2017-08-14

多人合作的git使用

git merge 的 —no-ff 参数

git merge 默认是”快进式合并”(fast-farward merge)。这样合并操作会直接将Master 指向 develop 分支

WechatIMG580

上图有多分支合并的结果图,可以看到 使用—no-ff的提交流程更清晰

分支管理

git flow 只存在两个长期分支master 和 develop

其他分支命名必须遵照规则,在合并之后立即删除。

1
2
3
  * 功能(feature)分支
  * 预发布(release)分支
  * 修补bug(fixbug)分支

master 分支代码是不可更改的。

正常流程中将准备发布的dev上的代码合并入master中再进行部署

需要修复bug,则新建fixbug分支,完成后分别合并入dev与master

主分支保持同步

请勿在多人工作分支上进行变基操作

fetch更新本地仓库两种方式:

复制代码;)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//方法一
$ git fetch origin master //从远程的origin仓库的master分支下载代码到本地的origin master
$ git log -p master.. origin/master//比较本地的仓库和远程参考的区别
$ git merge origin/master//把远程下载下来的代码合并到本地仓库,远程的和本地的合并
//方法二
$ git fetch origin master:temp //从远程的origin仓库的master分支下载到本地并新建一个分支temp
$ git diff temp//比较master分支和temp分支的不同
$ git merge temp//合并temp分支到master分支
$ git branch -d temp//删除temp

合并多次commit

开发的时候我们通常会在开发分支多次commit,但是对于多人合作来说,很多commit是无用的信息。如果将所有commit信息全部合并进git的baseline中,会导致commit信息过多并且混乱

git merge –squash abc
–squash选项的含义是:不保留待合并分支上的历史信息,也不提交、不移动HEAD,因此需要一条额外的commit命令。
其效果相当于将another分支上的多个commit合并成一个,放在当前分支上,原来的commit历史则没有拿过来。

判断是否使用–squash选项最根本的标准是,待合并分支上的历史是否有意义。

合并的时候—squash 参数可以将分支上所有的变动改为一次commit,使用merge命令后需要在合并后的分支上将变动添加,commit一次,这样在分支上的多次commit在git的baseline上就只会有一次commit。

但是—squash 和 —no-ff参数不可一并使用。

—squash 和 —no-ff 是不同的提交风格

fast-farward式的merge通过—squash 可以形成单一的整洁的提交历史记录

—no-ff 式的merge 形成的提交历史记录可以显示详细的提交历史

docker命令整理

发表于 2017-07-07
在Linux上启动Docker
启动
1
2
service docker start #旧语法
systemctl start docker.service #新语法
设置开启启动
1
2
chkconfig docker on #旧
systemctl enable docker.service #新
问题整理
1
2
$ docker ps
Cannot connect to the Docker daemon. Is the docker daemon running on this host?
1
2
3
4
$ ps aux | grep docker
root 17210 0.0 2.4 499624 24928 ? Ssl Sep06 0:26 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --selinux-enabled --log-driver=journald --signature-verification=false
root 17214 0.0 0.6 262960 6948 ? Ssl Sep06 0:02 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --shim docker-containerd-shim --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --runtime docker-runc --runtime-args --systemd-cgroup=true
zeno 21958 0.0 0.0 112648 964 pts/0 R+ 14:35 0:00 grep --color=auto docker

查看进程,其实docker已经运行了。其实是权限不够,需要在加上sudo.还有很多类似的命令,按照理解查看应该是不要root权限的,其实不然。docker info,docker ps,docker images都会没有权限

Docker镜像命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
docker rmi [镜像] #删除镜像
docker search #搜索镜像
docker images # 列出镜像
docker run 镜像名:标签 # 运行镜像 REPOSTITORY:TAG docker run --name web2 -d -p 81:80 nginx:v2
exit # 退出镜像
docker pull 镜像名 # 获取镜像
-i # 交互式操作
-t # 终端
-d # 让容器在后台运行。
-P [主机端口]:[容器端口] # 将容器内部使用的网络端口映射到我们使用的主机上。
-v [主机目录]:[容器目录]
docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2
-m:提交的描述信息
-a:指定镜像作者
e218edb10161:容器ID
2runoob/ubuntu:v2:指定要创建的目标镜像名
docker commit #慎用,黑箱操作 容易使镜像变得臃肿
docker diff #比较改动
docker build [选项] <上下文路径/URL/->
Docker容器命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker rm [name/id] #删除docker容器 ,容器必须是停止的否则报错
docker start [name/id] #重新启动docker
docker ps #查看正在运行的docker进程
docker ps -a #查看所有已创建的容器
docker rm $(docker ps -a -q) #删除所有的终止容器 Mac
docker port [name/id] #查看进程端口映射
docker stop [name/id] #停止进程
docker logs [name/id] #查看容器内的标准输出
-f #实时日志
docker top [name/id] #查看容器内的的进程
docker inspect [name/id] #来查看Docker的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。
docker inspect container_name | grep Mounts -A 20 #查看容器挂载目录
docker attach [name/id] #进入正在运行的docker进程中 NOTE: 这个链接终止后,容器会退出后台运行
docker exec -it [name/id] /bin/sh # 进入正在运行的docker进程中 常加参数 -it
1
2
sudo docker run -ti --rm --entrypoint="/bin/bash" jenkins -c "whoami && id" #查看容器拥有者
docker run -ti --rm --entrypoint="/bin/bash" jenkins -c "ls -la /var/jenkins_home" #查看容器内/var/jenkins_home拥有者
1234
Zeno Tian

Zeno Tian

38 日志
17 标签
GitHub
© 2017 Zeno Tian
由 Hexo 强力驱动
主题 - NexT.Mist