rpm -i로 설치하면 왜 의존성 에러가 나는가 — RPM과 dnf의 역할 분담
nginx를 설치하려고 rpm -i nginx.rpm을 쳤더니 의존성 에러로 실패한다. 왜? RPM은 의존성을 풀어주지 않는다. 단순 설치만 한다. 의존성 해결은 dnf의 일이다. 그래서 로컬 .rpm 파일도 dnf install ./pkg.rpm으로 설치해야 dnf가 의존성까지 처리한다.
이 글은 Rocky 10이 패키지를 어떻게 관리하는지 다룬다 — RPM(포장 형식 + 저수준 도구)과 dnf(앱스토어 관리자)의 역할 분담, 그리고 Rocky 10의 두 가지 큰 변화: dnf5 전환과 modularity 폐지. 이 변화를 모르면 구형 자료의 명령이 Rocky 10에서 동작하지 않는다.
RPM과 dnf는 역할이 다르다
| 역할 | 비유 | |
|---|---|---|
| RPM | 단일 .rpm 패키지 파일 + 저수준 설치 도구 |
포장된 상자(내용물 + 설명서 + 조립법) |
| dnf5 | 저장소 관리 + 의존성 자동 해결 + 설치/업데이트 | 앱스토어 관리자(검색·배달·세트물 해결) |
RPM은 패키지 형식(.rpm)이자 저수준 도구다. dnf는 그 위에서 저장소 관리와 의존성 자동 해결을 한다. 의존성 지옥(openssl, pcre... 각각 컴파일하던 시절)에서 벗어나게 한 것이 dnf의 핵심 가치다.
NEVRA — 패키지 식별자
nginx-1.26.3-1.el10.x86_64.rpm
│ │ │ │ │
│ │ │ │ └ 아키텍처(x86_64, aarch64, noarch)
│ │ │ └ 배포 태그(el10 = Enterprise Linux 10)
│ │ └ 릴리스(같은 버전의 빌드 회차)
│ └ 버전(업스트림)
└ 이름
noarch는 아키텍처 무관(스크립트/문서). RPM 파일 내부는 헤더(메타데이터) + 페이로드(cpio 압축) + 서명(GPG)으로 이루어진다.
트랜잭션 스크립트
패키지는 설치/제거 시점에 스크립트를 실행한다:
| 스크립트 | 실행 시점 |
|----------|-----------|
| %pre / %post | 설치 전 / 후 |
| %preun / %postun | 제거 전 / 후 |
Rocky 10의 큰 변화 — dnf5와 modularity 폐지
Rocky 10은 dnf4(구)에서 dnf5로 전환했다.
flowchart LR
D[dnf5 명령] --> LIB[libdnf5<br/>C++ 라이브러리]
LIB --> REPO[저장소 메타데이터]
LIB --> RPM[RPM DB<br/>/var/lib/rpm]
| 항목 | dnf4(구) | dnf5(Rocky 10) |
|---|---|---|
| 구현 | Python + libdnf(C++) | libdnf5(전체 C++ 재작성) |
| Python 의존 | 필수 | 제거(컨테이너에 유리) |
| 속도 | 보통 | 더 빠름 |
modularity(dnf module) |
지원 | 폐지 |
| filelists metadata | 기본 다운로드 | 기본 생략(필요 시 자동/수동) |
| 사용자 캐시 | ~/.cache/dnf |
~/.cache/libdnf5 |
modularity 폐지 — 구형 자료가 동작하지 않는 이유
Rocky 8/9에선 특정 버전을 설치하려고 dnf module enable nginx:1.14 && dnf module install nginx:1.14를 썼다. Rocky 10에선 이 명령이 안 통한다. modularity가 폐지됐기 때문이다. 대신 버전을 직접 지정한다.
| 작업 | 구 방식(Rocky 8/9) | 새 방식(Rocky 10) |
|---|---|---|
| 특정 버전 설치 | dnf module enable nginx:1.14 && dnf module install nginx:1.14 |
dnf install nginx-1.26.3 |
| 버전 목록 | dnf module list nginx |
dnf repoquery nginx |
구버전(Rocky 8/9)에서는 구 방식이 정상 동작한다. 버전에 따라 명령이 다르니, 자료의 Rocky 버전을 반드시 확인하라.
nginx-1.26.3(하이픈)과nginx:1.26(콜론, module 방식)은 다르다 — Rocky 10은 하이픈 방식만 된다.
dnf4와 dnf5는 같은 RPM DB(
/var/lib/rpm)를 공유하지만, 트랜잭션 히스토리 DB는 다르다. dnf5로 깐 패키지를 dnf4로 보면 "user installed"로 보이고 그 반대도 마찬가지. Rocky 10은 dnf5가 기본이라 혼용할 일은 거의 없다.
저장소와 GPG 검증 — 변조를 막는다
패키지와 메타데이터를 제공하는 원격/로컬 소스가 저장소(repository)다.
- 설정:
/etc/yum.repos.d/*.repo. - 기본 저장소(Rocky 10): BaseOS, AppStream, Extras.
- 메타데이터:
repodata/(primary, filelists, updateinfo).
.repo 파일 예시:
[example-base]
name=Example Base
baseurl=https://example.com/linux/10/BaseOS/$basearch/os/
enabled=1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-example
저장소/패키지의 GPG 서명으로 변조 여부를 확인한다. gpgcheck=1이면 서명 안 된 패키지 설치를 거부한다. 저장소 추가 시 공개 키를 먼저 등록: rpm --import <keyfile>. gpgcheck를 끄면 편하지만 위험하다 — 변조된 패키지가 설치될 수 있다.
Rocky 10에서 직접 확인하기
미검증(출처 인용). Rocky 10 VM에서 실행 권장.
dnf --version # dnf5 버전 출력
# 패키지 조회
dnf list installed # 설치된 패키지
dnf info nginx # 패키지 상세
dnf search "web server" # 이름/요약 검색
dnf provides /usr/bin/curl # 파일이 어느 패키지인지
dnf repoquery nginx # 저장소의 모든 버전(modularity 대체)
sudo dnf install -y nginx # -y 자동 yes
sudo dnf install -y nginx-1.26.3 # 특정 버전(새 방식)
sudo dnf remove nginx
sudo dnf update # 전체 업데이트(= upgrade)
sudo dnf check-update # 업데이트 가능 목록만
sudo dnf downgrade nginx
# 저장소 관리
dnf repolist # 활성 저장소
dnf repolist all # 전체
sudo dnf config-manager --add-repo https://example.com/repo.repo
sudo dnf config-manager --disable example-base
sudo dnf clean all # 캐시 삭제
# 히스토리 — 롤백
dnf history list # 트랜잭션 목록
dnf history info 5 # 5번 상세
sudo dnf history undo 5 # 5번 취소(롤백)
sudo dnf history rollback 3 # 3번 이후 모두 취소
dnf5는 서브명령이 필수:
dnf history만 치면 안 되고dnf history list.
# 저수준 rpm (dnf로 안 될 때)
rpm -qa | grep nginx # 설치된 패키지 검색
rpm -qi nginx # 패키지 정보
rpm -ql nginx # 설치한 파일 목록
rpm -qf /usr/bin/curl # 파일 소속 패키지
rpm -Va nginx # 검증(변조/무결성)
sudo rpm -ivh pkg.rpm # 설치(로컬, 의존성 안 풀림)
dnf group list
sudo dnf group install "Server with GUI"
흔히 묻는 것, 흔히 틀리는 것
| 오해 | 정정 |
|---|---|
"rpm -i로 설치하면 된다" |
의존성 안 풀림. dnf install ./pkg.rpm 사용 |
"Rocky 10에선 dnf module이 된다" |
안 됨(폐지). dnf install pkg-ver로 |
| "filelists는 항상 받아진다" | Rocky 10은 기본 생략. 필요 시 자동/optional_metadata_types=filelists |
"dnf update와 dnf upgrade는 다르다" |
현대 dnf에선 동일(upgrade가 alias) |
"-y는 항상 좋다" |
운영에선 의존성 변경 먼저 확인 권장. 자동 스크립트만 -y |
| "EPEL은 기본 저장소다" | 아니다. 서드파티. 필요 시 별도 설치(dnf install epel-release) |
| "gpgcheck 끄면 편하다" | 위험. 변조 패키지 설치 가능. 공식 외엔 더 엄격히 |
| "dnf5 히스토리에 과거가 다 보인다" | dnf4→5 전환 시 과거 히스토리 마이그레이션 안 됨 |
더 깊이
- EPEL(Extra Packages for Enterprise Linux): Fedora 커뮤니티가 RHEL/Rocky용으로 제공하는 추가 패키지 저장소. RHEL 기본에 없는 도구(htop, nginx 최신 등) 설치에 유용.
dnf install epel-release로 활성화. 단, 공식 지원 아님(운영 환경 주의). - dnf5 명령 변경:
dnf shell→dnf5 do,dnf updateinfo→dnf5 advisory summary,dnf mark install→dnf5 mark user등 서브명령이 바뀌었다. 자동화 스크립트 작성 시 dnf5 문서 확인. - RPM 직접 빌드:
rpmbuild+.spec파일로 커스텀 패키지를 생성. 소스 + 패치 + 설치 스크립트 + 메타데이터를 묶어 배포. 고급 주제.
요약 — 이 글의 결론
- RPM = 패키지 형식(
.rpm) + 저수준 도구. 의존성을 안 푼다 — 그래서rpm -i는 실패하고dnf install ./pkg.rpm을 써야 한다. - dnf5(Rocky 10) = libdnf5(C++ 재작성), Python 의존 제거, 더 빠름.
- NEVRA: Name-Version-Release.Architecture.
- modularity 폐지:
dnf module이 안 통한다.dnf install pkg-ver로 버전 지정(하이픈). 구버전(8/9)은 콜론 module 방식. - filelists 기본 생략(필요 시 자동/
optional_metadata_types=filelists). - 저장소:
/etc/yum.repos.d/*.repo. GPG 서명(gpgcheck=1)으로 변조 방지 — 끄면 위험. - rollback:
dnf history undo N/dnf history rollback N. - dnf update = upgrade(동일).
생각해 볼 문제
- RPM과 dnf의 역할 분담을 설명하라. 왜
rpm -i로 설치하면 안 되는가? - NEVRA의 각 자리가 의미하는 바를 풀어 설명하라.
- dnf5가 dnf4보다 나은 점 3가지는?
- Rocky 10에서 특정 버전 패키지를 설치하는 명령은? 구버전(8/9) 방식과 비교하라.
- filelists metadata가 기본 생략된 이유와, 필요할 때 어떻게 하는가?
/usr/bin/curl이 어느 패키지 소속인지 확인하는 두 명령은?- 설치를 롤백하려면 어떤 명령을 쓰는가? gpgcheck를 끄면 왜 위험한가?
참고
- Rocky Linux 10 Release Notes — DNF/Modularity - 접근 2026-07-09
- RHEL 10 Considerations — Software management - 접근 2026-07-09
- Changes between DNF and DNF5 - 접근 2026-07-09
- Migrating from DNF to DNF5 - 접근 2026-07-09
- man page:
man dnf5,man rpm,man dnf5.conf
'Tech Artifacts > Linux' 카테고리의 다른 글
| Linux - 10. security (0) | 2026.07.09 |
|---|---|
| Linux - 09. network (0) | 2026.07.09 |
| Linux - 07. shell script (0) | 2026.07.09 |
| Linux - 06. io device (0) | 2026.07.09 |
| Linux - 05. filesystem (0) | 2026.07.09 |
