小白上手RPM包制作

发布于:2025-05-15 ⋅ 阅读:(11) ⋅ 点赞:(0)

目录

rpm常用命令

安装环境-Ruby

安装环境-fpm

关于服务器

打包-打包二进制工程 

.fpm配置文件

打包-打没有文件的包

RPM 包微调

命令行参数 fpm --help

RPM 签名 

打包-制作NGINX的RPM包

关于rpmbuild 简单使用  

打包之前的准备工作

rpmbuild 打包 - sniproxy 为例 

客户端安装验证

参阅:


打包其实是一个简单的工作,编译才是需要花大精力去学习的。

        FPM(Effing Package Management)它简化了软件包的构建过程,使得创建和打包软件变得更加简单和快捷,如果需要精确控制 RPM 包的构建过程 rpmbuild 会更适合你。

        FPM 支持多个平台,可以对 rpm包、普通目录、没有任何文件的包、python虚拟环境 等等 进行打包操作,输出个格式也很多,本次主要对.rpm 包格式测试。

感觉将软件与安装或者脚本结合起来做成一个rpm包非常有趣,制作成rpm后 管理部署也是非常方便。

rpm常用命令

#查询 
	-q			#查询       			 #后面接软件包name名称
    -q -p		#查询软件包的文件		 #后面接包的文件名
    -q  -l		#查询软件包中的文件列表	 #后面接软件包name名称 
    -q  -pl		#查询软件包中的文件列表	 #后面接包的文件名
    
    -q -a		#查询所有安装的软件包 
    -q -f		#查询属于哪个软件包 【安装后】        		    #后面统一接文件
    -q -if		#查询属于哪个软件包 【安装后】包的属性信息   	#后面统一接文件
	-q -lf      #查询属于哪个软件包 【安装后】包的文件信息   	#后面统一接文件 
   
#安装与删除
    -ivh		#安装
    -uvh		#升级
    -e			#删除
    --force 	#忽略软件包及文件的冲突,强制安装
    --nodeps 	#不检查依赖性关系 

#例如
[root@t33 ~]# rpm -qp --scripts    webhook-2.8.0-1.el7.x86_64.rpm    #查看脚本
[root@t33 ~]# rpm -qpi  webhook-2.8.0-1.el7.x86_64.rpm  			 #rpm属性
[root@t33 ~]# rpm -qpR   webhook-2.8.0-1.el7.x86_64.rpm 		 	 #显示依赖
[root@t33 ~]# rpm -qR  rpm-build 									 #显示依赖  rpm-build本身就有很多依赖项必读perl、zip
[root@t33 ~]# rpm -qp devtools-1.0-1.noarch.rpm --requires    		 #也可以用 rpm -qpR   #显示依赖
[root@t33 ~]# rpm -qpl webhook-2.8.0-1.el7.x86_64.rpm 				 #包的目录结构
[root@t33 ~]# rpm -ql webhook  										 #安装之后的目录结构
[root@t33 ~]# rpm -K devtools-1.0-1.noarch.rpm 						 #验证
[root@t33 ~]#  rpm -qp --changelog nginx-1.28.0-release.el7.x86_64.rpm 

安装环境-Ruby

dotenv requires Ruby version >= 3.0.    如果出现这个报错  就需要安装 RVM,并升级Ruby 

yum install ruby-devel gcc make rpm-build rubygems ruby squashfs-tools  #不接 -y  自己可以确认一下

#安装ruby环境   ruby3.0
[root@t33 nginx]# ruby  -v
ruby 2.0.0p648 (2015-12-16) [x86_64-linux]

#dotenv requires Ruby version >= 3.0.	如果出现这个报错  需要升级Ruby ,如果没有就不需要安装rvm 

#安装Ruby 管理工具 rvm
[root@t33 nginx]# curl -sSL https://get.rvm.io | bash -s stable     #需要网络			
[root@t33 nginx]# bash rvm-installer.sh  stable  					#也需要网络
#手动安装
[root@t33 rvm]# cd /usr/local/src/rvm
[root@t33 rvm]# tar -xvf rvm-1.29.12.tar.gz 
[root@t33 rvm]# cd  rvm-1.29.12
[root@t33 rvm-1.29.12]# ./install --path /usr/local/rvm				#安装
Creating group 'rvm'
Installing RVM to /usr/local/rvm/
Installation of RVM in /usr/local/rvm/ is almost complete:

  * First you need to add all users that will be using rvm to 'rvm' group,
    and logout - login again, anyone using rvm will be operating with `umask u=rwx,g=rwx,o=rx`.

  * To start using RVM you need to run `source /etc/profile.d/rvm.sh`
    in all your open shell windows, in rare cases you need to reopen all shell windows.
  * Please do NOT forget to add your users to the rvm group.
     The installer no longer auto-adds root or users to the rvm group. Admins must do this.
     Also, please note that group memberships are ONLY evaluated at login time.
     This means that users must log out then back in before group membership takes effect!
     
