使用reprepro+nginx搭建apt服务器

目录

项目背景

项目要求

项目开发过程

1、apt服务器的搭建

2、实现自定义指定源文件列表来实现apt update更新

3、实现软件启动时自动更新

4. source.list中镜像源地址的格式

项目开发的难点/坑点

总结


项目背景

       前面写过一篇“利用Nginx搭建一个apt服务器”, 但只是前期铺垫工作,只适合用于简单的场景,并没有细化,简单实现能用apt安装就可以了。现在我们来细化一下,添加一下要求,使其更加实用,适用于大型项目。

项目要求

  1. 远程服务器(实际应用会部署在阿里云上)搭建apt服务器,建立软件包管理仓库,以提高软件包下载速度,并保存有软件包仓库的地址、发行版代号、组件等信息;
  2. 本地可用apt install来安装软件;
  3. 本地可用apt update来检查是否有软件更新;
  4. 检查是否有更新或更新软件时,只涉及本apt服务器所在的源地址,不涉及其他源地址;
  5. 每当软件启动时,会自动检查更新,当有更新时自动更新;

项目开发过程

1、apt服务器的搭建

        首先需要在服务器上建立一个本地软件包镜像仓库,而建立仓库有多种手段,可以借助工具来实现,比如:apt-mirror 、repreproaptly等都是可以的,选其一即可。在此我选择了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       // 给软件包仓库设置一个标签,用于标识仓库

 // 每个发行版都有一个代号,比如 stabletestingunstable 等

Codename: Your_Codename 

// 指定软件包支持的架构,比如 amd64i386arm64 等

Architectures: Your_Architectures

// 指定软件包仓库的组件,比如 maincontribnon-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

来安装软件了。

2、实现自定义指定源文件列表来实现apt update更新

 下面说一下实现自定义指定源文件列表来实现apt update更新,在 /etc/apt/sources.list 定义了软件源外,/etc/apt/sources.list.d 目录下的文件中也会定义一些第三方的软件源或者叫 PPA(Personal Package Archives)。如果将apt服务器的源地址写在source.list 文件中的话,每次update的时候都要将系统上所有的镜像源全都检查一遍,耗时较多,并不符合我们此次的项目的目的。如果使用软件启动时采用自检查更新的方案的话,这将会造成软件启动慢、客户体验不佳的问题。因此,单独设置apt服务器源地址是有必要的。

  1. /etc/apt/sources.list.d/目录下创建一个新的源文件,比如mirror.list,可以使用以下命令创建:

    $ sudo touch /etc/apt/sources.list.d/mirror.list

  2. 编辑这个新创建的源文件mirror.list,并添加您想要使用的镜像源地址,例如:

    deb http://your-mirror-server/ubuntu bionic main

  3. 确保mirror.list中的源地址格式正确,包括deb或者deb-src开头,并且每行只包含一个源地址。

  4. 运行 

apt update -o Dir::Etc::sourcelist=/etc/apt/sources.list.d/mirror.list

命令来更新APT,这样APT会按照mirror.list中的源地址来更新软件包信息。

3、实现软件启动时自动更新

程序启动时需要启动的脚本:

#!/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系统。

4. source.list中镜像源地址的格式

  1. 源地址的格式

    • 源地址通常以debdeb-src开头,分别表示二进制软件包和源代码软件包。
    • 紧接着是软件包的下载地址,可以是HTTP、FTP等协议的URL。
    • 接下来是发行版的代号,例如Ubuntu中的版本代号(如bionic、focal等)。
    • 最后是软件包的组件,如main、restricted、universe、multiverse等。
  2. 源地址的组成

    • 主要组件(main):包含由官方团队维护的自由软件。
    • 受限组件(restricted):包含受限制的软件,不是完全自由的。
    • 宇宙组件(universe):包含社区维护的自由软件。
    • 多元宇宙组件(multiverse):包含非自由软件。

项目开发的难点/坑点

  • 问题1,将软件包文件包含进仓库的时候报错:

$ 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  // 软件包适用的架构,例如 amd64i386 等,此属性必须有

maintainer: name <email>   //软件包的维护者信息,包括姓名和邮箱地址,可不写

depends: dpkg  //软件包的运行时依赖关系,没有的话可以不写

recommends: npm,sudo // 软件包的建议性依赖关系,可不写

description: 描述信息,随便写

