让你的项目自动化部署到服务器

通俗点讲,就是在本地开发完成,然后 git push 到 gitlab 上,然后自动更新到服务器,无需手动进入服务器手动 git pull

简单点讲,就是 git push 后,有个钩子( http://www.a.com/update.php类似这样的网址 )请求一下,update.php 代码中会执行相关命令,代替手动 git pull

建议:建立一个 demo 项目,放到 git 上,把整个流程跑通了再用在其他项目中,要不然你的 git 记录会有很多垃圾 push 信息

第一步:登录你的服务器

不管用 password 还是 ssh 登录服务器均可,不是本地介绍重点,简单略过.建议用 ssh 登录
具体实现可以查看资料

Linux 篇:Linux ssh 登录
服务器搭建:(二)SSH 登录详解

第二步:查看你的 nginx 所属用户

因为是个人博客项目,偷个懒,直接 lnmp 一键环境搭建,没搭建环境的可以去官网lnmp 官网 https://lnmp.org/查看安装命令即可,在服务器搭建环境如下:
已安装好 nginx、PHP 等环境的忽略下面的命令

wget http://soft.vpser.net/lnmp/lnmp1.6.tar.gz -cO lnmp1.6.tar.gz && tar zxf lnmp1.6.tar.gz && cd lnmp1.6 && ./install.sh lnmp

安装好环境以后,执行命令

cd /usr/local/nginx/conf/  #每个人的安装路径可能不同,最关键是找到nginx.conf,查看执行用户名称
vi nginx.conf   #第一行,查看到当前nginx的执行用户是user  www www;

第三步:给服务器项目目录权限

cd /home  #先进入/home/目录
ll   # 或者 ls-a查看wwwroot所属权限

drwx—— 3 www www 111 Dec 26 09:26 www
drwxrwxrwx 2 root root 79 Dec 25 14:32 wwwlogs
drwxr-xr-x 6 www www 74 Dec 25 16:35 wwwroot

#如果权限这个不是 www,就执行以下命令

chown -R www:www /home/wwwroot/ #这个是LNMP默认存放项目的地方,换成你自己的

这样目录就可以移交给 www 用户了,现在 www 用户可以访问这个目录和.git 文件了。

切换到执行用户,接着我们我们切换到 www 用户

su www

结果显示“This account is currently not available.”,啥?这不让我登录?别急,这是因为 linux 连 www 帐户登录 shell 的权利都给剥夺了,我们暂时给 www 权利就好了。到/etc/passwd 中,把 www 用户的配置修改一下,让他的登录 shell 变成/bin/bash

vi /etc/passwd

www:x:1001:1001::/home/www:/sbin/nologin
(建议注释原来的,重新复制一行修改)
www:x:1001:1001::/home/www:/bin/bash

然后 www 用户就有登录权限了。我们用 su www 重新切换一次,就会发现你现在是以 www 用户登录了。

su www

第四步:为 www 这个用户生成密钥

第一步也有相关资料推荐

ssh-keygen

注意:.ssh 的存放目录,一般是/home/当前用户名,然后接下来的操作都是回车
Enter file in which to save the key (/home/www/.ssh/id_rsa):

第五步:把生成的 ssh key 加入到你的 gitlab

->注意:不建议把 root 密钥增加到 gitlab 上,root 的密钥用于登录管理服务器就好,把 www 用户所属的密钥增加到 gitlab 即可
不管你是用以下哪个 git 平台去管理,皆大同小异,目前列举比较流行的几种,一般都是在(个人设置->ssh 公钥->新增)

  1. 码云 https://gitee.com/
  2. 阿里云 http://code.aliyun.com/ ->我使用的是这个
  3. github https://github.com/
  4. CODING https://coding.net/
  5. gitlab 内部搭建的 git 服务器
  6. 等待添加

第六步:拉取 gitlab 上的项目

cd /home/wwwroot
git clone git@code.aliyun.com:personage/demo.git #改成你的项目地址,如果拉取不成功,说明你的密钥没弄好

第七步:配置 nginx

因为我用 lnmp vhost add 增加了我的域名配置,自动在/home/wwwroot 下生成了 www.chengtianzhu.com 目录,所以我直接修改

chattr -i www.chengtianzhu.com/.user.ini  #lnmp生成时有个.user.ini,默认无法直接删除
rm -rf www.chengtianzhu.com/ #删除默认生成的目录
mv demo/ www.chengtianzhu.com/  把git拉取下来的项目重命名

在浏览器中输入 www.chengtianzhu.com, 看是否能否访问,如果是子目录,需要自己去 nginx 配置中修改路径

第九步:把自动拉取git的php代码放到项目中

www.chengtianzhu.com/update.php 为例,最好是单独配置个地址,因为是外部公共访问的:

<?php

class Deploy {

    /**
     * A callback function to call after the deploy has finished.
     *
     * @var callback
     */
    public $post_deploy;

    /**
     * The name of the file that will be used for logging deployments. Set to
     * FALSE to disable logging.
     *
     * @var string
     */
    private $_log = 'deployments.log';

    /**
     * The timestamp format used for logging.
     *
     * @link    http://www.php.net/manual/en/function.date.php
     * @var     string
     */
    private $_date_format = 'Y-m-d H:i:sP';

    /**
     * The name of the branch to pull from.
     *
     * @var string
     */
    private $_branch = 'master';

    /**
     * The name of the remote to pull from.
     *
     * @var string
     */
    private $_remote = 'origin';

    /**
     * The directory where your website and git repository are located, can be
     * a relative or absolute path
     *
     * @var string
     */
    private $_directory;

    /**
     * Sets up defaults.
     *
     * @param  string  $directory  Directory where your website is located
     * @param  array   $data       Information about the deployment
     */
    public function __construct($directory, $options = array())
    {
        // Determine the directory path        
                // Create the log file
                file_put_contents($filename, '');

                // Allow anyone to write to log files
                chmod($filename, 0666);
            }

            // Write the message into the log file
            // Format: time --- type: message
            file_put_contents($filename, date($this->_date_format).' --- '.$type.': '.$message.PHP_EOL, FILE_APPEND);
        }
    }

    /**
     * Executes the necessary commands to deploy the website.
     */
    public function execute()
    {
        try
        {
            // Make sure we're in the right directory
            chdir($this->_directory);
            $this->log('Changing working directory... ');
            // Discard any changes to tracked files since our last deploy
            exec('git reset --hard HEAD', $output);
            $this->log('Reseting repository... '.implode(' ', $output));

            // Update the local repository
            exec('git pull '.$this->_remote.' '.$this->_branch, $output);
            $this->log('Pulling in changes... '.implode(' ', $output));
            // Secure the .git directory
            exec('chmod -R og-rx .git');
            $this->log('Securing .git directory... ');

            if (is_callable($this->post_deploy))
            {
                call_user_func($this->post_deploy, $this->_data);
            }

            $this->log('Deployment successful.');
        }
        catch (Exception $e)
        {
            $this->log($e, 'ERROR');
        }
    }

}

