PHP项目RPM与DEB包制作

wen PHP项目 2

PHP项目RPM与DEB包制作:从零构建高效分发系统的完整指南

目录导读

  1. 为什么需要将PHP项目打包为RPM/DEB?
  2. RPM与DEB包的核心区别与适用场景
  3. 环境准备:构建工具链安装与配置
  4. PHP项目RPM包制作实战(基于SPEC文件)
  5. PHP项目DEB包制作实战(基于Debian规则)
  6. 包依赖管理与PHP扩展处理技巧
  7. 自动化构建与持续集成方案
  8. 常见问题解答(FAQ)

为什么需要将PHP项目打包为RPM/DEB?

PHP项目通常以源码形式部署,但这种方式存在明显痛点:依赖手工配置、环境差异导致故障、回滚困难,将PHP项目打包为原生系统包(如CentOS/RHEL的RPM或Ubuntu/Debian的DEB),能实现以下价值:

PHP项目RPM与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.jsonpublic/index.php
  • 拷贝所有依赖到源码树:composer install --no-dev
  • 压缩源码包,放入对应目录:
    • RPM:cp phpapp-1.0.0.tar.gz ~/rpmbuild/SOURCES/
    • DEB:dh_make会自动引用源码

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服务器,标准化后的包管理将显著提升部署效率与运维稳定性,建议从简单项目开始实践,逐步将复杂依赖和扩展纳入打包逻辑。

上一篇PHP项目Phar打包与分发

下一篇当前分类已是最新一篇

抱歉,评论功能暂时关闭!