//软件包所属的分类,用于组织软件包在软件包管理器中的显示,此属性必须有

section: default 

// 软件包的优先级,指定软件包在安装时的优先级,此属性必须有

priority: optional 

homepage: https://xxxx/   //软件包的官方网站或主页链接,可不写

conflicts:    xxx      //软件包的冲突关系,可不写

所以,打包.deb安装包的时候尽量使用规范的写法哦。 

  • 问题2,

 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 

就可以了。 

总结

这样的搭配才是最实用的。

动手操作才会发现更多的细节。

Talk is cheap.Show me your code.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/460722.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

异次元发卡源码系统/荔枝发卡V3.0二次元风格发卡网全开源源码

– 支付系统&#xff0c;已经接入易支付及Z支付免签接口。 – 云更新&#xff0c;如果系统升级新版本&#xff0c;你无需进行繁琐操作&#xff0c;只需要在你的店铺后台就可以无缝完成升级。 – 商品销售&#xff0c;支持商品配图、会员价、游客价、邮件通知、卡密预选&#…

双线性插值缩放算法原理以及matlab与verilog的实现(二)

系列文章目录 双线性插值缩放算法原理以及matlab与verilog的实现&#xff08;一&#xff09; 文章目录 系列文章目录前言一、前提回顾二、FPGA实现步骤2.1 找到源图像四个像素点求目标像素点2.2 FPGA实现步骤2.3 总体框架2.4 ROM缓存模块2.5 VGA模块2.6 双线性算法模块 三、下…

【AI+应用】一步步搭建聊天机器人搭配多种国内外大模型以及api接口调用

如果你看过我之前写的一篇文章 【AI应用】怎么快速制作一个类chatGPT套壳网站&#xff0c; 你可能顺利地使用chatGPT、Gemini&#xff0c; 用得很happy。 突然有一天&#xff0c;你发现一些网站&#xff0c;除了chatGPT、Gemini &#xff0c;还可以切换使用国内外其他的大模型…

【原创】一文读懂RAG的来源、发展和前沿