// This is just an example
$deploy = new Deploy('/home/wwwroot/www.chengtianzhu.com/'); //修改成你的项目路径

$deploy->execute();

?>

第十步:gitlab配置

在项目–>设置–>WebHooks,增加刚才的www.chengtianzhu.com/update.php
或者在setting–>integrations,增加钩子
增加完成后可以点击<测试钩子>按钮测试一下.
显示200成功

Hook executed successfully: HTTP 200
但是一般还是拉取不了代码,因为第九步的php代码使用了exec函数,默认是禁用的.
我们写一个简单的demo测试一下,在服务器环境下:
vi test.php
内容为:

<?php
    exec('php hello.php',$out,$status);
    var_dump($out);
?>

再创建一个hello.php

vi hello.php

内容为:

<?php
 echo 'hello world';
?>

保存后,执行试一下

php test.php

提示:exec() has been disabled for security reasons,说明exec用不了

PHP Notice:  Undefined variable: out in /home/wwwroot/www.chengtianzhu.com/test.php on line 2
PHP Notice:  Undefined variable: return in /home/wwwroot/www.chengtianzhu.com/test.php on line 2
PHP Warning:  exec() has been disabled for security reasons in /home/wwwroot/www.chengtianzhu.com/test.php on line 2
PHP Notice:  Undefined variable: o in /home/wwwroot/www.chengtianzhu.com/test.php on line 3
NULL

第十一步:开启exec

首先要用find命令查找到php.ini所在位置

find / -name php.ini

得到好多结果,关注最后台一条信息

/usr/local/php/etc/php.ini

用VI修改一下

vi /usr/local/php/etc/php.ini

查找disable_functions = passthru,exec,system,chroot或者查找disable_functions,把exec删掉保存.
修改后要重启才能生效,这里的重启并不是重启nginx-一定要注意。
我这里使用的是Lnmp,使用lnmp reload

lnmp reload #或者 sudo /etc/init.d/php-fpm restart

这个时间再执行第十步的php test.php,显示结果为:

array(1) {
  [0]=>
  string(11) "hello world"
}

这时表示已经可以执行钩子(update.php),exec的代码了.回到你的本地测试一下,随便新增或者修改一些东西,再git提交.服务器显示已成功.

第十二步:恢复执行用户的 nologin

不要忘了第三步的时候修改了/etc/passwd配置,现在把 www 用户的 nologin 选项恢复回去哟

vi /etc/passwd

www:x:1001:1001::/home/www:/bin/bash
(改回原来的)
www:x:1001:1001::/home/www:/sbin/nologin

参考网站

  1. gitlab 通过 webhook 自动部署 https://www.jianshu.com/p/59a54e2e27d3
  2. Webhook 实践 —— 自动部署 https://segmentfault.com/a/1190000003908244?utm_source=tag-newest
  3. [后端]gitlab 之 webhook 自动部署 https://www.jianshu.com/p/00bc0323e83f

请我喝杯咖啡吧~

支付宝
微信