关于php-Apache网页项目采用php脚本打包成phar进行自动化部署的方式
一、相关环境配置
1、php5.6,jenkins
php的安装可以使用以下内容进行配置,以下代码会顺便把phar支持给打开的,酌情使用部分的代码。#因为当时采用了jenkins进行操作,所以这个流程写成了个流水线。
pipeline {
agent any
stages {
/*
stage('1 Download and Install PHP 5.6.4') {
steps {
//下载PHP5.6.4
bat 'cd C:\\ && curl -o php-5.6.40-Win32-VC11-x64.zip https://windows.php.net/downloads/releases/archives/php-5.6.40-Win32-VC11-x64.zip'
//解压到C盘根目录
bat 'powershell Expand-Archive -Path C:\\php-5.6.40-Win32-VC11-x64.zip -DestinationPath C:\\PHP5.6.4'
}
}
stage('2 Install PHP') {
steps {
bat '''
@echo off
set "PHP_DIR=C:\\PHP5.6.4"
rem 切换到PHP安装目录
cd /d %PHP_DIR%
rem 检查php.ini-development.ini文件是否存在,如果存在则重命名为php.ini
if exist php.ini-development.ini (
ren php.ini-development.ini php.ini
echo php.ini-development.ini 已成功修改为 php.ini
) else (
echo php.ini-development.ini 文件不存在
)
rem 执行安装PHP
echo Installing PHP...
setx PATH "%PATH%;%PHP_DIR% /M
echo PHP installation complete.
pause
'''
//检查是否安装完成
bat 'C:\\PHP5.6.4\\php.exe -v'
}
}
stage('3 Install PHar') {
steps {
bat '''
@echo off
set php_ini_path=C:\\PHP5.6.4\\php.ini
REM 检查 php.ini 文件是否存在
if not exist %php_ini_path% (
echo PHP 配置文件 php.ini 未找到。
pause
exit
)
REM 修改 phar.readonly 配置为 Off
findstr /C:"phar.readonly" %php_ini_path% >nul
if %errorlevel% equ 0 (
echo phar.readonly 已存在于 php.ini 中,将修改为 Off。
findstr /v /c:"phar.readonly" %php_ini_path% > %php_ini_path%.tmp
echo phar.readonly = Off >> %php_ini_path%.tmp
del %php_ini_path%
ren %php_ini_path%.tmp php.ini
echo phar.readonly 已修改为 Off。
) else (
echo phar.readonly 未在 php.ini 中找到,将添加配置为 Off。
echo phar.readonly = Off >> %php_ini_path%
echo phar.readonly 已添加并设置为 Off。
)
echo PHP 配置文件 php.ini 修改完成。
pause
'''
}
}
/*
stage('5 Destroy PHP') {
steps {
bat "dir /b C:\\*"
bat '''
del /q C:\\phar-2.0.0.tgz
del /q C:\\php-5.6.4.zip
del /q C:\\php-5.6.40-Win32-VC11-x64.zip
'''
bat '''
@echo off
REM 清除 C:\\PHP5.6.4 路径下的文件夹
rmdir /s /q C:\\PHP5.6.4
REM 清除与 PHP 相关的环境变量
setx PATH "%PATH:;C:\\PHP5.6.4\\php.exe=%" /m
setx PHP_PATH "" /m
setx EXT_PATH "" /m
setx PHAR_FILE "" /m
setx PHP_EXE "" /m
echo PHP 相关环境已清除。
pause
'''
bat "dir /b C:\\*"
}
}
*/
stage('6 modify PHP ini') {
steps {
bat "dir /b C:\\*"
bat "dir /b C:\\PHP5.6.4\\*"
bat '''
@echo off
set php_folder_path=C:\\PHP5.6.4
set php_ini_path=%php_folder_path%\\php.ini
set php_ini_development_path=%php_folder_path%\\php.ini-development
echo Renaming php.ini-development to php.ini...
ren %php_ini_development_path% php.ini
echo php.ini-development renamed to php.ini successfully.
echo Updating php.ini file...
findstr /C:"phar.readonly" %php_ini_path% >nul
if %errorlevel% == 0 (
echo Setting phar.readonly to Off...
findstr /v /c:"phar.readonly" %php_ini_path% >%php_ini_path%.tmp
echo phar.readonly = Off>>%php_ini_path%.tmp
del %php_ini_path%
ren %php_ini_path%.tmp php.ini
echo php.ini file updated successfully.
) else (
echo phar.readonly setting not found in php.ini file.
echo Please add the following line to php.ini:
echo phar.readonly = Off
)
echo Finished.
'''
bat "dir /b C:\\*"
}
}
}
}
jenkins安装详见相关的教程,正常安装即可。jenkins需要配置反向代理详见相关的教程,以及一些与pipeline相关的插件,不详细赘述。
二、jenkins的node进行配置
很显然,使用node是为了做jenkins的代理去操作目标服务器进行一种部署。
这里进行配置,我们create nodes(new node)
Number of executors 执行人人数尽量填1,保证运行过程中不会有第二个人启用它,因为部署的两个版本不同是很令人头疼的一件事。
远程工作目录 可以自定义一个jenkins目录,我一般使用/home/jenkins
标签 这是引用agent中需要使用的,告诉这个脚本在哪个node中进行执行。
用法和启用方式如图:
下面就是配置凭证了,最好采用一对秘钥的形式进行加密传输。
最后配置好git工具确保代理上可以正常使用git进行checkout。
节点配置完成后,尝试连接ok即可进行下一步。
三、使用pipeline在代理checkout并进行打包
pipeline {
agent {
#填写标签在这里,下面写个stage的hello,进行测试,没问题后进行以下操作
label 'xxx'
}
stages {
stage('Checkout from Git') {
steps {
echo 'Checkout from git...'
checkout scmGit(userRemoteConfigs:[[credentialsId: 'xxxxxx', url: 'https://gitee.com/xxx/xxxx.git']])
}
}
/*
stage('Generate and Run Shell Script') {
#在代码中,增加一个build.ini文件,用来做本次更新的版本号,如不需要此阶段可以忽略
steps {
script {
// 修改build.ini文件,定义本次新的版本号versionName
sh "cat build.ini"
def scriptContent = """#!/bin/bash
buildIniFile="build.ini"
versionName="1.1.3"
while IFS= read -r line; do
if [[ \$line == *"versionName = "* ]]; then
echo "versionName = \$versionName"
else
echo \$line
fi
done < "\$buildIniFile" > "\$buildIniFile.new"
mv "\$buildIniFile.new" "\$buildIniFile"
"""
writeFile file: "update_version.sh", text: scriptContent
sh "ls -l update_version.sh"
sh "bash update_version.sh"
sh "cat build.ini"
sh "rm update_version.sh"
}
}
}
*/
stage('Make PHAR') {
steps {
#使用工作目录下的工具使用脚本进行打包
echo 'Making PHAR'
sh '/opt/php-5.6.40/bin/php --define phar.readonly=0 create_phar.php'
}
}
stage('Copy to target') {
steps {
sh 'cp xxx.phar /opt/xxx/'
}
}
}
}
打包的代码采用脚本打包成phar的形式进行打包
<?php
$buildIni = parse_ini_file("build.ini");
$versionName = $buildIni['versionName'];
$meta = ["versionName" => $versionName];
// 在当前目录生成PHAR文件,Jenkins复制去目标位置
$buildRoot = realpath(".");
$finalName = "xxx.phar";//包名
$finalFile = "$buildRoot/$finalName";
$flag = FilesystemIterator::CURRENT_AS_FILEINFO | FilesystemIterator::KEY_AS_FILENAME | FilesystemIterator::SKIP_DOTS;
echo $finalFile . "\n";
if (file_exists($finalFile)) {
unlink($finalFile);
}
$phar = new Phar($finalFile);
$phar->setMetadata($meta);
$phar->startBuffering();
//当前代码下的某个文件夹进行打包部署
$itor = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("$buildRoot/xxx", $flag));
$phar->buildFromIterator($itor, "$buildRoot/");
$itor1 = new RecursiveIteratorIterator(new RecursiveDirectoryIterator("$buildRoot/xxx1", $flag));
$phar->buildFromIterator($itor1, "$buildRoot/");
$count = $phar->count();
$phar->stopBuffering();
echo "$count entries added.";
php的网页是不需要重启服务的,因此这边没有类似这样的操作。
四、使用包和包自带的版本号
定义在index.php中,一般这个指向的是前端的主页面的变量配置。
define('TMPL_PATH', 'phar://xxx.phar/xxx/');
定义在common中,引用包自带的版本号可以采用这样的形式。
/**
* 从PHAR文件取得当前系统的版本
* @return string 版本字串
*/
function get_system_version_from_phar() {
$phar = new Phar("xxx.phar");
if (!$phar->isFileFormat(Phar::PHAR)) {
return false;
}
$meta = $phar->getMetadata();
$versionName = $meta['versionName'];
return $versionName;
}
五、其它内容
1、遇到permission defined问题,可以尝试jenkins用户加入有写入权的用户组中即可解决。
2、不希望phar进入代码库,可以在.gitignore中定义需要进入代码库的内容。
*.phar
3、这是个大概的思路,请谨慎使用。