Зеркало на базе apt-mirror

Всем привет! В чате попросили рассказать о зеркалировании репозиториев, поэтому здесь этим и займёмся. У меня самый простой вариант, потому что инфра как код, через гит управлять удобнее всего.

Устанавливаем apt-mirror. Для Debian это делается через

sudo apt install apt-mirror

Если у вас Ubuntu, можно ставить apt-mirror2

sudo apt install apt-mirror2

Конфигурационный файл лежит в /etc/apt/mirror.list. Моё содержимое файла:

$ cat mirror.list 
############# config ##################
#
set base_path    /app/apt-mirror ## Куда будет качаться
#
# set mirror_path  $base_path/mirror ## Стандартная папка
# set skel_path    $base_path/skel ## Стандартная папка
# set var_path     $base_path/var ## Стандартная папка
# set cleanscript $var_path/clean.sh ## Скрипт очистки устаревших пакетов, которых нет в release
# set defaultarch  <running host architecture> ## Работает как попало, надёжнее указывать как у меня ниже
set postmirror_script /home/apt-mirror/postmirror.sh ## Пост-скрипт, тоже будет ниже
set run_postmirror 1 ## Разрешить postmirror_script 
set nthreads     20 ## Потоков для загрузки
set _tilde 0
#
############# end config ##############


deb [arch=amd64] https://apt.syncthing.net/ syncthing stable-v2
clean https://apt.syncthing.net/ syncthing stable-v2

deb [arch=amd64] https://download.docker.com/linux/debian trixie stable
clean https://download.docker.com/linux/debian trixie stable

deb [arch=amd64] https://deb.debian.org/debian trixie main contrib non-free non-free-firmware
deb [arch=amd64] https://deb.debian.org/debian trixie-updates main contrib non-free non-free-firmware
deb [arch=amd64] https://deb.debian.org/debian-security trixie-security main contrib non-free non-free-firmware
clean https://deb.debian.org/debian
clean https://deb.debian.org/debian-security

deb [arch=amd64] http://download.proxmox.com/debian/pve trixie pve-no-subscription
clean http://download.proxmox.com/debian/pve

deb [arch=amd64] http://download.proxmox.com/debian/pbs trixie pbs-no-subscription
clean http://download.proxmox.com/debian/pbs

postmirror.sh:

$ cat postmirror.sh 
#!/bin/bash

MIRROR_BASE="/app/apt-mirror/mirror" ## Куда скачиваются репозитории
REPO_BASE="/app/apt-mirror/repository" ## Куда делается ссылка, чтобы url выглядел красиво

REPOS=(
    "apt.syncthing.net|syncthing" ## Тут указываем какой репозиторий какое название ссылки и соответственно url имеет.
    "download.docker.com|docker"
    "deb.debian.org|debian"
    "download.proxmox.com|proxmox"
)

mkdir -p "$REPO_BASE"

for REPO in "${REPOS[@]}"; do
    DOMAIN="${REPO%%|*}"
    NAME="${REPO##*|}"
    
    SOURCE="$MIRROR_BASE/$DOMAIN"
    TARGET="$REPO_BASE/$NAME"
    
    if [ -d "$SOURCE" ]; then
        [ -L "$TARGET" ] && rm "$TARGET"  # удалить старую ссылку
        ln -s "$SOURCE" "$TARGET"
        echo "Создана ссылка: $TARGET -> $SOURCE"
    fi
done

CLEAN_SCRIPT="/app/apt-mirror/var/clean.sh" ## Скрипт очистки. Отлично работает, если указан в postmirror
if [ -f "$CLEAN_SCRIPT" ]; then
    echo "Запуск очистки..."
    bash "$CLEAN_SCRIPT"
    echo "Очистка завершена"
else
    echo "Внимание: $CLEAN_SCRIPT не найден, пропускаем очистку"
fi

chown -R www-data:www-data "$REPO_BASE" ## Выдача прав для nginx в папку зеркала

echo "Постпроцесс завершён"

Как выглядит структура:
В папку mirror скачиваются сами репозитории:

apt.syncthing.net  deb.debian.org  download.docker.com  download.proxmox.com

А в папке repository после postmirror создаются их ссылки:

ntdvme@apt-mirror:/app/apt-mirror$ ls -la repository/
итого 8
drwxr-xr-x 2 www-data   www-data   4096 мая  6 09:00 .
drwxr-xr-x 6 apt-mirror apt-mirror 4096 мая  5 17:10 ..
lrwxrwxrwx 1 www-data   www-data     37 мая  6 09:00 debian -> /app/apt-mirror/mirror/deb.debian.org
lrwxrwxrwx 1 www-data   www-data     42 мая  6 09:00 docker -> /app/apt-mirror/mirror/download.docker.com
lrwxrwxrwx 1 www-data   www-data     43 мая  6 09:00 proxmox -> /app/apt-mirror/mirror/download.proxmox.com
lrwxrwxrwx 1 www-data   www-data     40 мая  6 09:00 syncthing -> /app/apt-mirror/mirror/apt.syncthing.net

Собственно сам mirror.conf для nginx, который забирает файлики:

server {
    listen 80;
    server_name mirror.ntdv.me;
    disable_symlinks off;
    
    location / {
        root /app/apt-mirror/repository;
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
        
    }

}

Дальше с 80 порта проксировать можно как и куда угодно, я это делаю через основной веб-сервер. Все сервисы по 80 и 443 порту гуляют через единую точку входа/выхода.

Когда мы с вами сделали зеркало репозитория, использовать его можно так:

Types: deb
URIs: https://mirror.ntdv.me/debian/debian
Suites: trixie trixie-updates
Components: main contrib non-free non-free-firmware 
Enabled: yes
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg

Types: deb
URIs: https://mirror.ntdv.me/debian/debian-security
Suites: trixie-security
Components: main contrib non-free non-free-firmware
Enabled: yes

Тут важно помнить, что зеркало mirror.domain.com - общий домен. Сами репозитории указываются через path. В примере выше первый debian - идти по символьной ссылке. Второй debian - путь в сам репозиторий.

Для автозапуска использую cron через cronfile, в /etc/cron.d создаём файл cron, и в нём:

0 7,9,13,16,19,22 * * * root proxychains4 /usr/bin/apt-mirror >> /var/log/apt-mirror.log 2>&1

4 лайка