创建私有Ubuntu软件源

-
2026-01-07

方法一:使用 dpkg-scanpackages + Web服务器(最简单)

1. 创建仓库目录结构

# 创建仓库根目录
sudo mkdir -p /var/www/html/myrepo/ubuntu/dists/jammy/main/binary-amd64
sudo mkdir -p /var/www/html/myrepo/ubuntu/pool/main

# 设置权限
sudo chown -R $USER:$USER /var/www/html/myrepo

2. 放置你的deb包

# 把你的.deb文件放到pool目录
cp /path/to/your-package_1.0.0_amd64.deb /var/www/html/myrepo/ubuntu/pool/main/

# 可以按项目创建子目录
mkdir -p /var/www/html/myrepo/ubuntu/pool/main/myproject
cp *.deb /var/www/html/myrepo/ubuntu/pool/main/myproject/

3. 生成Packages文件

cd /var/www/html/myrepo/ubuntu

# 生成Packages.gz文件
dpkg-scanpackages --multiversion pool/main > dists/jammy/main/binary-amd64/Packages
gzip -9c dists/jammy/main/binary-amd64/Packages > dists/jammy/main/binary-amd64/Packages.gz

# 或者使用更简单的脚本
cd /var/www/html/myrepo/ubuntu
apt-ftparchive packages pool/main > dists/jammy/main/binary-amd64/Packages
gzip -kf dists/jammy/main/binary-amd64/Packages

4. 生成Release文件

cd /var/www/html/myrepo/ubuntu

# 创建Release文件
cat > dists/jammy/Release << EOF
Origin: My Private Repository
Label: My Repo
Suite: jammy
Codename: jammy
Version: 1.0
Architectures: amd64
Components: main
Description: My custom software packages
Date: $(date -Ru)
EOF

# 添加MD5/SHA校验
apt-ftparchive release dists/jammy >> dists/jammy/Release

5. 创建自动更新脚本

#!/bin/bash
# /usr/local/bin/update-my-repo.sh

REPO_PATH="/var/www/html/myrepo/ubuntu"

cd $REPO_PATH

# 生成Packages文件
apt-ftparchive packages pool/main > dists/jammy/main/binary-amd64/Packages
gzip -kf dists/jammy/main/binary-amd64/Packages

# 生成Release文件
cat > dists/jammy/Release << EOF
Origin: My Private Repository
Label: My Repo
Suite: jammy
Codename: jammy
Version: 1.0
Architectures: amd64
Components: main
Description: My custom software packages
Date: $(date -Ru)
EOF

apt-ftparchive release dists/jammy >> dists/jammy/Release

echo "Repository updated at $(date)"

给脚本执行权限:

chmod +x /usr/local/bin/update-my-repo.sh

方法二:使用reprepro(推荐,支持签名)

1. 安装和配置

sudo apt install reprepro gnupg

# 创建仓库目录
mkdir -p ~/myrepo/{conf,dists,jammy/main/binary-amd64,pool}
cd ~/myrepo

2. 创建配置文件

nano conf/distributions

内容:

Origin: My Company
Label: My Private Repository
Codename: jammy
Architectures: amd64 i386 all
Components: main
Description: Repository for our custom packages
SignWith: yes

3. 生成GPG密钥(可选但推荐)

# 生成密钥
gpg --full-generate-key
# 选择 RSA and RSA,密钥长度 4096,永不过期

# 导出公钥
gpg --armor --export your-email@example.com > myrepo.gpg.key

4. 添加软件包

# 添加单个包
reprepro -b . includedeb jammy /path/to/your-package.deb

