自动化部署 - Laravel Deploy实战

Deployer 是一个基于 SSH 协议的无侵入 web 项目部署工具,因为它不需要你在目标服务器上装什么服务之类的东西即可使用,它的原理就是通过 SSH 到你的机器去创建目录,移动文件,执行指定的动作来完成项目的部署。他支持多种框架:LaravelYii

流程:

  • 在本地使用 composer 安装 deployer
  • Linux 服务器添加账户与配置权限
  • 项目 git 仓库允许服务器访问(clone 代码)
  • 部署我们的 web 项目

安装deploy

官网:https://deployer.org/docs/installation.html
我这里是局部安装,大家可以选择命令式全局安装或者composer全局安装,根据大家需要求选择。

我这里直接安装了一个新的laravel项目,然后准备对他进行deploy初始化。

php vendor/bin/dep init

# 这里会叫你去设置框架类型和远程仓库

# 最后成功啦就会在项目根目录看见一个deploy.php 

配置deploy

  • 配置文件
<?php
namespace Deployer;

require 'recipe/laravel.php';

set('laravel-server', '192.168.1.1);

// Project name
set('application', 'laravel-dep');

// Project repository
set('repository', 'git@code.aliyun.com:testsmile/laravel-dep.git');

// [Optional] Allocate tty for git clone. Default value is false.
set('git_tty', true); 

// 分享文件即目录,通常也不用改,默认包含了 storage 目录
add('shared_files', []);
add('shared_dirs', []);

// 可写目录,一般不用改
add('writable_dirs', []);
set('allow_anonymous_stats', false);

// 保存最近五次部署,这样的话回滚最多也只能回滚到前 5 个版本
set('keep_releases', 5);

set('writable_use_sudo', false);

// 配置服务器主机
host(get('laravel-server'))
    ->stage('production')
    ->set('branch', 'master') // 最新的主分支部署到生产机
    ->user('root')
    ->port(22)
    ->set('http_user', 'www-data') // 这个与 nginx 里的配置一致
    ->set('deploy_path', '/var/www/{{application}}')
    ->identityFile('~/.ssh/deployerkey') # 这里直接指定sshkey就不需要密码啦
    ->forwardAgent(true);
    
// 这算是个自定义任务示例
task('build', function () {
    run('cd {{release_path}} && build');
});

// 如果部署失败,自动解除部署锁定状态,以免影响下次执行
after('deploy:failed', 'deploy:unlock');

// 执行数据库迁移 我这里就不迁移了 大家根据情况来
//before('deploy:symlink', 'artisan:migrate');

部署

php vendor/bin/dep deploy production -vvv

# 期间会看到很多的部署日志输出 如果有什么错误对应解决就行,我这边有些扩展没有 我安装了一下就好啦
  • Unable to prepare route [api/user] for serialization. Uses Closure.

这个问题是闭包路由无法缓存,将apiuser路由和首页那个闭包路由改成使用控制器或者注释掉,要记得提交代码

首次部署设置一下envnginx配置也是需要创建的。对于 .env 文件,存放于目标主机的 /path/to/project/shared/ 目录下。

修改 .env 后记得重新缓存配置 php artisan config:cache

另外需要注意的是配置 nginx 站点时,网站根目录应该为 /path/to/project/current/public。如果使用 supervisor 之类的,相关的目录在配置时也要注意了。

部署后目录的结构及相关说明

| projectname
    |--- @current -> releases/<num>
    |--- .dep
        |--- releases 一个文本文件,里面存着各次部署的时间、次数序号(或者说版本号)信息
    |--- releases // 目录下根据配置保存近几次部署,更早的则会被自动清理
        |--- 1
        |--- 2
        |--- .
        |--- .
        |--- <num>
            |--- 目录中是项目的实际代码
            |--- 包括 .git, vendor, .env, storage ...
            |---  .env, storage 实际通过 symlink 链接到 shared 目录下对应的文件上
    |--- shared
        |--- storage // 即 laravel 项目的 storage 文件夹
        |--- .env // 即 laravel 项目的 .env

每次部署更新,会在 releases 下新建文件夹如 num,拉取对应的最新代码,安装 composer 依赖完成一些其它自定义任务,并将 storage, .env 链接到 shared 文件夹下的那两个上去,然后项目根目录下的 current 通过 syslink 链接到这个新文件夹 num 上,这算是其动作的基本原理,网站在部署过程中能继续访问也得益于此。

.envstorage 下的一些未加入代码库中的内部,部署时不会自动更新,因此有些情况下需要手动处理。

nginx配置

server {
    listen 80;
    server_name test.aoppp.com;
    root /var/www/laravel-dep/current/public;
    index index.php index.html index.htm;

    location / {
         try_files $uri $uri/ /index.php$is_args$args;
    }

    if (!-e $request_filename) {
        rewrite ^.*$ /index.php last;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass localhost:9000;
        fastcgi_index index.php;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PHP_VALUE "error_log=/var/log/nginx/application_php_errors.log";
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}

这里要注意,你php-fpmlistensock就采用sock,根据自己来。

最终部署成功

  • 参考

这个也是简单部署
部署权限看这个

您的支持是对我最大的鼓励!

发表于: 作者:憧憬。
关注互联网以及分享全栈工作经验的原创个人博客和技术博客,热爱编程,极客精神
Github 新浪微博 SegmentFault 掘金专栏