[root@t33 rvm-1.29.12]# source /etc/profile.d/rvm.sh				#加载  可以写入vim /root/.bash_profile 文件中
[root@t33 src]# rvm list know
[root@t33 src]# rvm install 3		#安装Ruby 下载慢

#下载慢更换镜像源
[root@t33 src]# rvm get stable --auto-dotfiles
Downloading https://get.rvm.io
[root@t33 src]# rvm install ruby-3.0.0 --url https://mirrors.tuna.tsinghua.edu.cn/rvm   #指定
[root@t33 src]# export rvm_url="https://mirrors.tuna.tsinghua.edu.cn/rvm/"				#或者先配置环境变量

[root@t33 src]# ruby  -v
ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]
[root@t33 src]# rvm use 3.0.0 			切换Ruby版本

#隔离项目,解决冲突          --暂时不需要。
rvm gemset create my_project
rvm use 2.7.2@my_project

安装环境-fpm

https://fpm.readthedocs.io/en/latest/  #fpm——安装使用文档

#删除官方源 添加国内源
[root@t33 nginx]# gem sources -l
[root@t33 nginx]# gem sources --add https://mirrors.cloud.tencent.com/rubygems/      #二选一
[root@t33 nginx]# gem sources --add http://mirrors.aliyun.com/rubygems/				 #二选一
[root@t33 nginx]# gem sources --remove https://rubygems.org/

#安装 fpm 
[root@t33 nginx]# gem install --no-document fpm  不生成文档的 ri(Ruby 文档索引),不生成 RDoc 文档 
Successfully installed stud-0.0.23
Successfully installed dotenv-3.1.8
Successfully installed insist-1.0.0
Successfully installed mustache-0.99.8
Successfully installed clamp-1.3.2
Successfully installed cabin-0.9.0
Successfully installed pleaserun-0.0.32
Successfully installed arr-pm-0.0.12
Successfully installed backports-3.25.1
Successfully installed fpm-1.16.0

#也可以使用 -minimal-deps 方式安装
[root@t33 nginx]# gem install --no-document --minimal-deps dotenv:2.8.1 fpm  #--no-document   与  --no-ri --no-rdoc 类似功能

[root@t33 webhook]# fpm -v
1.16.0

关于服务器

打包服务器

           CentOS Linux release 7.9.2009 (Core)
           fpm 1.16.0
客户端 : VMware系统,新安装后做好镜像, 时刻准备还原

            CentOS Linux release 7.9.2009 (Core)   

打包-打包二进制工程 

#打包二进制工程 
[root@t33 webhook]# ll 	#--例如 编译好的webhook 制作成rpm包  https://github.com/adnanh/webhook
total 15704
-rw-r--r-- 1 www  www       285 May  6 16:20 hooks.yaml
-rwxr-xr-x 1 www  www  10579739 Jun 21  2021 webhook

#https://fpm.readthedocs.io/en/latest/getting-started.html 参照命令参数选项 执行
[root@t33 webhook]# fpm \
  -s dir -t rpm \							#-s [必须]源来类型, -t [必须]构建类型	
  -p webhook-2.8.0-1.el7.x86_64.rpm  \		#包命名,可以是任意名,不过也有约定的规范,看一看其他的就行
  --name webhook \							#程序名称
  --license agpl3 \							#AGPL 3.0 许可证
  --version 2.8.0 \							#版本
  --architecture all \						#运行的系统类型,可以在包名上体现	 x86_64/amd64、all/noarch/any	
  --depends bash \							#依赖项
  #--depends lolcat \  						#先去掉 依赖报错
  --description "webhook is a lightweight configurable tool written in Go!" \   #解释说明项:程序描述
  --url "https://github.com/adnanh/webhook" \									#解释说明项:项目的 URL 如果有			
  --maintainer "adnanh" \														#解释说明项:作者
  webhook=/export/app/webhook/webhook hooks.yaml=/export/app/webhook/hooks.yaml #[必须]文件安装目录指定

Created package {:path=>"webhook-2.8.0-1.el7.x86_64.rpm"}

[root@localhost src]# rpm -qpR   webhook-2.8.0-1.el7.x86_64.rpm 	#依赖项
bash
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(CompressedFileNames) <= 3.0.4-1


[root@t33 webhook]# rpm -qpi   webhook-2.8.0-1.el7.x86_64.rpm  #rpm属性
Name        : webhook
Version     : 2.8.0
Release     : 1
Architecture: noarch
Install Date: (not installed)
Group       : default
Size        : 10580024
License     : agpl3
Signature   : (none)
Source RPM  : webhook-2.8.0-1.src.rpm
Build Date  : Tue 06 May 2025 04:25:14 PM CST
Build Host  : t33
Relocations : / 
Packager    : adnanh
Vendor      : none
URL         : https://github.com/adnanh/webhook
Summary     : webhook is a lightweight configurable tool written in Go!
Description :
webhook is a lightweight configurable tool written in Go!

