Пакета нет в репозитории РЕД ОС: собираем свой RPM
Вы вводите dnf install на РЕД ОС, а в ответ — «No match for argument». Пакет, который на CentOS или AlmaLinux ставится одной командой, в официальном репозитории РЕД ОС просто отсутствует: либо его туда не включили, либо версия там древняя и не устраивает. Дальше два пути — плюнуть на задачу или собрать RPM самостоятельно. Второй путь рабочий, но требует понимания, что вы делаете и какую ответственность на себя берёте. Разберём процесс по шагам и честно — где он оправдан, а где лучше выбрать другой вариант.
Содержание
- Когда пакета действительно нет, а когда только кажется
- Из чего состоит RPM и как устроен spec-файл
- Готовим окружение и собираем пакет
- Альтернатива сборке: пакеты из других RHEL-совместимых репозиториев
- Альтернатива системной установке: контейнер вместо 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
Дальше — цикл, который вы будете проходить итеративно:
- Кладёте архив с исходниками в
SOURCES/, spec-файл — вSPECS/. - Устанавливаете зависимости для сборки, которые перечислены в
BuildRequires. Это можно сделать вручную черезdnf install, либо — что удобнее — черезdnf builddep имя.spec, если эта команда доступна в вашей версии РЕД ОС (в некоторых RHEL-подобных системах это отдельный плагин dnf, который может потребовать доустановки). - Запускаете сборку:
rpmbuild -ba SPECS/имя.spec
Флаг -ba означает «собрать и binary, и source RPM». Если нужен только бинарный пакет — -bb, только source — -bs.
- Если сборка падает — читайте вывод: чаще всего это либо отсутствующая зависимость сборки (
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и других системных библиотек. Если в РЕД ОС версии отличаются — установка может пройти, а бинарник — падать при запуске с ошибкой вида «versionGLIBC_2.XXnot 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 ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →