MAATRIX / Блог / Пакета нет в репозитории РЕД ОС: собираем свой RPM

Пакета нет в репозитории РЕД ОС: собираем свой RPM

MAATRIX

Вы вводите dnf install на РЕД ОС, а в ответ — «No match for argument». Пакет, который на CentOS или AlmaLinux ставится одной командой, в официальном репозитории РЕД ОС просто отсутствует: либо его туда не включили, либо версия там древняя и не устраивает. Дальше два пути — плюнуть на задачу или собрать RPM самостоятельно. Второй путь рабочий, но требует понимания, что вы делаете и какую ответственность на себя берёте. Разберём процесс по шагам и честно — где он оправдан, а где лучше выбрать другой вариант.

Когда пакета действительно нет, а когда только кажется

Прежде чем собирать что-то руками, стоит убедиться, что вы не изобретаете велосипед. РЕД ОС — RHEL-совместимый дистрибутив, и у него, как и у любого клона RHEL, есть несколько слоёв репозиториев: базовый, дополнительный (обычно что-то вроде extra или updates), и то, что подключается отдельно вручную. Часто нужный пакет просто не входит в базовую поставку, но лежит в дополнительном репозитории, который не включён по умолчанию.

Проверочный минимум перед тем, как садиться писать spec-файл:

dnf repolist all
dnf search <имя_пакета>
dnf provides '*/bin/имя_бинарника'

Если пакет не находится ни в одном подключённом репозитории — посмотрите список доступных репозиториев в документации к вашей версии РЕД ОС (он периодически меняется между релизами) и убедитесь, что не пропустили один из них. Иногда пакет физически есть, просто в репозитории, который не активирован в /etc/yum.repos.d/.

Если пакета действительно нет нигде из официальных источников — переходите к следующему вопросу: он вам нужен как системный RPM, или достаточно контейнера с этим ПО? Об этом — в одном из следующих разделов. Если ответ «да, нужен именно системный пакет», едем дальше.

Из чего состоит RPM и как устроен spec-файл

RPM — это не просто архив с файлами. Это архив плюс метаданные: версия, зависимости для установки, зависимости для сборки, скрипты, которые выполняются до/после установки и удаления, список файлов с указанием, куда они кладутся. Всё это описывается в spec-файле — текстовом файле с расширением .spec, который читает утилита rpmbuild.

Основные секции spec-файла, если коротко:

  • ЗаголовокName, Version, Release, Summary, License, URL, Source0 (откуда брать исходники).
  • BuildRequires — что нужно установить в систему сборки, чтобы пакет вообще собрался (компилятор, dev-заголовки библиотек, инструменты сборки вроде cmake или make).
  • Requires — что должно быть установлено в системе, где пакет будет работать (рантайм-зависимости).
  • %description — человекочитаемое описание.
  • %prep — подготовка: обычно распаковка исходников (%setup или %autosetup), применение патчей.
  • %build — собственно компиляция: ./configure && make или аналог для другой системы сборки.
  • %install — установка собранных файлов во временный каталог (%{buildroot}), из которого потом соберётся сам RPM.
  • %files — список файлов, которые войдут в пакет, с путями.
  • %changelog — история версий пакета.

Если у вас уже есть spec-файл от апстрима проекта (многие проекты публикуют его сами) или от совместимого дистрибутива — для RHEL-совместимых систем нередко можно взять spec из исходного RPM другого клона RHEL и адаптировать под РЕД ОС, поправив зависимости под доступные в её репозиториях версии библиотек. Если spec-файла нет вообще — его придётся писать с нуля, ориентируясь на то, как проект собирается «руками» (обычно это описано в README или INSTALL исходников).

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Готовим окружение и собираем пакет

Сборка RPM требует отдельного, не production-окружения. Собирать пакеты на боевом сервере — плохая идея по тем же причинам, по которым плохая идея собирать на нём Docker-образы: сборка тянет за собой компиляторы, dev-библиотеки и произвольный код из исходников, а это лишняя поверхность атаки и риск случайно что-то сломать на работающем сервисе. Логика та же, что разобрана в статье про сборку образа на боевом сервере — сборочное окружение и продакшен должны быть разными машинами.

Базовый набор инструментов для сборки RPM:

dnf install rpm-build rpmdevtools
rpmdev-setuptree

Команда rpmdev-setuptree создаёт в домашнем каталоге стандартную структуру:

~/rpmbuild/
├── SPECS/     # сюда кладём .spec-файл
├── SOURCES/   # сюда кладём архив с исходниками (tar.gz) и патчи
├── BUILD/     # рабочий каталог сборки
├── RPMS/      # сюда попадут готовые бинарные RPM
└── SRPMS/     # сюда попадёт source RPM

Дальше — цикл, который вы будете проходить итеративно:

  1. Кладёте архив с исходниками в SOURCES/, spec-файл — в SPECS/.
  2. Устанавливаете зависимости для сборки, которые перечислены в BuildRequires. Это можно сделать вручную через dnf install, либо — что удобнее — через dnf builddep имя.spec, если эта команда доступна в вашей версии РЕД ОС (в некоторых RHEL-подобных системах это отдельный плагин dnf, который может потребовать доустановки).
  3. Запускаете сборку:
rpmbuild -ba SPECS/имя.spec

Флаг -ba означает «собрать и binary, и source RPM». Если нужен только бинарный пакет — -bb, только source — -bs.

  1. Если сборка падает — читайте вывод: чаще всего это либо отсутствующая зависимость сборки (BuildRequires), либо путь, который в %install не совпадает с тем, что реально положил make install, либо несовпадение версий между тем, что ожидает spec, и тем, что реально распаковалось из архива.

Для более чистой и воспроизводимой сборки в изолированном chroot-окружении в экосистеме RPM есть утилита mock — она собирает пакет в контейнере-чруте с минимальным набором зависимостей, что помогает поймать ситуацию «у меня собралось, потому что на машине случайно стоит лишний пакет, а в чистой системе не соберётся». Если планируете собирать RPM регулярно, а не разово — присмотритесь к mock, это избавит от части сюрпризов на этапе установки уже собранного пакета.

Результат сборки — .rpm-файл в RPMS/<архитектура>/. Устанавливается он как обычный пакет:

dnf install ./RPMS/x86_64/имя-версия.rpm

Альтернатива сборке: пакеты из других RHEL-совместимых репозиториев

Полная сборка из исходников — не единственный вариант. РЕД ОС собрана на базе RHEL, и в этой же родословной — CentOS Stream, AlmaLinux, Rocky Linux, Oracle Linux. У них может найтись готовый бинарный RPM того же пакета той же (или близкой) версии. Соблазн понятен: скачать .rpm из репозитория AlmaLinux и поставить его на РЕД ОС вместо собственной сборки.

Это иногда работает, но осторожность здесь важнее скорости:

  • Совместимость версий системных библиотек не гарантирована. Пакет, собранный под конкретную минорную версию другого дистрибутива, линкуется против конкретных версий glibc, openssl и других системных библиотек. Если в РЕД ОС версии отличаются — установка может пройти, а бинарник — падать при запуске с ошибкой вида «version GLIBC_2.XX not found».
  • Отсутствие проверки и подписи от вендора РЕД ОС. Пакет из чужого репозитория не проходит тот путь тестирования, который проходят пакеты официального репозитория РЕД ОС, и не подписан её ключами — при включённой проверке подписи dnf такой пакет либо не установится без --nogpgcheck, либо потребует явного доверия к чужому GPG-ключу, а это отдельное решение, которое стоит принимать осознанно, а не походя.
  • Риск конфликта пакетов — «навесной» RPM из другого дистрибутива может тянуть зависимости, которые конфликтуют с версиями, уже установленными из репозиториев РЕД ОС, и dnf начнёт предлагать даунгрейд или удаление системных пакетов.

Если всё же идёте этим путём — ставьте такой пакет сначала на тестовом сервере, проверяйте зависимости через rpm -qpR имя.rpm (список требуемых зависимостей) до установки, и держите в голове, что при следующем обновлении системы этот пакет никто, кроме вас, не обновит и не проверит на совместимость.

Альтернатива системной установке: контейнер вместо RPM

Если пакет нужен не как системная служба, глубоко интегрированная с остальной ОС (не демон, который должен стартовать через systemd и общаться с другими системными сервисами), а просто как инструмент или сервис со своим портом — часто разумнее не собирать RPM вообще, а взять готовый Docker- или Podman-образ. Это снимает большую часть головной боли: не нужно подбирать BuildRequires, не нужно думать о совместимости с системными библиотеками РЕД ОС, обновление сводится к docker pull новой версии образа.

Сравнение подходов для нетривиального случая:

КритерийСборка RPMКонтейнер
Интеграция с systemd/ОСПолная, как у нативного пакетаЧерез unit-файл, запускающий контейнер
Изоляция от системных библиотекНет, зависит от версий в РЕД ОСДа, образ несёт свои зависимости
Обновления безопасностиВаша ответственность полностьюОтветственность на вас + образ апстрима
Порог входаВыше: нужно понимать spec, сборкуНиже, если образ уже опубликован
Подходит дляСистемных демонов, драйверов, утилит с плотной интеграциейВеб-сервисов, изолированных инструментов

Это не универсальный совет «всегда берите контейнер» — там, где программа должна работать как системная служба с доступом к системным ресурсам, интегрированная через systemd, PAM или другие системные механизмы, контейнеризация может быть неудобной или вовсе не подходящей заменой. Но если задача — просто «нужна конкретная версия сервиса, которой нет в репозитории» — контейнер часто закрывает вопрос быстрее и с меньшим количеством граблей, чем самостоятельная сборка RPM. Подробнее о том, когда контейнер уместнее нативной установки, а когда наоборот — в статье Docker или LXC: что выбрать для сервера.

Тестирование и риски самостоятельной сборки в продакшене

Собранный своими руками пакет — это не пакет из репозитория, который прошёл тестирование вендора. Прежде чем ставить его на боевой сервер, стоит пройти минимум проверок:

  • Установка на тестовом окружении, максимально близком к продакшену — та же версия РЕД ОС, тот же набор уже установленных пакетов.
  • Проверка зависимостейrpm -qpR покажет, что пакет требует, ldd на бинарнике после установки покажет, все ли динамические библиотеки резолвятся.
  • Проверка скриптов установки/удаления, если они есть в spec (%post, %preun и т.д.) — они выполняются с правами root и могут менять состояние системы, поэтому их стоит читать, а не просто доверять.
  • Функциональная проверка — сервис действительно запускается, слушает нужный порт, пишет лог туда, куда ожидается, переживает systemctl restart.
  • Проверка на чистой системе через mock (если собирали не в нём) — чтобы исключить эффект «у меня собралось, потому что на сборочной машине случайно стоит лишний пакет».

Теперь о рисках, которые стоит проговорить честно, а не спрятать между строк:

Вы теряете официальную поддержку. Если самосборный пакет что-то ломает или конфликтует с системным обновлением — это не тот случай, где можно написать в поддержку вендора РЕД ОС и получить фикс. Разбираться придётся самостоятельно.

Обновления безопасности — теперь ваша обязанность. Пакет из официального репозитория обновляется вендором, когда выходит патч уязвимости в апстриме. Самосборный пакет не обновится сам — ни через dnf upgrade, ни как-то ещё. Вам нужно будет вручную отслеживать CVE в проекте, исходники которого вы когда-то собрали, и пересобирать пакет заново при каждом security-фиксе. Если таких самосборных пакетов на сервере несколько и они пылятся без присмотра — это ровно тот сценарий, который разбирается в статье про то, как устаревшая зависимость обернулась бэкдором: никто не следил за обновлением конкретного компонента, и уязвимость закрылась не сразу.

Конфликты при системных обновлениях. Если позже вендор РЕД ОС всё же добавит этот пакет в официальный репозиторий, или обновит зависимость, от которой зависит ваша сборка — dnf может не суметь корректно определить, что делать с вашим «чужеродным» пакетом: обновлять, оставлять как есть, или ругаться на конфликт версий.

SELinux-контексты. РЕД ОС, как и другие защищённые RHEL-совместимые дистрибутивы, может использовать SELinux в enforcing-режиме. Файлы, установленные вручную собранным пакетом, могут не получить нужный SELinux-контекст автоматически (в отличие от пакетов, для которых политика прописана в дистрибутиве), и сервис будет падать с непонятной ошибкой доступа, которая на первый взгляд выглядит как баг в самом пакете. Отключать SELinux ради того, чтобы сборка заработала, — плохое решение: это разобрано в статье отключить SELinux и забыть. Правильный путь — разобраться, какой контекст нужен, и назначить его явно через semanage fcontext и restorecon.

Держите список всех самосборных пакетов на сервере в отдельном документе — какая версия, откуда исходники, когда собирали, кто отвечает за обновление. Без этого через полгода никто не вспомнит, что вон тот демон — не из репозитория, и его безопасность на сервере держится на честном слове.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли просто взять .rpm с сайта проекта, если он там есть, и поставить без пересборки?

Можно, но с той же осторожностью, что и с пакетами из других RHEL-клонов: проверьте зависимости через rpm -qpR, убедитесь, что версии системных библиотек совпадают, и по возможности протестируйте на некритичном сервере перед продакшеном.

Обязательно ли писать spec-файл с нуля?

Нет, если у проекта есть официальный spec (многие публикуют его в исходниках или отдельном репозитории для сборки) или если можно взять spec из совместимого RHEL-клона и адаптировать под доступные в РЕД ОС версии зависимостей — это ощутимо экономит время и снижает риск ошибок.

Как понять, что зависимостей для сборки хватает, до самого rpmbuild?

Секция BuildRequires в spec-файле перечисляет их явно; можно попробовать dnf builddep имя.spec, если этот функционал доступен в вашей версии РЕД ОС, либо установить зависимости вручную по списку и повторить попытку сборки, если она упадёт с ошибкой отсутствующего инструмента или заголовочного файла.

Что делать, если после установки самосборного пакета сервис не стартует, а в логе — «denied» без явной причины?

Проверьте journalctl и audit.log на записи AVC — это почти всегда означает, что SELinux заблокировал доступ, потому что файлам не назначен ожидаемый контекст безопасности; решается через semanage fcontext и restorecon, а не через отключение SELinux.

Стоит ли вообще связываться со сборкой, если пакет нужен разово?

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

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →