Библиотека — FreeBSD — pkg и Ports Collection: управление сторонним софтом [X]
Шифр
freebsd-pkg-and-ports
Разделы
freebsd tooling
Сверено
2 сентября — в этот день утверждения статьи сверялись с первоисточниками, а не правился текст
Объём
16 881 знак · 23 раздела · чтения около 15 минут

FreeBSD — pkg и Ports Collection: управление сторонним софтом


Обзор

FreeBSD предоставляет две взаимодополняющие технологии для установки стороннего софта: бинарные пакеты (через pkg(8)) и Ports Collection (сборка из исходников). Это не конкурирующие системы, а две стороны одной медали: порты — это рецепты сборки, пакеты — результат их применения. Официальные бинарные пакеты собираются из тех же портов на сборочной ферме FreeBSD.

Ключевое отличие от Linux-дистрибутивов: весь сторонний софт устанавливается в /usr/local, а не смешивается с base system в /usr. Это архитектурное разделение (описанное в статье о файловой структуре) делает обновление base system и пакетов полностью независимыми операциями.

pkg: бинарные пакеты

Архитектура

pkg(8) — менеджер бинарных пакетов, заменивший устаревший pkg_install начиная с FreeBSD 10 (2014). Работает с репозиторием pre-compiled пакетов, автоматически разрешает зависимости, ведёт локальную базу данных установленного софта.

При первом вызове pkg на свежей системе автоматически скачивается и устанавливается из /usr/sbin/pkg (bootstrap). Поставляемая системой конфигурация репозиториев лежит в /etc/pkg/FreeBSD.conf; править её не следует — переопределения и собственные репозитории кладутся в /usr/local/etc/pkg/repos/.

Бинарные пакеты собираются на сборочной ферме FreeBSD из дерева портов с дефолтными опциями. Если нужны нестандартные опции сборки — это территория портов или poudriere.

Репозитории: quarterly vs latest

FreeBSD поддерживает две ветки репозитория:

quarterly — обновляется раз в квартал, ориентирован на стабильность. Пакеты получают только security-фиксы и критичные исправления. Используется по умолчанию.

latest — актуальные версии, обновляется непрерывно. Ближе к rolling release для стороннего софта.

Переключение на latest:

mkdir -p /usr/local/etc/pkg/repos
cat > /usr/local/etc/pkg/repos/FreeBSD.conf << 'EOF'
FreeBSD-ports: {
  url: "pkg+https://pkg.FreeBSD.org/${ABI}/latest"
}
EOF
pkg update -f

Имя блока обязано совпадать с именем репозитория из /etc/pkg/FreeBSD.conf: при несовпадении получится не переопределение, а второй репозиторий рядом с прежним. В FreeBSD 15 этот репозиторий переименован из FreeBSD в FreeBSD-ports, а рядом с ним появились FreeBSD-ports-kmods (модули ядра) и выключенный по умолчанию FreeBSD-base. В 14.x имя прежнее — FreeBSD.

Trade-off прост: quarterly — для production, где важна предсказуемость; latest — для development или когда нужны свежие версии.

Основные операции

pkg update                     # обновить индекс репозитория
pkg search nginx               # поиск пакета
pkg search -o nginx            # поиск с отображением origin (категория/имя)
pkg install nginx              # установка с зависимостями
pkg install -y nginx           # без подтверждения
pkg delete nginx               # удаление
pkg autoremove                 # удалить осиротевшие зависимости
pkg upgrade                    # обновить все пакеты
pkg info                       # список установленных пакетов
pkg info nginx                 # детали конкретного пакета
pkg info -l nginx              # список файлов пакета
pkg info -d nginx              # зависимости пакета
pkg which /usr/local/bin/curl  # какому пакету принадлежит файл

Безопасность и аудит

pkg audit -F                   # обновить БД уязвимостей и проверить установленные пакеты
pkg check -d -a                # проверить целостность зависимостей всех пакетов
pkg check -s -a                # проверить контрольные суммы файлов

