PHP项目RPM与DEB包制作:从零构建高效分发系统的完整指南
目录导读
- 为什么需要将PHP项目打包为RPM/DEB?
- RPM与DEB包的核心区别与适用场景
- 环境准备:构建工具链安装与配置
- PHP项目RPM包制作实战(基于SPEC文件)
- PHP项目DEB包制作实战(基于Debian规则)
- 包依赖管理与PHP扩展处理技巧
- 自动化构建与持续集成方案
- 常见问题解答(FAQ)
为什么需要将PHP项目打包为RPM/DEB?
PHP项目通常以源码形式部署,但这种方式存在明显痛点:依赖手工配置、环境差异导致故障、回滚困难,将PHP项目打包为原生系统包(如CentOS/RHEL的RPM或Ubuntu/Debian的DEB),能实现以下价值:

- 标准化部署:通过包管理器一键安装、升级、卸载
- 依赖自动解析:自动处理PHP版本、扩展、数据库驱动等依赖
- 可追溯性:每个包包含版本号、变更日志、数字签名
- 安全合规:企业级环境强制要求包管理审计
典型场景:将基于Laravel/Symfony的PHP应用打包为rpm,部署到数十台生产服务器。
RPM与DEB包的核心区别与适用场景
| 特性 | RPM (Red Hat系列) | DEB (Debian系列) |
|---|---|---|
| 所属发行版 | CentOS, RHEL, Fedora | Ubuntu, Debian, Mint |
| 打包规范 | SPEC文件 + rpmbuild | debian目录 + dpkg-deb |
| 包格式 | .rpm | .deb |
| 依赖管理 | yum/dnf | apt |
| 元数据字段 | Requires, Provides | Depends, Provides |
| 脚本支持 | %pre, %post, %preun, %postun | preinst, postinst, prerm, postrm |
选择建议:若目标服务器以CentOS为主,优先RPM;若以Ubuntu为主,选DEB,混合环境需双包并行构建。
环境准备:构建工具链安装与配置
1 RPM构建环境
# CentOS/RHEL 7/8/9
yum install -y rpm-build rpmdevtools gcc make
# 初始化构建目录结构
rpmdev-setuptree # 生成 ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
2 DEB构建环境
# Ubuntu/Debian apt install -y build-essential debhelper dh-make devscripts # 生成模板 dh_make --createorig -p phpapp-1.0.0
3 PHP项目准备
- 确保源码目录规范,包含
composer.json、public/index.php - 拷贝所有依赖到源码树:
composer install --no-dev - 压缩源码包,放入对应目录:
- RPM:
cp phpapp-1.0.0.tar.gz ~/rpmbuild/SOURCES/ - DEB:
dh_make会自动引用源码
- RPM:
PHP项目RPM包制作实战
步骤1:编写SPEC文件 (~/rpmbuild/SPECS/phpapp.spec)
Name: phpapp
Version: 1.0.0
Release: 1%{?dist}
Summary: PHP Application Deployment Package
Group: Applications/Web
License: MIT
URL: https://example.com
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
# 依赖声明
Requires: php >= 7.4, php-mbstring, php-pdo, php-xml, nginx
%description
PHP Application packaged as RPM for automated deployment.
Features: Laravel backend, MySQL support, RESTful API.
%prep
%setup -q
%build
# PHP项目通常无需编译,但可执行自定义脚本
# composer install --no-dev --optimize-autoloader
cd %{builddir}
composer install --no-dev --no-interaction --prefer-dist
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}%{_datadir}/nginx/html/%{name}
cp -a * %{buildroot}%{_datadir}/nginx/html/%{name}/
# 设置存储目录权限
mkdir -p %{buildroot}%{_datadir}/nginx/html/%{name}/storage/logs
mkdir -p %{buildroot}%{_datadir}/nginx/html/%{name}/bootstrap/cache
%files
%defattr(-,nginx,nginx,-)
%{_datadir}/nginx/html/%{name}/**/*
%attr(755,nginx,nginx) %{_datadir}/nginx/html/%{name}/artisan
%post
# 安装后执行:初始化数据库、配置缓存
/usr/bin/php %{_datadir}/nginx/html/%{name}/artisan migrate --force
systemctl reload nginx 2>/dev/null || true
%preun
# 卸载前清理:备份数据库
/usr/bin/php %{_datadir}/nginx/html/%{name}/artisan db:backup
%changelog
* Mon Jan 20 2025 Developer Name <dev@example.com> - 1.0.0-1
- Initial version with Laravel 8 support
步骤2:构建RPM包
rpmbuild -ba ~/rpmbuild/SPECS/phpapp.spec # 生成的包位于 ~/rpmbuild/RPMS/x86_64/phpapp-1.0.0-1.el8.x86_64.rpm
关键点解析
%files段:使用%defattr设定默认属主,PHP项目建议用nginx用户%post脚本:常用于初始化数据目录、执行migration、重启服务- 依赖处理:通过
Requires明确php版本和扩展,避免运行时缺失
PHP项目DEB包制作实战
步骤1:初始化Debian打包目录
mkdir phpapp-1.0.0 cd phpapp-1.0.0 # 创建debian目录 dh_make --createorig --indep --package phpapp --version 1.0.0 # 编辑规则文件:debian/control, debian/rules, debian/postinst等
步骤2:核心文件配置
debian/control(依赖声明)
Source: phpapp
Section: web
Priority: optional
Maintainer: Developer Name <dev@example.com>
Build-Depends: debhelper (>= 11), composer
Standards-Version: 4.1.4
Homepage: https://example.com
Package: phpapp
Architecture: all
Depends: php (>= 7.4), php-mbstring, php-pdo, php-xml, nginx, ${misc:Depends}
Description: PHP Application Deployment Package
PHP application with Laravel, MySQL support, RESTful API.
debian/rules(构建指令)
#!/usr/bin/make -f
%:
dh $@
override_dh_auto_build:
composer install --no-dev --no-interaction --prefer-dist
override_dh_auto_install:
mkdir -p debian/phpapp/usr/share/nginx/html/phpapp
cp -a * debian/phpapp/usr/share/nginx/html/phpapp/
# 创建所需子目录
mkdir -p debian/phpapp/usr/share/nginx/html/phpapp/storage/logs
mkdir -p debian/phpapp/usr/share/nginx/html/phpapp/bootstrap/cache
debian/postinst(安装后脚本)
#!/bin/bash set -e APP_PATH="/usr/share/nginx/html/phpapp" cd $APP_PATH php artisan migrate --force php artisan config:cache # 设置正确权限 chown -R www-data:www-data storage bootstrap/cache systemctl reload nginx || true
步骤3:构建DEB包
dpkg-buildpackage -us -uc -b # 生成的包位于上级目录:phpapp_1.0.0-1_all.deb
DEB特有注意事项
- 使用
Architecture: all表示纯PHP项目不依赖硬件架构 debian目录中的脚本必须具有可执行权限(chmod 755)- 依赖声明用
Depends,逗号分隔
包依赖管理与PHP扩展处理技巧
1 动态依赖处理
PHP项目常通过composer.json声明扩展,但打包时需手动列举所有依赖。推荐方案:
- 在SPEC/control中声明最低PHP版本和必需扩展
- 使用元包(meta-package)将多个PHP扩展捆绑,如:
# RPM虚拟包 Provides: php-extensions-required
- 或使用
php-pecl扩展通过%{_libdir}/php/modules/路径包含
2 处理PHP-FPM服务依赖
# RPM写法 Requires(pre): php-fpm %post systemctl restart php-fpm # DEB写法 Depends: php-fpm (>= 7.4)
注意:避免循环依赖,如php-fpm依赖nginx,nginx又反向依赖包。
3 配置文件保护
RPM通过%config(noreplace)标记:%config(noreplace) %{_sysconfdir}/phpapp/.env
DEB通过conffiles文件:/etc/phpapp/.env
自动化构建与持续集成方案
1 使用GitHub Actions双包构建
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
os: [ubuntu-22.04, centos-7]
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
if [ "${{ matrix.os }}" = "ubuntu-22.04" ]; then
apt update && apt install -y build-essential debhelper
dpkg-buildpackage -us -uc -b
else
yum install -y rpm-build
rpmbuild -ba phpapp.spec
fi
- uses: actions/upload-artifact@v4
with:
name: phpapp-${{ matrix.os }}
path: ./*.deb
2 使用dockerized构建环境
FROM centos:8 as rpm-builder WORKDIR /root RUN yum install -y rpm-build COPY phpapp-1.0.0.tar.gz /root/rpmbuild/SOURCES/ COPY phpapp.spec /root/rpmbuild/SPECS/ RUN rpmbuild -ba /root/rpmbuild/SPECS/phpapp.spec
3 版本管理策略
- 采用语义化版本:
MAJOR.MINOR.PATCH-RELEASE - 变更日志自动生成:
git log --oneline生成%changelog - GPG签名:
rpm --addsign phpapp-1.0.0-1.x86_64.rpm
常见问题解答(FAQ)
Q1:打包后的PHP项目为何无法访问,提示缺少PHP扩展?
A:检查SPEC或control中的Requires/Depends是否正确,常见遗漏:php-json(PHP 7.4+内建,但需显式声明)、php-mysqlnd(替代php-mysql),可运行rpm -qpR phpapp.rpm查看实际依赖。
Q2:如何将.env配置文件打包并保护?
A:将.env.example作为配置文件包含,安装后通过%post脚本询问用户创建或复制默认值,生产环境建议使用环境变量注入,不打包.env文件。
Q3:RPM包安装时报文件冲突:/usr/share/nginx/html/phpapp已被占用?
A:在%files段中使用%exclude排除目标目录中的现有文件,或使用%dir声明目录归属,更佳实践:不在一个包中覆盖其他包的目录结构。
Q4:DEB包构建时提示dh_install: cannot find file?
A:检查debian/install文件中目标路径是否正确,或使用override_dh_auto_install手动复制文件,常见错误:忘记以debian/phpapp/为前缀。
Q5:如何在一条命令中构建RPM和DEB?
A:使用make工具结合Makefile,根据目标参数调用不同构建脚本,示例如下:
build-rpm:
rpmbuild -ba phpapp.spec
build-deb:
dpkg-buildpackage -us -uc -b
通过本指南,您应能系统掌握PHP项目RPM与DEB包的制作方法,无论是面向CentOS还是Ubuntu服务器,标准化后的包管理将显著提升部署效率与运维稳定性,建议从简单项目开始实践,逐步将复杂依赖和扩展纳入打包逻辑。