检索增强生成(Retrieval Augmented Generation&#xff0c;RAG)结合了检索 (Retrieval) 和生成 (Generation) 两个过程&#xff0c;旨在提高机器生成文本的相关性、准确性和多样性。RAG通过在生成文本输出之前先检索大量相关信息&#xff0c;然后将这些检索到的信息作为上下文输…

练习题手撕总结

基础篇 1.基础知识&#xff08;时间复杂度、空间复杂度等&#xff09; 2.线性表&#xff08;顺序表、单链表&#xff09; 3.双链表、循环链表 4.队列 5.栈 6.递归算法 7.树、二叉树&#xff08;递归、非递归遍历&#xff09; 8.二叉搜索树&#xff08;BST&#xff09; 9.二分查…

FPGA静态时序分析与约束(三)、读懂vivado时序报告

系列文章目录 FPGA静态时序分析与约束&#xff08;一&#xff09;、理解亚稳态 FPGA静态时序分析与约束&#xff08;二&#xff09;、时序分析 文章目录 系列文章目录前言一、时序分析回顾二、打开vivado任意工程2.1 工程布局路由成功后&#xff0c;点击vivado左侧**IMPLEMENT…

浅易理解:非极大抑制NMS

什么是非极大抑制NMS 非极大值抑制&#xff08;Non-Maximum Suppression&#xff0c;简称NMS&#xff09;是一种在计算机视觉和图像处理领域中广泛使用的后处理技术&#xff0c;特别是在目标检测任务中。它的主要目的是解决目标检测过程中出现的重复检测问题&#xff0c;即对于…

家具工厂5G智能制造数字孪生可视化平台,推进家具行业数字化转型

家具制造5G智能制造工厂数字孪生可视化平台&#xff0c;推进家具行业数字化转型。随着科技的飞速发展&#xff0c;家具制造业正迎来一场前所未有的数字化转型。在这场家具制造业转型中&#xff0c;5G智能制造工厂数字孪生可视化平台发挥着至关重要的作用。 5G智能制造工厂数字孪…

深度学习模型部署(十)模型部署配套工具二

上篇blog讲了trtexec和onnx_graphsurgeon两个工具&#xff0c;一个用于将onnx转化为trt模型&#xff0c;另一个用于对onnx模型进行修改。这篇blog讲polygraphy和nsight systems&#xff0c;前者用于进行模型优化以及结果验证&#xff0c;后者用于性能分析。 polygraph polygra…

sqllab第二十三关通关笔记

知识点&#xff1a; mysqli_query() 返回值为资源型或布尔型如果内容为查询语句则返回资源型数据&#xff1b;如果内容为插入、更新、删除等语句则返回布尔类型结果mysql_fetch_array() 从结果集中取出一行作为关联数组或数字数组输入内容为指定查询的结果集单引号闭合绕过联…

hololens2发布unity设置

生成vs工程再向hololens发布时&#xff0c; Architecture选X64或ARM64都可以成功发布

爬虫3_爬取翻页URL不变的网站

之前实现了对大学排数据爬取&#xff1a;爬虫2_2019年549所中国大学排名. 近期复现代码&#xff0c;发现原网站升级&#xff0c;在翻页时&#xff0c;发现URL不改变&#xff0c;修改代码&#xff0c;使用网页自动化工具selenium实现对该类网站数据获取。 #-*- coding: UTF-8 -…

【物联网】Modbus 协议及Qinghub物联网平台应用

Modbus 协议简介 QingHub设计器在设计物联网数据采集时不可避免的需要针对Modbus协议的设备做相关数据采集&#xff0c;这里就我们的实际项目经验分享Modbus协议 你可以通过QingHub作业直接体验试用&#xff0c;也可以根据手册开发相应的代码块。 qinghub项目已经全面开源。 …

MC78L05ACDR2G线性稳压器芯片中文资料规格书PDF数据手册引脚图参数图片价格

产品概述&#xff1a; MC78L00A系列线性稳压器价格便宜&#xff0c;易于使用&#xff0c;适用于各种需要最高100mA的调节电源的应用。与大功率MC7800和MC78M00系列一样&#xff0c;这款稳压器也提供内部电流限制和高温关断&#xff0c;因此非常坚固耐用。在很多应用中&#xf…

MediaBox音视频终端SDK已适配鸿蒙星河版(HarmonyOS NEXT)

2024年1月&#xff0c;HarmonyOS NEXT 鸿蒙星河版系统开发者预览版开放申请&#xff0c;该系统将只能安装为鸿蒙开发的原生应用&#xff0c;而不再兼容安卓应用。对此&#xff0c;阿里云MediaBox音视频终端SDK产品已实现功能的鸿蒙化迁移和重构&#xff0c;全面适配鸿蒙系统Har…

王勇:硬科技的下一站 | 演讲嘉宾公布

一、智能耳机与可穿戴专题论坛 智能耳机与可穿戴专题论坛将于3月27日同期举办&#xff01; 智能耳机、可穿戴设备已经逐渐融入我们的生活&#xff0c;它们不仅带来了便捷与舒适&#xff0c;更在悄然改变着我们的生活方式和工作模式。在这里&#xff0c;我们将分享最新的研究成果…

前端基础——HTML傻瓜式入门(2)

该文章Github地址&#xff1a;https://github.com/AntonyCheng/html-notes 在此介绍一下作者开源的SpringBoot项目初始化模板&#xff08;Github仓库地址&#xff1a;https://github.com/AntonyCheng/spring-boot-init-template & CSDN文章地址&#xff1a;https://blog.c…

误分区酿苦果,数据恢复有妙方

一、误操作引发分区混乱 在数字化时代的浪潮中&#xff0c;硬盘分区成为我们管理和存储数据的重要手段。然而&#xff0c;误分区这一操作失误&#xff0c;却时常给许多用户带来不小的困扰。误分区&#xff0c;简单来说&#xff0c;就是在对硬盘进行分区操作时&#xff0c;由于…

P6安装:安装P6提示1433端口无效

错误描述 尝试运行 Microsoft SQL Server 2005 的 Primavera P6 数据库时&#xff0c;遇到以下错误&#xff1a; SQLServerException: The TCP/IP connection to the host [name], port 1433 has failed. Error: “Connection refused: connect. Verify the connection prope…

LCR144翻转二叉树(力扣简单题,Java,递归+非递归)

目录 题目描述&#xff1a; 递归代码1&#xff1a; 递归代码2&#xff1a; 非递归代码&#xff08;层次遍历&#xff09;&#xff1a; 题目描述&#xff1a; 给定一棵二叉树的根节点 root&#xff0c;请左右翻转这棵二叉树&#xff0c;并返回其根节点。 示例 1&#xff1a;…