# 添加目录下所有包
reprepro -b . includedeb jammy /path/to/debs/*.deb

# 查看仓库内容
reprepro -b . list jammy

5. 发布到Web服务器

# 复制到Web目录
sudo cp -r ~/myrepo /var/www/html/
sudo chown -R www-data:www-data /var/www/html/myrepo

方法三:使用aptly(功能最全)

1. 安装aptly

# 安装
sudo apt install aptly

# 初始化配置
aptly config show

2. 创建并管理仓库

# 创建本地仓库
aptly repo create my-private-repo

# 添加你的deb包
aptly repo add my-private-repo /path/to/your-packages/*.deb

# 创建快照
aptly snapshot create my-snapshot from repo my-private-repo

# 发布仓库
aptly publish snapshot -distribution=jammy my-snapshot

3. 配置Web服务

# aptly默认发布在~/.aptly/public
sudo ln -s ~/.aptly/public /var/www/html/aptly

客户端配置

1. 添加仓库源

# 创建源文件
sudo nano /etc/apt/sources.list.d/myrepo.list

添加内容(根据你的方法选择):

# 方法一:
deb [trusted=yes] http://your-server/myrepo/ubuntu jammy main

# 方法二(有签名):
deb http://your-server/myrepo jammy main

# 方法三:
deb http://your-server/aptly jammy main

2. 添加GPG密钥(如果仓库有签名)

# 下载并添加密钥
wget -qO - http://your-server/myrepo.gpg.key | sudo apt-key add -

# 或者手动导入
sudo apt-key add myrepo.gpg.key

3. 更新并安装

sudo apt update
sudo apt install your-package-name

自动化部署脚本

完整的管理脚本

#!/bin/bash
# manage-my-repo.sh

REPO_DIR="/var/www/html/myrepo/ubuntu"
POOL_DIR="$REPO_DIR/pool/main"

case "$1" in
    add)
        # 添加新包
        if [ -z "$2" ]; then
            echo "Usage: $0 add /path/to/package.deb"
            exit 1
        fi
        
        # 复制到仓库
        cp "$2" "$POOL_DIR/"
        
        # 更新仓库索引
        cd "$REPO_DIR"
        apt-ftparchive packages pool/main > dists/jammy/main/binary-amd64/Packages
        gzip -kf dists/jammy/main/binary-amd64/Packages
        
        # 更新Release文件
        apt-ftparchive release dists/jammy > dists/jammy/Release
        
        echo "Package added and repository updated"
        ;;
    
    remove)
        # 删除包
        if [ -z "$2" ]; then
            echo "Usage: $0 remove package-name"
            exit 1
        fi
        
        rm -f "$POOL_DIR/"*"$2"*
        
        # 更新索引
        cd "$REPO_DIR"
        apt-ftparchive packages pool/main > dists/jammy/main/binary-amd64/Packages
        gzip -kf dists/jammy/main/binary-amd64/Packages
        
        echo "Package removed and repository updated"
        ;;
    
    list)
        # 列出所有包
        cd "$REPO_DIR"
        zgrep -h "Package: " dists/jammy/main/binary-amd64/Packages.gz | sort | uniq
        ;;
    
    update)
        # 更新仓库索引
        cd "$REPO_DIR"
        apt-ftparchive packages pool/main > dists/jammy/main/binary-amd64/Packages
        gzip -kf dists/jammy/main/binary-amd64/Packages
        apt-ftparchive release dists/jammy > dists/jammy/Release
        echo "Repository updated"
        ;;
    
    *)
        echo "Usage: $0 {add|remove|list|update}"
        exit 1
        ;;
esac

Nginx配置示例

server {
    listen 80;
    server_name repo.your-domain.com;
    root /var/www/html/myrepo;
    
    location / {
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
    }
    
    # 可选的访问控制
    location /ubuntu {
        allow 192.168.1.0/24;
        deny all;
    }
}

最佳实践建议

  1. 版本管理
  • 包命名:package-name_version_arch.deb
  • 保留旧版本用于回滚
  1. 目录结构
myrepo/
├── ubuntu/
│   ├── dists/
│   │   └── jammy/
│   │       └── main/
│   │           └── binary-amd64/
│   │               ├── Packages
│   │               └── Packages.gz
│   └── pool/
│       └── main/
│           ├── project1/
│           │   ├── package1_1.0_amd64.deb
│           │   └── package1_1.1_amd64.deb
│           └── project2/
│               └── package2_2.0_amd64.deb
└── myrepo.gpg.key
  1. 定期清理
# 清理30天前的旧版本
find /var/www/html/myrepo -name "*.deb" -mtime +30 -delete

推荐方案

对于个人或小团队,推荐方法一(dpkg-scanpackages),因为:

  • 最简单直接
  • 不需要额外服务
  • 容易理解和维护
  • 完全满足自定义包的需求

每次添加新包后,只需运行更新脚本即可:

/usr/local/bin/update-my-repo.sh

目录