Docker Machine 简介

一句话概括的话就是 Docker Machine是一个可以方便对多个宿主服务器中的多个容器进行管理的工具。

Docker 与 Docker Machine 的区别 https://www.cnblogs.com/sparkdev/p/7066789.html

Docker Machine 工具出现的意义 https://www.2cto.com/net/201707/660864.html

Docker Machine 用法 http://www.linuxidc.com/Linux/2017-06/145232.htm

Docker Machine 命令 http://blog.csdn.net/warren_1992/article/details/51451522

Mac平台上Docker安装与使用 http://blog.csdn.net/warren_1992/article/details/51451522

windows平台在dos下执行docker pull 命令出错

这里docker Machine 是安装和管理 Docker 的工具(用来代替Boot2Docker,对于个个玩的话,个人不建议使用docker Machine,毕竟多了一个虚拟层,不如直接使用当前物理机器作为容器的宿主机)

$ docker pull gitlab/gitlab-ce:latest

Warning: failed to get default registry endpoint from daemon (error during connect: Get http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.33/info: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.). Using system default: https://index.docker.io/v1/
error during connect: Post http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.33/images/create?fromImage=gitlab%2Fgitlab-ce&tag=latest: open //./pipe/docker_engine: The system cannot find the file specified. In the default daemon configuration on Windows, the docker client must be run elevated to connect. This error may also indicate that the docker daemon is not running.

解决方法:打开新窗口后执行(

docker-machine env

根据提示运行命令

@FOR /f "tokens=*" %i IN ('docker-machine env default') DO @%i

default 是docker-machine的name,可以通过docker-machine -ls 查看。

如果还提示这个错误,说明没有启用 default ,执行下面的命令

D:\docker
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
default - virtualbox Stopped Unknown

如果为stopped状态,则需要启用一下

$ docker-machine start default
Starting "default"...
(default) Check network to re-create if needed...
(default) Windows might ask for the permission to configure a dhcp server. Sometimes, such confirmation window is minimized in the taskbar.
(default) Waiting for an IP...
Machine "default" was started.
Waiting for SSH to be available...
Detecting the provisioner...
Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

最后再执行

$ docker pull hub-mirror.c.163.com/gitlab/gitlab-ce:latest
latest: Pulling from gitlab/gitlab-ce
1be7f2b886e8: Pull complete
6fbc4a21b806: Pull complete
c71a6f8e1378: Pull complete
4be3072e5a37: Pull complete
06c6d2f59700: Pull complete
3e236075b07f: Pull complete
9d3aa9a75297: Pull complete
1fad4f75154b: Pull complete
5383bef86102: Pull complete
7343d4ab63b3: Pull complete
7f250f1b8a34: Downloading [==================> ] 157.4MB/415.4MB

 

利用“码云gitee"的钩子实现git仓库自动更新

使用git时,传统发布方式是手动将新代码 上传到远程仓库,然后在登录服务器执行git pull命令拉取最新的代码,这种操作如果频繁更新的话,我们可以利用git的钩子来实现自动 部署 功能。

前提:
linux
php (gitpull.php)
nginx 运行用户为 www

注意网站 gitpull.php 文件权限问题,还有是否有shell_exec 命令的执行权限

一、先创建自动部署用户的密钥

sudo - www
ssh-keygen -t rsa -C "syadmin@gmail.com"

二、将用户www生成的公钥添加到码云后台

cat ~/.ssh/id_rsa.pub

三、将码云域名gitee.com 添加到授权白名单

ssh-keyscan -t rsa gitee.com >> ~/.ssh/known_hosts

或者以www用户执行一次gitpull命令

sudo - www
cd /data/wwwroot/www
git pull

根据提示,输入 yes 即可。

四、在码云的部署钩子里进行url设置

url里填写 http://www.test.com/gitpull.php, 密码写123456

到此基本上可以实现了.

gitpull.php 脚本( 来自网友整理)

//git webhook 自动部署脚本
//项目存放物理路径,第一次clone时,必须保证该目录为空
$savePath = "/data/wwwroot/www";
$gitPath = "git@gitee.com:test/spa.git";//代码仓库

$name= "tom";//用户仓库邮箱
$email = "tom@gmail.com";//仓库用户名,一般和邮箱一致即可
$password = '123456';

$isCloned = true;//设置是否已经Clone到本地,true:已经clone,直接pull,false:先clone.

//如果已经clone过,则直接拉去代码
if ($isCloned) {
    $requestBody = file_get_contents("php://input");
    if (empty($requestBody)) {
        die('send fail');
    }

    //解析Git服务器通知过来的JSON信息
    $content = json_decode($requestBody, true);
    if($content['password'] != $password){
        exit('deny');
    }

    //若是主分支且提交数大于0
    if ($content['ref'] == 'refs/heads/master' && $content['total_commits_count'] > 0) {

        $res = PHP_EOL . "pull start --------" . PHP_EOL;
        $res .= shell_exec("cd {$savePath} && git pull {$gitPath}");//拉去代码
        $res_log = '-------------------------' . PHP_EOL;
        $res_log .= $content['user_name'] . ' 在' . date('Y-m-d H:i:s') . '向' . $content['repository']['name'] . '项目的' . $content['ref'] . '分支push了' . $content['total_commits_count'] . '个commit:';
        $res_log .= $res . PHP_EOL;
        $res_log .= "pull end --------" . PHP_EOL;
        file_put_contents("git-webhook_log.txt", $res_log, FILE_APPEND);//写入日志到log文件中
    }
} else {
    $res = "clone start --------" . PHP_EOL;
    //注:在这里需要设置用户邮箱和用户名,不然后面无法拉去代码
    $res .= shell_exec("git config --global user.email {$email}}") . PHP_EOL;
    $res .= shell_exec("git config --global user.name {$name}}") . PHP_EOL;
    $res .= shell_exec("git clone {$gitPath} {$savePath}") . PHP_EOL;
    $res .= "clone end --------" . PHP_EOL;
    file_put_contents("git-webhook_log.txt", $res, FILE_APPEND);//写入日志到log文件中
}

 

 

vux中实现自定义皮肤

有时候我们需要根据自己的需要对 weui默认的颜色进行修改,如果在每个单面里修改的过过于麻烦,我们可以使用一个less配置文件来实现对默认配置进行重置。

修改 webpack.base.conf.js 文件,找到

module.exports = vuxLoader.merge(webpackConfig, {
  plugins: ['vux-ui', 'progress-bar', 'duplicate-style', ]
})

修改如下:

module.exports = vuxLoader.merge(webpackConfig, {
  plugins: ['vux-ui', 'progress-bar', 'duplicate-style', {
      name: 'less-theme',
      path: 'src/theme.less'
    }]
})

然后在项目的 src 目录里创建文件 theme.less,文件内容写为

@button-primary-bg-color: #FC4A26;

然后重启服务即可。

CSS3 利用@media screen实现网页布局的自适应,样式顺序

利用@media screen可以适应不同屏幕大小,做出相应的界面调整;

在css中@media (min-width: 768px)表示最小是768也就是>=768;

@media (min-width: 768px){ //>=768的设备 }

@media (min-width: 992px){ //>=992的设备 }

@media (min-width: 1200){ //>=1200的设备 }

注意下顺序,如果你把@media (min-width: 768px)写在了下面那么很悲剧,

@media (min-width: 1200){ //>=1200的设备 }
@media (min-width: 992px){ //>=992的设备 }
@media (min-width: 768px){ //>=768的设备 }

因为如果是1440,由于1440>768那么你的1200就会失效。

所以我们用min-width时,小的放上面大的在下面,同理如果是用max-width那么就是大的在上面,小的在下面

@media (max-width: 1199){ //<=1199的设备 }

@media (max-width: 991px){ //<=991的设备 }

@media (max-width: 767px){ //<=768的设备 }

 

另外也支持混合写法

@media screen and (min-width: 960px) and (max-width: 1199px) { }

注意下面写了 and 关键字,and后面和左括号中间必须有一个空格,否则样式不生效。

centos 下安装 certbot 常见问题

上一篇(https://blog.haohtml.com/archives/17422)我们介绍了centos下安装certbot的方法,但有时间服务器环境不一样,总会遇到一些问题,常见问题如下:

centos7.5下安装certbot常见问题

一、出错”ImportError: ‘pyOpenSSL’ module missing required functionality. Try upgrading to v0.14 or newer.“
解决办法:

sudo pip uninstall pyOpenssl
sudo pip install pyOpenSSL==0.14.0

查看版本:

pip show pyOpenssl

一、出错信息为“certbot AttributeError: 'module' object has no attribute 'SSL_ST_INIT'”

解决办法:

pip uninstall pyOpenSSL
pip install pyOpenSSL==16.2.0

 

php的Pdo扩展实现类似mysql_ping的方法

在php里Pdo是没有mysql_ping和mysqli_ping函数的,可以使用以下方法来代替它

class NPDO {
    private $pdo;
    private $params;

    public function __construct() {
        $this->params = func_get_args();
        $this->init();
    }

    public function __call($name, array $args) {
        return call_user_func_array(array($this->pdo, $name), $args);
    }

    // The ping() will try to reconnect once if connection lost.
    public function ping() {
        try {
            $this->pdo->query('SELECT 1');
        } catch (PDOException $e) {
            $this->init();            // Don't catch exception here, so that re-connect fail will throw exception
        }

        return true;
    }

    private function init() {
        $class = new ReflectionClass('PDO');
        $this->pdo = $class->newInstanceArgs($this->params);
    }
}

转自:https://terenceyim.wordpress.com/2009/01/09/adding-ping-function-to-pdo/

或者使用以下方法(目前本人在用)

    /**
     * 检查连接是否可用
     * @param  Link $dbconn 数据库连接
     * @return Boolean
     */
    function ping() {
        try {
            $ret = $this->getAttribute(constant("PDO::ATTR_SERVER_INFO"));
            if ($ret === null) {
                return false;
            }

        } catch (\PDOException $e) {
            if(strpos($e->getMessage(), 'MySQL server has gone away')!==false){
                echo PHP_EOL . $e->getMessage() . PHP_EOL;
                return false;
            }
        }
        return true;
    }

bootstrap自动完成插件Typeahead.js的用法之ajax请求

官方对Typeahead.js的介绍太简单了,对于新手来说有些吃力,项目中使用了这个插件,困惑了两天,终于才搞定它的ajax用法。官方示例虽然可以使用,但从remote url 获取数据的时候,无法传递过多的自定义参数,如要根据省份、城市信息来获取当前城市的小区信息,这个时候我们就要想办法把省份和城市信息也同时发给后端才可以。这样可以过滤大部分的无用信息,产少数据量的产生。


js代码

$(function(){	
/*
	var filterResult = new Bloodhound({
		datumTokenizer: Bloodhound.tokenizers.whitespace,
		queryTokenizer: Bloodhound.tokenizers.whitespace,
		initialize: false,
		remote: {
			url: '/getCommunityList?province_code=' + $("#province_code").val() + '&q=%QUERY',
			wildcard: '%QUERY'
		}
	});
*/	
	
	$('#community_name').typeahead({
			highlight: true,
			hint: true,
			minLength: 1
		},
		{

			name: 'result-list',
			limit: 10,
			async: true,
			source: function (query, processSync, processAsync) {
					//processSync(['This suggestion appears immediately', 'This one too']);
					var params = {
						province_code: $("#province_code").val(),
						city_code: $("#city_code").val(),
						area_code: $("#area_code").val(),	
						q: query
					};
					
					if (params.province_code == '' || params.city_code == '' || params.area_code == '' || params.q == '') {
						return false;	
					}
					
					$.post('/getCommunityList', params, function(json) {
						if (json.status == '0') {
							layer.msg(json.info);	
						} else {
							return processAsync(json.data);	
						}
					});
                },
			display:function(item){
						return item.name
					},
			templates: {
			  suggestion: function (item){
							return '

' + item.name + '

'; }, notFound: '
未找到小区,请确认区域信息!
', header: '

可使用键盘↑↓选择。

', // footer: '

支持剪头移动选择项

' } } ); //结果项被选中事件 $('#community_name').bind('typeahead:select', function(ev, suggestion) { $("#address").html(suggestion.address); // console.log(suggestion); }); //鼠标移动到选择项事件 $('#community_name').bind('typeahead:cursorchange', function(ev, suggestion) { // console.log(suggestion); }); $('#community_name').bind('typeahead:autocomplete', function(ev, suggestion) { console.log(suggestion); }); })

注意上面的 async: true 配置,还有source回调函数要使用三个参数。