因按照官方文档使用 Docker Swarm 集群搭建的方式卡在注册 gitlab-runner 的环节上,加上 Gitlab 内存占用偏高,服务器成本增加的因素,进而考虑使用 Supervisor + Git 钩子进行部署的方案

先将 Hyperf 项目根目录中的 Dockerfile 拉取下来,生成本地镜像(假设项目名称叫project)

docker build -t project-prod:v1 . -f Dockerfile

接着启动容器,关键是需要开放9501和666端口,前者用来运行项目,后者用来钩子监听。与consul的连接这里选择link方式

docker run --name project-prod -v /opt/www/project:/opt/www -p 9501:9501 -p 666:666 -it --privileged -u root --link consul-01 --entrypoint /bin/sh project-prod:v1

进入容器后,第一件事先把项目的第三方依赖装好,composer使用国内腾讯云的源

composer config -g repo.packagist composer https://mirrors.cloud.tencent.com/composer/
composer update

再装 htop 和 supervisor

apk add htop
apk add supervisor

注意这里使用 apk 命令来管理包集成主要是因为 Hyperf 官方镜像是基于 Alpine 的轻量级 Linux 发行版来搭建的。

然后按官方文档上的说明进行supervisor的项目配置

mkdir /etc/supervisord.d
cp /etc/supervisord.conf /etc/supervisord.d/supervisord.conf
vi /etc/supervisord.d/supervisord.conf

继续在文件末尾添加

[program:project]
directory=/opt/www/
command=php ./bin/hyperf.php start
user=root
autostart=true
autorestart=true
startsecs=1
startretries=3
stderr_logfile=/opt/www/runtime/stderr.log
stdout_logfile=/opt/www/runtime/stdout.log

再然后创建runtime目录,并启动supervisor

mkdir runtime
supervisord -c /etc/supervisord.d/supervisord.conf

至此生产环境中的项目搭建已经完成了。接下来进行钩子调试,主要是 Git 拉取时需要输入账号密码,所以先让 Git 设置记录账号密码,保证后续拉取时不需再输入

git config --global credential.helper store

创建钩子执行文件

mkdir hook
cd hook
touch hook.php
vi hook.php

代码很简单

$data = file_get_contents('php://input');
$data = json_decode($data, true);
if ($data['password'] == 'fantasticbin') {
    echo shell_exec('cd /opt/www/ \
                        && git pull origin master 2>&1 \
                        && composer dump-autoload -o \
                        && php bin/hyperf.php \
                        && supervisorctl restart project');
    echo date('Y-m-d H:i:s');die;
}
echo 'you are dog!';

接着挂起钩子监听

cd ../
php -S 0.0.0.0:666 -t hook/

然后进入代码托管平台,发起钩子调试请求,在控制台输入账号密码后,拉取成功

紧接着就剩下把钩子监听程序配置进 supervisor 来守护了

vi /etc/supervisord.d/supervisord.conf

在末尾追加

[program:hook]
directory=/opt/www/
command=php -S 0.0.0.0:666 -t hook/
user=root
autostart=true
autorestart=true
startsecs=1
startretries=3

最后让 supervisor 重新加载配置文件生效

supervisorctl update

搞定