赞
踩
前面写过一篇“利用Nginx搭建一个apt服务器”, 但只是前期铺垫工作,只适合用于简单的场景,并没有细化,简单实现能用apt安装就可以了。现在我们来细化一下,添加一下要求,使其更加实用,适用于大型项目。
首先需要在服务器上建立一个本地软件包镜像仓库,而建立仓库有多种手段,可以借助工具来实现,比如:apt-mirror 、reprepro
和aptly
等都是可以的,选其一即可。在此我选择了reprepro,它是一个由Debian项目提供的开源软件包管理工具,用于构建和管理Debian软件包仓库,可以帮助用户轻松地创建本地APT仓库并进行软件包的管理、发布和分发。
reprepro
:首先,在您的服务器上安装reprepro
软件包管理工具。您可以使用以下命令进行安装:
$ sudo apt update
$ sudo apt install reprepro
reprepro
仓库: 创建一个目录用于存储reprepro
的仓库,例如/var/www/html/apt-repository
。
进入到reprepro
仓库目录,并使用以下命令初始化reprepro
仓库
$ mkdir /var/www/html/apt-repository
$ cd /var/www/html/apt-repository
$ mkdir conf
$ cd conf
$ touch distributions
distributions
用于指定软件包仓库的不同发行版(distribution)的信息。
编辑distributions
配置文件并添加必要的信息。您可以参考下面的示例配置文件内容:
Origin: Your_Origin // 指定软件包仓库的来源,通常是您或您的组织的名称
Label: Your_Label // 给软件包仓库设置一个标签,用于标识仓库
// 每个发行版都有一个代号,比如
stable
、testing
、unstable
等Codename: Your_Codename
// 指定软件包支持的架构,比如
amd64
、i386
、arm64
等Architectures: Your_Architectures
// 指定软件包仓库的组件,比如
main
、contrib
、non-free
等Components: main
Description: Your_Description
// 指定用于对软件包进行签名的GPG密钥ID
SignWith: YOUR_KEY_ID
GPG密钥的生成:
gpg --gen-key
按照提示创建你的GPG密钥。
gpg --list-keys //显示密钥
gpg --list-keys --keyid-format LONG //显示密钥和密钥ID
密钥ID通常是8byte的16进制组合。
确保配置文件中的信息正确无误后,再次尝试使用以下命令初始化reprepro
仓库:
$ cd /var/www/html/apt-repository
$ reprepro export
执行后,目录下应该会有以下文件生成:
$ ls
conf db dists lists
现在仓库初始化完成。
添加软件包到reprepro
仓库:
将您的软件包文件拷贝到服务器的某一
目录下,例如/home/w/publish/ 。
使用以下命令将软件包添加到reprepro
仓库中:
$ reprepro includedeb YourCodename
/home/w/publish/package.deb
其中,YourCodename
为您在配置文件中设置的Codename,当然
这里也可以写软件包镜像仓库的路径,但不如写codename来的方便。
发布版本:
使用以下命令发布版本到reprepro
仓库中:
$ reprepro export
执行的时候会需要再次输入密钥的短语,确认后即可。
可以看一下目录架构:
$ tree
成功后会生成一个“pool”的文件夹,存放安装包。
配置Nginx
:
安装Nginx
并配置为代理reprepro
仓库的静态文件。您可以使用以下命令安装Nginx
:
$ sudo apt-get install nginx
编辑Nginx
的配置文件/etc/nginx/sites-available/default
,添加类似以下配置来代理reprepro
仓库:
- server {
- listen 80;
-
- root /var/www/html/apt-repository;
- server_name _;
-
- location / {
- autoindex on;
- }
- }
nginx默认的路径是“/var/www/html”,将其改为仓库的路径,或者在location中使用alias命令:
- location / {
- alias /var/www/html/apt-repository;
- autoindex on;
- }
保存配置文件并重启Nginx
服务:
$ sudo systemctl restart nginx
本地配置访问APT服务器:
现在,您可以通过浏览器或者使用apt-get
命令来访问您搭建的APT服务器。
在客户端的/etc/apt/sources.list
文件中添加以下行来指向您的APT服务器:
deb http://192.168.2.103/ codename main
codename
为您的发行版名称,main
为您的软件包组。
sudo apt update
之后就可以通过
sudo apt install xxx
来安装软件了。
下面说一下实现自定义指定源文件列表来实现apt update更新,在 /etc/apt/sources.list 定义了软件源外,/etc/apt/sources.list.d 目录下的文件中也会定义一些第三方的软件源或者叫 PPA(Personal Package Archives)。如果将apt服务器的源地址写在source.list 文件中的话,每次update的时候都要将系统上所有的镜像源全都检查一遍,耗时较多,并不符合我们此次的项目的目的。如果使用软件启动时采用自检查更新的方案的话,这将会造成软件启动慢、客户体验不佳的问题。因此,单独设置apt服务器源地址是有必要的。
在/etc/apt/sources.list.d/
目录下创建一个新的源文件,比如mirror.list
,可以使用以下命令创建:
$ sudo touch /etc/apt/sources.list.d/mirror.list
编辑这个新创建的源文件mirror.list
,并添加您想要使用的镜像源地址,例如:
deb http://your-mirror-server/ubuntu bionic main
确保mirror.list
中的源地址格式正确,包括deb或者deb-src开头,并且每行只包含一个源地址。
运行
apt update -o Dir::Etc::sourcelist=/etc/apt/sources.list.d/mirror.list
命令来更新APT,这样APT会按照mirror.list
中的源地址来更新软件包信息。
程序启动时需要启动的脚本:
- #!/bin/bash
-
- # 执行 apt update 命令检查更新
- apt update -o Dir::Etc::sourcelist=/etc/apt/sources.list.d/mirror.list > /dev/null
-
- # 检查 apt update 命令的返回状态
- if [ $? -eq 0 ]; then
- echo "检查更新成功"
-
- # 检查是否有可用更新
- if apt list --upgradable | grep -qE '\[upgradable\]'; then
- echo "发现可用更新,执行升级操作"
- apt upgrade -y
- echo "软件包已升级"
- else
- echo "没有可用更新"
- fi
- else
- echo "检查更新失败,请检查网络连接或软件源配置"
- fi
软件启动时,采用自动检查是否有更新,如果有更新,则自动更新的方案避免了用户手动更新的问题,毕竟不能要求所有用户都会使用linux系统。
源地址的格式:
deb
或deb-src
开头,分别表示二进制软件包和源代码软件包。源地址的组成:
$ reprepro includedeb immortal
/home/w/publish/benan-test-gateway_1.0.2_amd64.deb
// error
“no section given for '.deb',skipping”
“no priority given for '.deb',skipping”
这个并不是distributions
配置文件的设置问题,不要被误导,这其实是因为.deb安装包打的有问题,.deb安装包打包的时候,其control文件的设置中缺少了“section”、“priority”属性。
control 文件的属性一般如下,
package: packagename // 软件包的名称
version: 1.0.2 // 软件包的版本号,通常遵循特定的版本号规范,此属性必须有
architecture: amd64 // 软件包适用的架构,例如
amd64
、i386
等,此属性必须有maintainer: name <email> //软件包的维护者信息,包括姓名和邮箱地址,可不写
depends: dpkg //软件包的运行时依赖关系,没有的话可以不写
recommends: npm,sudo // 软件包的建议性依赖关系,可不写
description: 描述信息,随便写
//软件包所属的分类,用于组织软件包在软件包管理器中的显示,此属性必须有
section: default
// 软件包的优先级,指定软件包在安装时的优先级,此属性必须有
priority: optional
homepage: https://xxxx/ //软件包的官方网站或主页链接,可不写
conflicts: xxx //软件包的冲突关系,可不写
所以,打包.deb安装包的时候尽量使用规范的写法哦。
W: GPG 错误:http://192.168.2.103 immortal InRelease: 由于没有公钥,无法验证下列签名: NO_PUBKEY 密钥ID
由于apt服务器的软件包镜像仓库使用了GPG加密,该加密为非对称加密,有公钥和私钥。该问题是因为系统没有该仓库的公钥用于验证软件包的签名。所以需要将其公钥下载下来并导入本地软件包仓库。
使用下面的命令来下载公钥:
sudo apt-key adv --keyserver http://192.168.2.103 --recv-keys 密钥ID
其中,“http://192.168.2.103” 替换成apt服务器的地址,“密钥ID”替换成真实的密钥ID。
如果不能下载的话,可以手动将密钥文件下载到本地,然后导入:
gpg --output public_key.asc --armor --export 密钥ID //生成密钥文件
将生成的.asc公钥文件传输到本地,然后
sudo apt-key add <public_key.asc>
然后,
sudo apt update
就可以了。
这样的搭配才是最实用的。
动手操作才会发现更多的细节。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。