[root@t33 webhook]#  rpm -qp --scripts    webhook-2.8.0-1.el7.x86_64.rpm  #暂时还没脚本
[root@t33 webhook]# 

#客户端安装
[root@localhost src]# yum install webhook-2.8.0-1.el7.x86_64.rpm   #--depends lolcat  先去掉
·······
--> Finished Dependency Resolution
Error: Package: webhook-2.8.0-1.noarch (/webhook-2.8.0-1.el7.x86_64)
           Requires: lolcat
······
[root@localhost src]# yum install webhook-2.8.0-1.el7.x86_64.rpm 
Installed:
  webhook.noarch 0:2.8.0-1                                                                                                                           
Complete!

[root@localhost src]# rpm -ql webhook   
/export/app/webhook/hooks.yaml
/export/app/webhook/webhook
[root@localhost src]# ll /export/app/webhook/    #目录也是正常的 
total 10336
-rw-r--r--. 1 root root      285 May  6  2025 hooks.yaml
-rwxr-xr-x. 1 root root 10579739 Jun 21  2021 webhook

成功!

.fpm配置文件

配置文件,将参数写入配置文件,简化命令,命令行可以覆盖配置文件参数 

[root@t33 webhook]# vim .fpm
-s dir 
-t rpm 
-p webhook-2.8.0-1.el7.x86_64.rpm  
--name webhook 
--license agpl3 
--version 2.8.0 
--architecture all 
--depends bash 
--description 'webhook is a lightweight configurable tool written in Go!' 
--url "https://github.com/adnanh/webhook" 
--maintainer "adnanh"

webhook=/export/app/webhook/webhook hooks.yaml=/export/app/webhook/hooks.yaml 

[root@t33 webhook]# fpm              #这么执行就简单多了
Loading flags from rc file .fpm {:level=>:warn}
Additional options: -s dir -t rpm -p webhook-2.8.0-1.el7.x86_64.rpm --name webhook --license agpl3 --version 2.8.0 --architecture all --depends bash --description webhook is a lightweight configurable tool written in Go! --url https://github.com/adnanh/webhook --maintainer adnanh {:level=>:warn}
Additional arguments: webhook=/export/app/webhook/webhook hooks.yaml=/export/app/webhook/hooks.yaml {:level=>:warn}
Created package {:path=>"webhook-2.8.0-1.el7.x86_64.rpm"}

[root@t33 webhook]# fpm -t deb -p webhook-2.8.0-2.any.deb   #命令行覆盖了配置文件参数
Loading flags from rc file .fpm {:level=>:warn}
Additional options: -s dir -t rpm -p webhook-2.8.0-1.el7.x86_64.rpm --name webhook --license agpl3 --version 2.8.0 --architecture all --depends bash --description webhook is a lightweight configurable tool written in Go! --url https://github.com/adnanh/webhook --maintainer adnanh {:level=>:warn}
Additional arguments: webhook=/export/app/webhook/webhook hooks.yaml=/export/app/webhook/hooks.yaml {:level=>:warn}
Created package {:path=>"webhook-2.8.0-2.any.deb"}

root@ubuntu:~# sudo apt install ./webhook-2.8.0-2.any.deb             
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting 'webhook' instead of './webhook-2.8.0-2.any.deb'
webhook is already the newest version (2.8.0).
0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.
root@ubuntu:~# ll /export/app/webhook/					 #Ubuntu 的目录也正常
total 10344
drwxr-xr-x 2 root root     4096 May  6 09:33 ./
drwxr-xr-x 3 root root     4096 May  6 09:33 ../
-rw-r--r-- 1 root root      285 May  6 08:20 hooks.yaml
-rwxr-xr-x 1 root root 10579739 Jun 21  2021 webhook*

 #Ubuntu 相关的命令
root@ubuntu:~# dpkg --contents webhook-2.8.0-2.any.deb   #查看 .deb 包的内容
root@ubuntu:~# dpkg --field webhook-2.8.0-2.any.deb      #查看 .deb 包的属性信息
root@ubuntu:~# dpkg -i webhook-2.8.0-2.any.deb  		 # 安装	

打包-打没有文件的包

empty包类型非常适合创建用于将依赖关系组合在一起的“元”包   解决依赖关系的,我觉得系统初始化是可以使用的

#制作一个init的元包 打包net-tools、 psmisc、 bind-utils、 yum-utils 软件  使用-d 参数添加
[root@t33 rpm]# cd empty/       #换一个目录       
[root@t33 empty]# fpm -s empty -t rpm -n devtools -a all -d net-tools -d psmisc -d bind-utils -d yum-utils  
Created package {:path=>"devtools-1.0-1.noarch.rpm"}
[root@t33 empty]# rpm -qp devtools-1.0-1.noarch.rpm --requires    #也可以用 rpm -qpR   #显示依赖
net-tools
psmisc
bind-utils
yum-utils
rpmlib(PayloadFilesHavePrefix) <= 4.0-1
rpmlib(CompressedFileNames) <= 3.0.4-1

