1. 项目概述
在服务器运维和嵌入式开发领域,离线环境下的软件安装一直是个令人头疼的问题。上周我在给某保密单位部署Ubuntu系统时就遇到了这个难题——他们的内网服务器完全隔离,却需要安装包括Docker、Nginx在内的数十个软件包。经过两天折腾,终于摸索出一套可靠的本地APT仓库搭建方案。
这个方案的核心在于创建一个完整的离线软件仓库(offline-repo),包含所有依赖关系的.deb包。与常见的"下载deb包手动安装"不同,本地APT仓库保持了完整的依赖解析能力,支持apt-get install等标准命令,还能通过apt-cache search查询软件。实测在Ubuntu 22.04 LTS上,用这种方法成功安装了包括MySQL 8.0、Redis等复杂服务。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 准备工作
2.1 硬件需求
建议准备一个至少64GB的U盘或移动硬盘作为传输介质。以安装基础开发环境(build-essential)加Docker为例,相关软件包大约需要800MB空间,如果包含图形界面组件则需要3GB以上。我曾遇到一个案例,某工业控制系统需要同时安装MATLAB运行时环境,最终离线仓库达到了28GB。
2.2 联网环境配置
在可联网的Ubuntu 22.04机器上执行:
bash复制sudo apt install apt-utils dpkg-dev -y
mkdir -p ~/offline-repo/{archives,lists}
这里dpkg-dev包是关键,它包含了生成Packages.gz的工具。有次我漏装了这个包,导致后续创建的仓库无法被正确识别。
3. 构建本地仓库
3.1 下载软件包
使用以下脚本批量下载软件及其依赖:
bash复制#!/bin/bash
pkg_list=(docker.io nginx mysql-server redis-server)
for pkg in "${pkg_list[@]}"; do
apt-get download $(apt-cache depends --recurse --no-recommends --no-suggests \
--no-conflicts --no-breaks --no-replaces --no-enhances \
--no-pre-depends ${pkg} | grep "^\w" | sort -u)
done
mv *.deb ~/offline-repo/archives/
这个脚本的精妙之处在于:
--no-recommends避免下载非必要依赖sort -u去除重复依赖- 只下载直接依赖项(去掉
--no-pre-depends会多下载30%的冗余包)
3.2 生成仓库索引
进入仓库目录执行:
bash复制cd ~/offline-repo
dpkg-scanpackages archives /dev/null | gzip > lists/Packages.gz
这里有个坑:如果archives内含不同架构的.deb包,需要添加-a amd64参数指定架构。上周有个同事在ARM设备上误用了AMD64的包,导致安装失败。
4. 离线环境部署
4.1 仓库文件传输
将整个offline-repo目录拷贝到离线机器的/etc/apt目录下:
bash复制sudo cp -r offline-repo /etc/apt/
4.2 配置sources.list
备份原有配置后,修改为:
bash复制deb [trusted=yes] file:/etc/apt/offline-repo archives/
注意必须加[trusted=yes],否则会因签名验证失败而拒绝安装。有次安全审计时,这个细节导致整个部署流程卡了2小时。
4.3 更新软件列表
执行:
bash复制sudo apt update
此时应该看到类似输出:
code复制Get:1 file:/etc/apt/offline-repo archives/ InRelease
Reading package lists... Done
5. 高级技巧
5.1 增量更新策略
当需要添加新软件时:
- 在联网机创建临时目录:
bash复制mkdir -p ~/offline-repo/new-pkgs - 下载新包到该目录
- 使用rsync同步到离线机:
bash复制
rsync -avz ~/offline-repo/new-pkgs user@offline-machine:/etc/apt/offline-repo/archives/ - 在离线机重新生成索引
5.2 空间优化
使用符号链接避免重复存储:
bash复制ln -s /var/cache/apt/archives/*.deb ~/offline-repo/archives/
这样已下载的包会自动纳入仓库。在存储紧张的嵌入式设备上,这个方法帮我节省了60%空间。
6. 常见问题排查
6.1 依赖关系错误
若出现"unmet dependencies"错误,检查:
- 是否漏下载了某些依赖(用
apt-cache depends再次确认) - 是否混用了不同Ubuntu版本的包(检查/etc/os-release)
6.2 仓库识别失败
当apt update报"Repository not found"时:
- 确认sources.list路径是否正确
- 检查Packages.gz是否有效:
bash复制zcat /etc/apt/offline-repo/lists/Packages.gz | head - 确保有执行权限:
bash复制chmod -R 755 /etc/apt/offline-repo
7. 实战案例
最近为某工厂部署的离线开发环境包含:
- 基础工具链(gcc-11, make, cmake)
- 数据库(MySQL 8.0, Redis 6.2)
- 容器环境(Docker 20.10, docker-compose 1.29)
- 监控工具(htop, nmon)
通过预先下载测试,发现gcc-11依赖libstdc++6 12.1.0,而默认仓库是11.2.0。解决方法是在联网机添加ubuntu-toolchain-r/test PPA:
bash复制sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt update
这个案例说明:复杂环境的离线部署需要充分测试依赖关系,必要时引入额外仓库。现在这套方案已经稳定运行3个月,支持了该工厂的CI/CD流水线建设。
