1. 为什么需要自己制作.deb包?
在Debian系Linux发行版中,.deb是最基础的软件包格式。虽然官方仓库和PPA源已经提供了大量软件包,但实际工作中我们经常会遇到这些情况:
- 需要打包自己开发的应用程序
- 某些软件只有源码版本没有现成的deb包
- 需要修改现有软件包的配置或补丁
- 企业内部软件的分发部署
我最早接触deb打包是在2015年,当时公司内部开发了一个监控工具,需要部署到上百台Ubuntu服务器上。手动编译安装不仅效率低下,还容易出错。学会制作deb包后,部署时间从原来的2小时缩短到5分钟,版本管理也变得非常简单。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 准备工作与环境搭建
2.1 基础工具安装
制作deb包需要以下基本工具(以Debian/Ubuntu为例):
bash复制sudo apt update
sudo apt install -y build-essential devscripts debhelper dh-make
注意:建议使用较新的Debian/Ubuntu版本,旧版本的工具链可能缺少某些功能。我在Debian 9上就遇到过dh_make版本过旧导致的问题。
2.2 项目目录结构
标准的deb包项目目录应该包含:
code复制myproject/
├── debian/ # 打包控制文件
│ ├── changelog # 版本变更记录
│ ├── control # 包依赖关系
│ ├── rules # 构建规则
│ └── ...
├── src/ # 源代码
└── Makefile # 构建脚本
3. 从零开始制作一个deb包
3.1 创建基础框架
假设我们要打包一个名为"hello-deb"的简单程序:
bash复制mkdir -p hello-deb/src
cd hello-deb
echo '#!/bin/bash\necho "Hello, Debian Package!"' > src/hello-deb
chmod +x src/hello-deb
然后初始化debian目录:
bash复制dh_make --createorig -s -n
实操心得:如果遇到"dh_make: command not found",可能是没安装dh-make工具。我在Ubuntu 22.04上就遇到过这个问题。
3.2 关键文件配置
3.2.1 debian/control文件示例
plaintext复制Source: hello-deb
Section: utils
Priority: optional
Maintainer: Your Name <your.email@example.com>
Build-Depends: debhelper-compat (= 13)
Standards-Version: 4.6.1
Package: hello-deb
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: A simple hello world package
This is a demonstration package showing how to create a basic .deb.
3.2.2 debian/rules文件关键内容
makefile复制#!/usr/bin/make -f
%:
dh $@
override_dh_auto_install:
install -D -m 0755 src/hello-deb $(CURDIR)/debian/hello-deb/usr/bin/hello-deb
3.3 构建deb包
执行构建命令:
bash复制dpkg-buildpackage -us -uc
成功后会生成:
code复制../hello-deb_1.0-1_amd64.deb
../hello-deb_1.0-1_amd64.changes
../hello-deb_1.0-1.debian.tar.xz
../hello-deb_1.0-1.dsc
../hello-deb_1.0.orig.tar.gz
4. 高级打包技巧
4.1 处理依赖关系
在control文件中可以指定多种依赖:
code复制Depends: python3 (>= 3.6), libc6
Recommends: python3-pip
Suggests: python3-venv
避坑指南:我曾经遇到过循环依赖的问题,A包依赖B包,B包又依赖A包。解决方案是创建虚拟包或调整包结构。
4.2 安装前后脚本
可以添加preinst/postinst/prerm/postrm脚本:
bash复制#!/bin/bash
# debian/postinst
case "$1" in
configure)
echo "Configuring hello-deb..."
# 初始化操作
;;
esac
exit 0
4.3 多架构支持
在debian/control中指定:
code复制Architecture: any # 或特定架构如 amd64, arm64等
5. 常见问题排查
5.1 依赖问题
错误示例:
code复制dpkg: dependency problems prevent configuration...
解决方案:
bash复制sudo apt install -f
5.2 安装路径冲突
错误示例:
code复制file '/usr/bin/hello' from install of hello-deb conflicts with file from package hello-world
解决方案:
- 修改包中的文件路径
- 使用alternatives系统
- 在debian/control中添加Conflicts/Replaces字段
5.3 构建失败
常见原因:
- 缺少构建依赖(查看debian/control中的Build-Depends)
- 文件权限问题
- 脚本语法错误
调试方法:
bash复制dpkg-buildpackage -us -uc -nc # 不清理上次构建
tail -f debian/hello-deb/debian/build.log
6. 实际项目经验分享
在为一个Python项目打包时,我总结了这些经验:
- 使用dh-virtualenv可以更好地处理Python虚拟环境
- 对于Go项目,建议使用debhelper的golang支持
- 大型项目可以拆分成多个二进制包
- 版本号管理遵循上游版本+打包版本格式(如1.0.0-1)
一个真实案例:我们有一个服务需要打包,它包含:
- 主程序(/usr/bin)
- 配置文件(/etc)
- systemd服务(/lib/systemd/system)
- 日志轮转配置(/etc/logrotate.d)
通过合理设计deb包结构,最终实现了:
- 一键安装部署
- 配置文件保留(conffiles机制)
- 服务自动启用
- 完善的日志管理
7. 测试与发布
7.1 本地测试
安装测试:
bash复制sudo dpkg -i ../hello-deb_1.0-1_amd64.deb
hello-deb # 验证执行
sudo dpkg -r hello-deb # 卸载
7.2 创建私有仓库
建立简单仓库:
bash复制mkdir repo
cp *.deb repo/
cd repo
dpkg-scanpackages . /dev/null | gzip -9c > Packages.gz
客户端配置:
bash复制echo "deb [trusted=yes] file:/path/to/repo ./" | sudo tee /etc/apt/sources.list.d/local.list
sudo apt update
7.3 上传到PPA
对于Ubuntu用户:
bash复制debuild -S
dput ppa:your-ppa/name ../hello-deb_1.0-1_source.changes
8. 维护与更新
更新版本时需要:
- 修改debian/changelog:
plaintext复制hello-deb (1.0-2) unstable; urgency=medium
* Fixed installation path issue
-- Your Name <your.email@example.com> Mon, 01 Jan 2023 12:00:00 +0800
- 重新构建包
- 测试后发布更新
我在维护一个内部工具包时,建立了这样的流程:
- 使用git管理源码和打包文件
- CI自动构建测试包
- 测试通过后发布到内部仓库
- 保留所有历史版本便于回滚