[root@t33 empty]# rpm -qpl devtools-1.0-1.noarch.rpm 
(contains no files)
[root@localhost src]# rpm -ql  devtools             #或者客户端安装完成之后
(contains no files)
[root@t33 empty]# rpm -K devtools-1.0-1.noarch.rpm  #验证
devtools-1.0-1.noarch.rpm: sha1 md5 OK

RPM 包微调

#制作初始包
[root@t33 empty]# fpm -s empty -t rpm -n devtools -a all -d net-tools -d psmisc -d bind-utils -d yum-utils
Created package {:path=>"devtools-1.0-1.noarch.rpm"}

[root@t33 empty]# rpm -qpi devtools-1.0-1.noarch.rpm 
Name        : devtools
Version     : 1.0
Release     : 1					
Architecture: noarch			
···

#做出调整 
==> Release改成2
==> Architecture改成 all
==> 添加依赖 lrszs

[root@t33 empty]# fpm -s rpm -t rpm  --iteration 2 -a noarch  -d lrszs  devtools-1.0-1.noarch.rpm 
Created package {:path=>"devtools-1.0-2.noarch.rpm"}
[root@t33 empty]# rpm -qpi devtools-1.0-2.noarch.rpm 
Name        : devtools
Version     : 1.0
Release     : 2
Architecture: noarch
···

命令行参数 fpm --help

https://fpm.readthedocs.io/en/latest/cli-reference.html
#常规选项
-C --chdir				#指定打包的相对路径,类似于buildroot.  默认当前位置
-a --architecture		#运行的系统类型,可以在包名上体现	 x86_64/amd64、all/noarch/any	
-d --depends			#依赖项
-f --force				#强制覆盖
-m --maintainer 		#解释说明项:作者
-n --name 				#程序名称
-p --package			#包存放路径
-s --input-type			#[必须] 源 dir/empty/rpm/python 等等 
-t --output-type		#[必须] 构建类型 deb/rpm 等等
-v --version 			#版本
-x --exclude			#排除文件,可以多次指定

--config-files			#标记为配置文件,可以多次指定
--conflicts 			#冲突软件,可以多次指定
--debug
--debug-workspace		#保留所有文件工作区
--verbose				#详细输出
--description			#解释说明项:程序描述
--directories			#目录标记为由包拥有  --感觉用出不大,需要的时候测试一下
--exclude-file			#排除文件	
--fpm-options-file      #添加配置文件 像默认的.fpm文件一样。
--inputs 				#输入文件路径。    --还没用上
--iteration				#软件包的版本号 1、2、3等   RPM 称之为“release”。FreeBSD 称之为“PORTREVISION”。Debian 称之为“debian_revision”。
--license 				#许可证 :AGPL 3.0 
--log 					#设置日志级别。值:error、warn、info、debug。
--replaces 				#此软件包替换的其他软件包/版本。
--url 					#解释说明项:为该包添加一个 url  一般是项目地址或者是官网地址
--vendor 				#解释说明项:此软件包的供应商名称

#显示作用
--no-auto-depends		#不自动列出此包中的任何依赖项
--no-depends			#不要列出此包中的任何依赖项

#感觉完整的安装步骤应该包含这6个脚本
--after-install 		#软件包安装后运行的脚本
--after-remove 			#软件包删除后运行的脚本
--after-upgrade 		#软件包升级后运行的脚本
--before-install 		#软件包安装前运行的脚本
--before-remove 		#删除软件包之前运行的脚本
--before-upgrade 		#在软件包升级前运行的脚本

#包的操作阶段 脚本
--rpm-posttrans 		#(仅限 rpm)posttrans 脚本  打包开始之前执行的脚本
--rpm-pretrans 			#(仅限 rpm)pretrans 脚本   打包完成之后执行的脚本
--rpm-init 				#(仅限 rpm)初始化脚本		
--rpm-verifyscript 		#(仅限 rpm)验证时运行的脚本

--template-scripts		# 使其他脚本 添加 <%= name %>  <%= version %>" 这类的变量
--template-value		# KEY=VALUE  给 template-scripts提供变量
--[no-]rpm-macro-expansion	#%pre %post %preun %postun 脚本中的安装时宏扩展

#rpm 类型特定参数 可以参照rpmbuild   
--rpm-attr					#(仅限 rpm)文件属性(%attr) -–rpm-attr 750,user1,group1:/some/file
--[no-]rpm-autoprov			#(仅限 rpm)启用 RPM 的 AutoProv 选项   	--默认就好
--[no-]rpm-autoreq			#(仅限 rpm)启用 RPM 的 AutoReq 选项		--默认就好
--[no-]rpm-autoreqprov		#(仅限 rpm)启用 RPM 的 AutoReqProv 选项 	--默认就好
--rpm-changelog FILEPATH	#(仅限 rpm)从 FILEPATH 内容添加变更日志
--rpm-compression none|xz|xzmt|gzip|bzip2	#(仅限 rpm)选择压缩方法。gzip 适用于大多数平台。
--rpm-compression-level [0-9]				#(仅限 rpm)选择压缩级别。0 为仅存储。9 为最大压缩。	
--rpm-os 					#(仅限 rpm)此 rpm 的目标操作系统	需要将其设置为“linux”。	-- 默认就好

--rpm-rpmbuild-define 		#(仅限 rpm)将 –define 参数传递给 rpmbuild。
--[no-]rpm-sign				#(仅限 rpm)将 –sign 传递给 rpmbuild
--rpm-summary SUMMARY		#(仅限 rpm)设置 RPM 摘要。如果设置了,则覆盖描述的第一行
--rpm-tag TAG				#(仅限 rpm)在 spec 文件中添加自定义标签。例如:–rpm-tag ‘Requires(post): /usr/sbin/alternatives’
--rpm-defattrdir ATTR		#(仅限 rpm)设置默认目录模式(%defattr)。
--rpm-defattrfile ATTR		#(仅限 rpm)设置默认文件模式(%defattr)。
--rpm-digest 				#(仅限 rpm)选择摘要算法  md5|sha1|sha256|sha384|sha512
--rpm-dist el7 				#(仅限 rpm)目标系统版本  可能体现在包命名中

RPM 签名 

#RPM 签名 防止修改-但不能阻止安装
[root@t33 empty]# yum install gnup rpm-sign

#生成密钥对时会使用/dev/random生成的真随机数(通过噪音产生),可能会因熵池不够而阻塞,需要安装rng-tools自动补充熵池:不安装等等就好了
[root@t33 empty]# gpg --gen-key     #测试 都回车就行
Is this correct? (y/N) y
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

[root@t33 empty]# gpg --list-keys    #列出
/root/.gnupg/pubring.gpg
------------------------
pub   2048R/AB318270 2025-05-14
uid                  devtools (GPG-RPM-KEY) <devtools@gmail.com>
sub   2048R/ED3925FF 2025-05-14

[root@t33 empty]# gpg --export -a "devtools" > RPM-GPG-KEY-devtools  #导出
[root@t33 empty]# ll
-rw-r--r-- 1 root root 1735 May 14 15:48 RPM-GPG-KEY-devtools

#rpm --addsign  调用是 rpmsign
rpmsign  支持
  --addsign                     sign package(s)
  --resign                      sign package(s) (identical to --addsign)
  --delsign                     delete package signatures

#方式一:
[root@t33 empty]# rpm --addsign --define "_gpg_name devtools "  devtools-1.0-1.noarch.rpm   #_gpg_name 可以写到.rpmmacros ,下面有介绍
Enter pass phrase: 				#回车,刚没配置密码
Pass phrase is good.
devtools-1.0-1.noarch.rpm:

[root@t33 empty]# rpm -qpi  devtools-1.0-1.noarch.rpm 
····
Signature   : RSA/SHA1, Wed 14 May 2025 03:51:47 PM CST, Key ID bc95d17cab318270
···