pkg audit проверяет установленные пакеты по базе VuXML (FreeBSD Vulnerability and Exploits Markup Language). Рекомендуется запускать периодически или после pkg upgrade.

Управление кэшем и блокировкой

pkg clean                      # удалить устаревшие пакеты из кэша (/var/cache/pkg/)
pkg clean -a                   # удалить весь кэш
pkg lock nginx                 # заблокировать пакет от обновления
pkg unlock nginx               # разблокировать
pkg lock -l                    # список заблокированных

Блокировка полезна, когда конкретная версия пакета критична для production и не должна обновляться при pkg upgrade.

Бэкап и восстановление

pkg автоматически бэкапит свою базу данных: ежедневный скрипт 411.pkg-backup включается переменной daily_backup_pkg_enable в periodic.conf и складывает сжатые дампы в /var/backups (каталог — daily_backup_pkg_dir, глубина ротации — daily_backup_pkg_count).

Отдельной команды pkg backup больше нет: её удалили в pkg 1.19, оставив дамп через sqlite-консоль — ровно то, что делает periodic-скрипт.

pkg shell .dump > /var/backups/pkg.sql              # дамп /var/db/pkg/local.sqlite
sqlite3 local.sqlite.new < /var/backups/pkg.sql    # восстановление: заливать в чистую базу

Схема базы привязана к версии pkg, поэтому periodic-скрипт сохраняет вместе с дампом ещё и pragma user_version — при восстановлении на другой версии pkg об этом стоит помнить.

Создание списка установленных пакетов для воспроизведения на другой машине:

pkg query -e '%a = 0' '%o' > manually_installed.txt   # только вручную установленные
# На другой машине:
xargs pkg install -y < manually_installed.txt

Флаг %a = 0 фильтрует пакеты, установленные как зависимости (%a = 1), оставляя только те, что были установлены напрямую.

Конфигурация pkg

Глобальная конфигурация — /usr/local/etc/pkg.conf. Репозитории — /usr/local/etc/pkg/repos/*.conf.

Полезные настройки:

# /usr/local/etc/pkg.conf
ALIAS: {
  up: "upgrade -y",
  in: "install -y",
  rm: "delete -y"
}

После этого pkg up эквивалентно pkg upgrade -y.

Ports Collection: сборка из исходников

Архитектура

Ports Collection — это дерево каталогов (/usr/ports), где каждый каталог содержит рецепт сборки одного приложения. Рецепт (port skeleton) включает: Makefile (инструкции по сборке), distinfo (контрольные суммы исходников), files/ (патчи для FreeBSD), pkg-descr (описание), pkg-plist (список устанавливаемых файлов).

При сборке порта система автоматически скачивает исходный код из upstream, применяет FreeBSD-специфичные патчи, компилирует, устанавливает и регистрирует результат в базе pkg. Результат установки порта и установки бинарного пакета идентичен — в обоих случаях это запись в локальной базе pkg, управляемая через pkg info, pkg delete и т.д.

Коллекция организована по категориям: www/nginx, databases/postgresql16-server, editors/vim, security/openssh-portable, lang/python311. По квартальному отчёту за первый квартал 2026 года в дереве почти 38 тысяч портов.

Когда нужны порты вместо pkg

Порты нужны, когда дефолтные опции сборки не подходят: нужно включить модуль, не включённый в бинарный пакет, или отключить ненужную зависимость. Например, www/nginx имеет десятки опциональных модулей, из которых в бинарном пакете включены только базовые.

Другие случаи: нужна версия новее, чем в репозитории; нужна специфическая оптимизация под процессор (CFLAGS); требуется патч, не включённый в upstream.

Для большинства задач на production-сервере бинарных пакетов достаточно. Порты — инструмент для ситуаций, когда стандартная сборка не подходит.

Получение дерева портов

# Через git (рекомендуемый способ)
pkg install git-lite
git clone https://git.FreeBSD.org/ports.git /usr/ports

# Quarterly ветка (соответствует quarterly-репозиторию pkg)
# Ветки нарезаются в январе, апреле, июле и октябре: 2026Q1, 2026Q2, 2026Q3, ...
git clone -b 2026Q3 https://git.FreeBSD.org/ports.git /usr/ports

# Обновление
cd /usr/ports && git pull

Важно: если используются одновременно pkg и порты, ветка дерева портов должна соответствовать ветке репозитория pkg (quarterly или latest). Несоответствие — основной источник проблем с зависимостями при смешанном использовании.

Сборка и установка порта

cd /usr/ports/www/nginx
make config                    # интерактивный выбор опций (curses-диалог)
make install clean             # скачать, собрать, установить, очистить рабочий каталог

make config сохраняет выбранные опции в /var/db/ports/<категория>_<порт>/options — для www/nginx это /var/db/ports/www_nginx/options. Они запоминаются и применяются при последующих сборках.

Другие полезные make-цели:

make showconfig                # показать текущие опции без диалога
make rmconfig                  # сбросить опции к дефолтным
make config-recursive          # настроить опции для порта и всех зависимостей
make fetch                     # только скачать исходники
make extract                   # скачать и распаковать
make build                     # скачать, распаковать, собрать (без установки)
make package                   # собрать бинарный пакет (.pkg)
make deinstall                 # удалить установленный порт
make reinstall                 # переустановить
make clean                     # очистить рабочий каталог (work/)

Исходники скачиваются в /usr/ports/distfiles/. Рабочий каталог — work/ внутри каталога порта. Оба занимают место и могут быть периодически очищены.

Структура каталога порта

/usr/ports/www/nginx/
├── Makefile           # основной файл сборки: зависимости, версия, опции, URL
├── distinfo           # SHA256 и размер исходников для верификации
├── pkg-descr          # описание для pkg info
├── pkg-plist          # список файлов, устанавливаемых портом
└── files/
    ├── patch-*        # патчи, применяемые к исходникам
    └── nginx.in       # шаблон rc-скрипта (устанавливается в /usr/local/etc/rc.d/)

Makefile порта — не произвольный makefile, а декларативный файл с переменными, интерпретируемый системой фреймворка (bsd.port.mk). Типичный Makefile содержит: PORTNAME, PORTVERSION, MASTER_SITES (откуда скачать), USES (используемые фреймворки: python, cmake, ssl...), OPTIONS_DEFINE (опции сборки).

Поиск портов

cd /usr/ports
make search name=nginx                  # поиск по имени
make search key=web\ server             # поиск по ключевым словам
make quicksearch name=redis             # краткий вывод

# Или через pkg (работает и без установленного дерева портов)
pkg search -o nginx                     # origin: www/nginx

Онлайн: freshports.org — наиболее полная и оперативная информация о портах, включая историю изменений и зависимости.

Смешанное использование pkg и портов

Это самый частый источник путаницы и проблем. Результат установки порта и пакета — одно и то же с точки зрения pkg: запись в базе данных. Но при pkg upgrade репозиторий может заменить собранный из порта пакет на бинарный с другими опциями, нарушив зависимости.

Безопасные паттерны:

Только pkg (рекомендуемый для большинства) — используются исключительно бинарные пакеты. Простота, предсказуемость, скорость.

Pkg + несколько портов — бинарные пакеты для всего, порты только для нескольких приложений с нестандартными опциями. Работает, если ветки совпадают (quarterly/latest), но порты-исключения стоит заблокировать через pkg lock, чтобы pkg upgrade не перезаписал их бинарными версиями.

Только порты через poudriere — все пакеты собираются из портов с нужными опциями в чистом окружении, результат используется как локальный репозиторий для pkg. Наиболее корректный подход для production с кастомизированной сборкой.

Poudriere: собственный репозиторий

Poudriere — инструмент для сборки пакетов из портов в изолированных jail-окружениях. Каждая сборка происходит в чистом jail, что гарантирует воспроизводимость и отсутствие влияния хост-системы.

Это оптимальный подход, когда нужны кастомные опции сборки, но при этом хочется сохранить удобство управления через pkg. Poudriere собирает .pkg-файлы, из которых формируется локальный репозиторий. После этого pkg настраивается на использование этого репозитория вместо (или вместе с) официального.

Базовый workflow:

pkg install poudriere

# Создать jail для сборки
poudriere jail -c -j 14amd64 -v 14.4-RELEASE

# Получить дерево портов
poudriere ports -c -p default

# Создать список пакетов для сборки
echo "www/nginx" >> /usr/local/etc/poudriere.d/pkglist
echo "databases/postgresql16-server" >> /usr/local/etc/poudriere.d/pkglist

# Задать опции (интерактивный диалог)
poudriere options -j 14amd64 -p default -f /usr/local/etc/poudriere.d/pkglist

# Собрать
poudriere bulk -j 14amd64 -p default -f /usr/local/etc/poudriere.d/pkglist

Результат сборки — готовый репозиторий в /usr/local/poudriere/data/packages/. Остаётся настроить pkg на его использование:

cat > /usr/local/etc/pkg/repos/local.conf << 'EOF'
local: {
  url: "file:///usr/local/poudriere/data/packages/14amd64-default",
  enabled: yes,
  priority: 100
}
EOF

priority: 100 означает, что локальный репозиторий будет предпочтён официальному при совпадении пакетов.

Poudriere заслуживает отдельной статьи — здесь обозначены только базовые принципы.

Обновление портов

Если порты используются напрямую (без poudriere), обновление требует дополнительных инструментов. Сам фреймворк портов не имеет встроенного upgrade — он умеет только устанавливать.

portmaster (ports-mgmt/portmaster) — наиболее простой инструмент, не имеющий зависимостей кроме base system:

pkg install portmaster
portmaster -a                  # обновить все порты
portmaster -a --no-confirm     # без подтверждений
portmaster www/nginx           # обновить конкретный порт

portupgrade (ports-mgmt/portupgrade) — альтернатива, более мощная, но зависит от Ruby.

В обоих случаях: перед обновлением стоит обновить дерево портов (cd /usr/ports && git pull) и проверить /usr/ports/UPDATING — файл содержит заметки о портах, требующих особого внимания при обновлении (изменённые зависимости, переименования, миграции конфигов).

Полезные утилиты для работы с пакетами

pkg stats                      # общая статистика: сколько пакетов, размер
pkg prime-list                 # только вручную установленные (не зависимости)
pkg query '%n: %sh' | sort -t: -k2 -h   # пакеты по размеру
pkg annotate -A nginx custom_note "production, don't remove"  # пометки

Отличия от Linux-менеджеров пакетов

В отличие от apt/dnf/pacman, где пакетный менеджер управляет и системными пакетами, и пользовательским софтом, pkg управляет только сторонним софтом. Base system обновляется отдельно через freebsd-update или пересборку из исходников.

Граница, впрочем, размывается. Начиная с 15.0-RELEASE pkgbase (freebsd-base) объявлен tech preview для установки системы, минорных и мажорных обновлений: base разложен на пакеты и лежит в репозитории FreeBSD-base, который присутствует в /etc/pkg/FreeBSD.conf, но выключен по умолчанию. По плану он со временем заменит и наборы дистрибутивов вроде base.txz, и freebsd-update, но пока это именно предварительный вариант, а не режим по умолчанию.

Нет PPA/COPR/AUR — аналогом является дерево портов, где любой может создать порт для нового софта и отправить его в коммит.

Rollback пакетов не встроен нативно (в отличие от, например, Nix). Но в комбинации с ZFS boot environments или jail'ами можно добиться аналогичного результата.

Источники


Связанные заметки

Из библиотеки института уносят только знания. Читателей здесь не считают: посещение не регистрируется, отметок в издании не остаётся, счётчиков нет ни у одного издания фонда.

Издание пополняется и пересверяется. Текст доступен на условиях CC BY-SA 4.0 — унесённое можно передавать дальше на тех же условиях.