[root@t33 empty]# rpm --checksig devtools-1.0-1.noarch.rpm  
devtools-1.0-1.noarch.rpm: RSA sha1 ((MD5) PGP) md5 NOT OK (MISSING KEYS: (MD5) PGP#ab318270) 
[root@t33 empty]# rpm --import RPM-GPG-KEY-devtools
[root@t33 empty]# rpm --checksig devtools-1.0-1.noarch.rpm    #导入证书  再次验证
devtools-1.0-1.noarch.rpm: rsa sha1 (md5) pgp md5 OK
[root@t33 empty]# rpm -K devtools-1.0-2.noarch.rpm 		  	  #未添加证书的 没有pgp验证标志
devtools-1.0-2.noarch.rpm: sha1 md5 OK


#方式二: rpmbuild 在做包的时候加进去    未验证
[root@t33 empty]#  rpmbuild --sign --bb xxx.spec  

#然后可以放置在测试的yum源使用了
[root@localhost ~]# cat /etc/yum.repos.d/Centos-Base.repo
····
gpgkey=···

打包-制作NGINX的RPM包

[root@localhost src]# tar -xvf nginx-1.28.0.tar.gz 
[root@localhost src]# cd nginx-1.28.0
[root@localhost nginx-1.28.0]#  yum install  gcc gcc-c++ make libaio-devel pcre pcre-devel openssl-devel zlib-devel unzip libxslt-devel libxml2-devel gd-devel  perl-devel perl-ExtUtils-Embed gperftools  

#编译是个费神的工作,像nginx常用软件 编译问题都能搜到。 只是测试的话,开启的模块随意了。
[root@localhost nginx-1.28.0]# ./configure --prefix=/opt/app/nginx --user=www --group=www --with-compat --with-debug --with-file-aio --with-google_perftools_module --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_degradation_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_mp4_module --with-http_perl_module=dynamic --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-http_xslt_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-threads

Configuration summary
  + using threads
  + using system PCRE library
  + using system OpenSSL library
  + using system zlib library
#配置启动的时候  根据这些目录指定 
  nginx path prefix: "/opt/app/nginx"
  nginx binary file: "/opt/app/nginx/sbin/nginx"
  nginx modules path: "/opt/app/nginx/modules"
  nginx configuration prefix: "/opt/app/nginx/conf"
  nginx configuration file: "/opt/app/nginx/conf/nginx.conf"
  nginx pid file: "/opt/app/nginx/logs/nginx.pid"
  nginx error log file: "/opt/app/nginx/logs/error.log"
  nginx http access log file: "/opt/app/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

[root@localhost nginx-1.28.0]# make  & make install

[root@localhost nginx-1.28.0]# tree /opt/app/nginx/
/opt/app/nginx/
├── conf
│   ├── fastcgi.conf
│ 	···
│   ├── nginx.conf
│ 	···
│   └── win-utf
├── html
│   ├── 50x.html
│   └── index.html
├── logs
├── modules+
│   ├── ngx_http_image_filter_module.so
│ 	····
└── sbin
    └── nginx

#然后添加开机启动文件
[root@localhost rpm]# cd /usr/local/src/rpm/
[root@localhost rpm]# mv /opt/app/nginx .

[root@localhost rpm]# vim nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
LimitNOFILE=655350
LimitNPROC=655350
Type=forking
PIDFile=/opt/app/nginx/logs/nginx.pid
ExecStartPre=/usr/bin/rm -f /opt/app/nginx/logs/nginx.pid
ExecStartPre=/opt/app/nginx/sbin/nginx -t
ExecStart=/opt/app/nginx/sbin/nginx
ExecReload=/opt/app/nginx/sbin/nginx  -s reload
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true

[Install]
WantedBy=multi-user.target

#编辑打包脚本 --线上的话脚本还是要写的 健全一点 ,其他的 日志切割、配置文件调整 就先忽略了。
[root@localhost rpm]# vim before-install.sh    #安装前脚本
#!/bin/bash
getent passwd www
if [ $? -ne 0  ] 
then
        useradd www  -s /sbin/nologin 
fi
if [ ! -d /opt/app ]
then
        mkdir -p  /opt/app
fi
exit 0
[root@localhost rpm]# vim after-install.sh       #安装后脚本,开启启动的步骤也可以放到手动配置
#!/bin/bash
/bin/cp -f nginx.service /usr/lib/systemd/system/nginx.service
systemctl  enable nginx
systemctl  start nginx
exit 0
[root@localhost rpm]# vim before-remove.sh 		#卸载前
#!/bin/bash 
systemctl  disable nginx
systemctl  stop nginx
exit 0
[root@localhost rpm]# vim after-remove.sh 		#卸载后,文件、用户是否删除看实际需要。
#!/bin/bash
rm -f /usr/lib/systemd/system/nginx.service
exit 0

#编辑.fpm文件
[root@localhost rpm]# cat .fpm 
-s dir -t rpm  
-d gperftools-libs  -d openssl11-libs -d nginx-filesystem  -d centos-indexhtml 
-a x86_64
--maintainer nginx.x
--name nginx
--version 1.28.0
--config-files nginx/conf/nginx.conf
--debug
--description 'Nginx is a web server...'
--iteration release
--license BSD
--url 'https://nginx.org'
--vendor 'test Project'

--before-install before-install.sh
--after-install  after-install.sh
--before-remove  before-remove.sh
--after-remove  after-remove.sh

--rpm-changelog  changelog.txt
--rpm-os  linux
--rpm-summary  'RPM summary content'
--rpm-digest md5
--rpm-dist el7 


nginx=/opt/app
nginx.service=nginx.service

[root@localhost rpm]# fpm   #实际还是调用了rpmbuild
Running rpmbuild {:args=>["rpmbuild", "-bb", "--target", "x86_64-unknown-linux", "--define"
...
Created package {:path=>"nginx-1.28.0-release.el7.x86_64.rpm", :file=>"clamp/command.rb", :line=>"66", :method=>"run"}

#changelog报错
#error: %changelog entries must start with *   #changelog 不能乱序,需要列表格式  
#error: bad date in %changelog: nginc changelog...
* Thu May  1 2025 nginc changelog...
- add ...
- fix ...
[root@localhost rpm]# rpm -qp --changelog nginx-1.28.0-release.el7.x86_64.rpm 
* Thu May 01 2025 nginc changelog...
- add ...
- fix .

#签名
[root@localhost rpm]# rpm --addsign --define "_gpg_name devtools "   nginx-1.28.0-release.el7.x86_64.rpm   

[root@localhost rpm]# rpm -qlp nginx-1.28.0-release.el7.x86_64.rpm 
/nginx.service
/nginx/conf/nginx.conf
...
/opt/app/nginx/nginx/sbin/nginx

#安装测试
[root@localhost ~]# yum install nginx-1.28.0-release.el7.x86_64.rpm 
Installed:
  nginx.x86_64 0:1.28.0-release.el7                                                                                                                                             

Complete!

[root@localhost nginx]#  systemctl status nginx.service
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2025-05-01 14:11:02 CST; 2min 10s ago
  Process: 17859 ExecStart=/opt/app/nginx/sbin/nginx (code=exited, status=0/SUCCESS)
  Process: 17856 ExecStartPre=/opt/app/nginx/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 17854 ExecStartPre=/usr/bin/rm -f /opt/app/nginx/logs/nginx.pid (code=exited, status=0/SUCCESS)
 Main PID: 17861 (nginx)
   CGroup: /system.slice/nginx.service
           ├─17861 nginx: master process /opt/app/nginx/sbin/nginx
           └─17862 nginx: worker process

[root@localhost nginx]# netstat -nlpt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      17861/nginx: master 

完成!

关于rpmbuild 简单使用  

  • 打包之前的准备工作
主要是借鉴了【RPMBUILD从入门到放弃】 https://blog.csdn.net/weixin_50902636/article/details/140215376
# 精确控制 RPM 包的构建过程 rpmbuild 会适合你
[root@t33 webhook]# yum install  rpm-build rpmdevtools
[root@t33 webhook]# rpmbuild --version    
RPM version 4.11.3

[root@t33 rpmbuild]# su - rpmbuild 		#网上建议用普通用户,如果不清楚编译的命令的话,可能出问题。

[rpmbuild@t33 rpmbuild]$ rpmbuild --showrc|grep macros						#配置文件读取优先级
Macro path: ····:/etc/rpm/macros:/etc/rpm/%{_target}/macros:~/.rpmmacros   #  ~/.rpmmacros 默认的配置文件 

#目录结构 
[rpmbuild@t33 rpmbuild]# rpmbuild --showrc | grep topdir 
-14: _builddir  		%{_topdir}/BUILD			#源码解压的目录。
-14: _buildrootdir      %{_topdir}/BUILDROOT		#临时目录,构建过程中测试安装的目录,最终将其中的打包成 RPM 包。用完即删
-14: _rpmdir    		%{_topdir}/RPMS				#最终输出的RPM	        		   存放目录。
-14: _sourcedir 		%{_topdir}/SOURCES			#源文件、依赖、补丁等 需要的都放这    存放目录。
-14: _specdir   		%{_topdir}/SPECS			#配置文件.spec          			存放目录。
-14: _srcrpmdir 		%{_topdir}/SRPMS			#源码包 .src.rpm         			 存放目录。
-14: _topdir    		%{getenv:HOME}/rpmbuild    #默认的工作目录

[root@t33 rpm]# rpm --eval “%{_topdir}”
“/root/rpmbuild”

/root/rpmbuild/ #因为机器之前编译安装过sniproxy
├── BUILD
│   └── sniproxy-0.6.1
│       ├── configure
		···
├── BUILDROOT
├── RPMS
│   └── x86_64											#RPM包根据硬件平台不同分类
│       ├── sniproxy-0.6.1-1.el7.x86_64.rpm
│       └── sniproxy-debuginfo-0.6.1-1.el7.x86_64.rpm
├── SPECS
└── SRPMS
    └── sniproxy-0.6.1-1.el7.src.rpm

#.rpmmacros  自定义不了 使用 export RPM_CONFIG_FILE=*** 会找不到目录的
#自定义宏   其他的宏 可以查看  https://blog.csdn.net/weixin_50902636/article/details/140215376
[rpmbuild@t33 rpmbuild]$ cat /home/rpmbuild/.rpmmacros 				
%_topdir 			/usr/local/src/rpm/rpmbuild		#下面的目录可以不用指定,  默认都是%{_topdir} 目录下了
%_builddir  		%{_topdir}/BUILD				#也可以写绝对路径,这里也是想试试宏
%_buildrootdir  	%{_topdir}/BUILDROOT
%_rpmdir    		%{_topdir}/RPMS		
%_sourcedir 		%{_topdir}/SOURCES	
%_specdir   		%{_topdir}/SPECS	
%_srcrpmdir 		%{_topdir}/SRPMS	
#还可以加其他宏
%_builduser         rpmbuild

[root@t33 rpm]# rpm --eval “%{_builduser}” 				#默认路径下的可以查看,rpm没有找到指定rpmmacros
“rpmbuild”

#创建目录
[rpmbuild@t33 rpmbuild]$ mkdir -p {BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS} 
  • rpmbuild 打包 - sniproxy 为例 
#以sniproxy 为例  https://github.com/dlundquist/sniproxy/
#sniproxy 安装步骤如下
yum install autoconf automake curl gettext-devel libev-devel pcre-devel perl pkgconfig rpm-build udns-devel
./autogen.sh && ./configure && make dist   							#命令后会生成 sniproxy-0.6.1.tar.gz 生成发布包,可以理解为源码包
rpmbuild --define "_sourcedir `pwd`" -ba redhat/sniproxy.spec  		#"_sourcedir `pwd`  将本地目录变成源文件目录,进行编译打包
yum install /root/rpmbuild/RPMS/x86_64/sniproxy-0.6.0-1.el6.x86_64.rpm 
-----------------------------------------------------------------------------------------
#工作正式开始  #需要解析sniproxy.spec,将所需要的文件放置到自定义目录下
[rpmbuild@t33 sniproxy-0.6.1]# mv sniproxy-0.6.1.tar.gz /usr/local/src/rpm/rpmbuild/SOURCES/  #拷贝 make dist  生成的源码包
[rpmbuild@t33 sniproxy-0.6.1]# cp -rfp redhat/sniproxy.spec   /usr/local/src/rpm/rpmbuild/SPECS/

[rpmbuild@t33 SPECS]$ cat sniproxy.spec 		#定义配置文件
#和fpm一样的字段定义
Name: sniproxy
·····
Source0: %{name}-%{version}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)  #用到了宏,还是用了name 、version 定义的变量
BuildRequires: autoconf, automake, curl, libev-devel, pcre-devel, perl, gettext-devel, udns-devel	#依赖

%description
Proxies incoming HTTP ···

%prep
%setup -q             #解压并cd到目录中

%build
%configure CFLAGS="-I/usr/include/libev"  	#configure编译
make %{?_smp_mflags}						#开启并行编译

%install											
rm -rf $RPM_BUILD_ROOT
make install DESTDIR=$RPM_BUILD_ROOT		#安装

#脚本有
#%pre		安装前需要做的任务,如:创建用户
#%post		安装后需要做的任务 如:自动启动的任务
#%preun		卸载前需要做的任务 如:停止任务
#%postun	卸载后需要做的任务 如:删除用户,删除/备份业务数据

%pre											#在客户端安装前执行
if [ $1 -eq 1 ]; then							#Spec文件中判断是升级or卸载 根据 $1,$2判断
    echo  %{_builduser}							#显示一下_builduser自定义宏
    %define Localtime 1990-01-01				#自定义变量
    echo  %{Localtime}		
fi

%clean
rm -rf $RPM_BUILD_ROOT						#BUILDROOT  用完即清理

%files										#设置文件属性
%defattr(-,root,root,-)						#目录下的文件不指定 都继承此权限
%{_sbindir}/sniproxy

%doc										#文档	
%{_mandir}/man8/sniproxy.8.gz
%{_mandir}/man5/sniproxy.conf.5.gz

%changelog
* Thu Mar 16 2023 Dustin Lundquist <dustin@null-ptr.net 0.6.1-1
···

#编译打包       步骤可以跳过,直接执行-ba
rpmbuild -bp 	从开始执行到pre阶段				   BUILD 有解压文件了	
rpmbuild -bc    从开始执行执行到build阶段
rpmbuild -bi	从开始执行执行到install阶段        BUILDROOT开始有文件了,包含 -bl 阶段了
rpmbuild  -bl 	检查spec中的%file段 文件是否齐全

rpmbuild -ba 		从开始执行编译后生成*.rpm和* src.rpm
					-bb 只生成*.rpm
		   			-bs 只生成*.src.rpm     
  • 客户端安装验证
[root@localhost ~]# yum install sniproxy-0.6.1-1.el7.x86_64.rpm 
Dependencies Resolved
=====================================================================================================================================================
 Package                       Arch                        Version                           Repository                                         Size
=====================================================================================================================================================
Installing:
 sniproxy                      x86_64                      0.6.1-1.el7                       /sniproxy-0.6.1-1.el7.x86_64                       86 k
Installing for dependencies:
 udns                          x86_64                      0.4-3.el7                         epel                                               60 k

Transaction Summary
=====================================================================================================================================================
Install  1 Package (+1 Dependent package)
Running transaction
  Installing : udns-0.4-3.el7.x86_64                                                                                                             1/2 
rpmbuild					# pre脚本输出
1990-01-01                  # pre脚本输出 
  Installing : sniproxy-0.6.1-1.el7.x86_64                                                                                                       2/2 
  Verifying  : udns-0.4-3.el7.x86_64                                                                                                             1/2 
  Verifying  : sniproxy-0.6.1-1.el7.x86_64                                                                                                       2/2 

Installed:
  sniproxy.x86_64 0:0.6.1-1.el7                                                                                                                      

Dependency Installed:
  udns.x86_64 0:0.4-3.el7                                                                                                                            

Complete!

参阅:

fpm安装和使用fpm打包rpm

fpm - packaging made simple — fpm - packaging made simple 1.9.0 documentation

RPMBUILD从入门到放弃