Ubuntu APT 문제 해결: 손상된 패키지, 홀드(Hold) 및 GPG 오류 수정

추측 없이 Ubuntu APT를 해결하세요.

Page content

장기간 사용된 Ubuntu 머신에서는 APT 실패가 흔히 발생하며, 이는 주로 릴리스 업그레이드, 서드파티 리포지토리 변경, PPA 제거, 수동으로 설치된 .deb 파일 또는 중단된 패키지 설치 후에 나타납니다.

오류 메시지는 극적으로 보일 수 있지만, 대부분의 APT 문제는 신비로운 것이 아닙니다. 이는 리포지토리, 버전 및 설치된 패키지에 대한 APT의 관점이 더 이상 일치하지 않는 상태(state) 문제입니다.

laptop ubuntu apt packages

APT는 다음 네 가지 질문에 답하려고 합니다:

  1. 어떤 리포지토리가 활성화되어 있습니까?
  2. 어떤 패키지 버전이 사용 가능한가요?
  3. 어떤 패키지가 이미 설치되어 있습니까?
  4. 어떤 패키지 변경이 허용됩니까?

이 답변들이 충돌할 때, 패키지가 보류(held)되거나, 종속성이 깨지거나, 공개 키가 누락되거나, PPA 오류가 발생하거나, 업그레이드 중에 패키지가 유지(kept back)되는 현상이 발생합니다. 이 가이드는 개발자, DevOps 엔지니어 및 Linux 사용자를 위해 작성되었으며, 포럼 스레드의 임의 명령을 맹목적으로 붙여넣지 않고 시스템을 복구할 수 있는 실용적인 Ubuntu APT 문제 해결 시퀀스를 제공합니다. 일상적인 설치 및 업그레이드 명령은 Ubuntu APT 및 dpkg 치트시트와 함께 사용하고, 관련 Linux 워크플로우에 대해서는 더 넓은 Developer Tools 컬렉션을 참조하십시오.

요약본

시스템이 약간의 손상만 입었다면 다음에서부터 시작하십시오:

sudo apt update
sudo dpkg --configure -a
sudo apt --fix-broken install
sudo apt update
sudo apt upgrade

패키지가 유지(kept back)되는 경우:

apt list --upgradable
apt-mark showhold
sudo apt full-upgrade

PPA 또는 서드파티 리포지토리가 실패하는 경우:

ls /etc/apt/sources.list.d/
sudo apt update

실패하는 리포지토리 줄을 읽고 해당 리포지토리를 비활성화하거나 수정하십시오. NO_PUBKEY를 보는 경우 키서버에서 임의의 키를 맹목적으로 가져오지 마십시오. 대신 공식 리포지토리 지침을 찾아 리포지토리 키를 /etc/apt/keyrings에 설치하고 signed-by를 사용하여 해당 리포지토리에 바인딩하십시오.

수정하기 전에: APT 오류를 먼저 읽으십시오

먼저 다음을 실행하십시오:

sudo apt update

이 단계를 건너뛰지 마십시오. apt update는 패키지 메타데이터를 새로 고칩니다. 패키지를 업그레이드하지는 않습니다. 이 명령은 Ubuntu가 구성된 모든 리포지토리를 읽고 메타데이터를 검증할 수 있는지 알려줍니다.

그런 다음 Ubuntu 버전 및 코드네임을 확인하십시오. /etc/apt/sources.list.d/에 오래된 릴리스 이름이 있는 것이 404 및 Release 파일 오류의 흔한 원인입니다. 현재 어떤 릴리스를 사용 중인지 확실하지 않다면 Ubuntu 버전 확인 방법을 참조하십시오:

lsb_release -a

또는:

cat /etc/os-release

업그레이드 가능한 항목도 확인하십시오:

apt list --upgradable

보류(hold)된 패키지가 있는지 확인하십시오:

apt-mark showhold

이로써 결정 트리의 첫 번째 분기가 생깁니다. 실패 클래스를 먼저 식별하면 문제 해결이 쉬워집니다. 각 클래스에는 고유한 첫 번째 수정 방법이 있기 때문입니다:

  • 리포지토리 문제: apt update 실패.
  • 종속성 문제: apt update는 작동하지만 설치 또는 업그레이드가 실패함.
  • 보류(hold)된 패키지 문제: APT가 특정 패키지를 변경하는 것을 거부함.
  • 혼합 소스 문제: PPA, 수동 .deb, 또는 오래된 리포지토리가 호환되지 않는 버전을 제공함.
  • 중단된 설치 문제: dpkg가 구성되지 않은 추출된 패키지를 남김.

흔한 Ubuntu APT 실패 유형

유지(Kept Back)된 패키지

유지된 패키지는 항상 오류가 있는 것은 아닙니다. 이는 APT가 현재 명령을 사용하여 패키지를 업그레이드하지 않기로 결정했다는 의미입니다. 이는 종종 업그레이드에 새로운 종속성 설치, 오래된 패키지 제거 또는 단순한 apt upgrade가 수행하지 않는 방식으로 패키지 변경이 필요할 때 발생합니다.

상세 정보를 확인하십시오:

apt list --upgradable
apt-cache policy package-name

APT가 무엇을 하려는지 읽은 후에만 전체 업그레이드를 시도하십시오:

sudo apt full-upgrade

full-upgrade는 업그레이드를 완료하려면 필요한 경우 새 패키지를 설치하고 패키지를 제거할 수 있습니다. 이는 유용하지만, 수용하기 전에 제안된 변경 사항을 읽어야 하는 이유이기도 합니다. 워크스테이션에서는 검토 후 full-upgrade가 일반적으로 문제가 없습니다. 서버에서는 제거 대상 목록을 두 번 확인하십시오.

보류(Hold)된 패키지

보류된 패키지는 단순히 유지된 패키지와 다릅니다. 홀드(Hold)는 APT가 해당 패키지를 자동으로 설치, 업그레이드 또는 제거하는 것을 방지하는 명시적 지침입니다. 홀드는 커널, 데이터베이스, 드라이버 또는 런타임 버전을 고정(pinning)하는 데 유용하지만, 쉽게 잊어버리기也容易합니다.

보류된 패키지를 나열하십시오:

apt-mark showhold

패키지를 보류(hold)하십시오:

sudo apt-mark hold package-name

보류(hold)를 제거하십시오:

sudo apt-mark unhold package-name

보류된 패키지와 관련된 종속성 오류가 보이는 경우, 그 보류가 여전히 의도적인지 결정하십시오. 보류를 자동으로 제거하지 마십시오. 이는 프로덕션 서비스, 드라이버 또는 호환성이 민감한 도구 체인을 보호하고 있을 수 있습니다.

깨진 종속성

깨진 종속성은 APT가 유효한 패키지 세트를 찾을 수 없음을 의미하며, 이는 일반적으로 손상된 다운로드보다는 버전 충돌을 나타냅니다.

흔한 원인은 다음과 같습니다:

  • 패키지가 사용할 수 없는 버전을 필요로 함.
  • PPA가 Ubuntu가 예상하는 것보다 더 새로운 라이브러리를 제공함.
  • 수동으로 설치된 .deb가 다른 릴리스의 패키지에 종속됨.
  • 패키지 설치가 중단됨.
  • 잘못된 Ubuntu 릴리스용 리포지토리가 활성화됨.
  • 패키지 고정(pinning) 또는 보류(hold)가 필요한 버전 변경을 방지함.

다음으로 시작하십시오:

sudo dpkg --configure -a
sudo apt --fix-broken install

그런 다음 패키지를 검사하십시오:

apt-cache policy package-name
apt-cache depends package-name
apt-cache rdepends package-name

그런 다음 일련의 복구 명령을 실행하는 대신 이러한 명령을 사용하여 APT를 막고 있는 패키지 버전 충돌을 찾십시오.

GPG 키 및 NO_PUBKEY 오류

NO_PUBKEY 오류는 APT가 리포지토리 메타데이터를 받았지만 필요한 공개 키가 누락되어 서명을 검증할 수 없음을 의미합니다. 이는 단순히 다운로드 문제가 아닌 신뢰(trust) 문제입니다.

전형적인 오류는 다음과 같습니다:

The following signatures could not be verified because the public key is not available: NO_PUBKEY ABCD1234EF567890

오래된 지침은 종종 apt-key add를 사용했지만, 새로운 리포지토리 설정에는 이를 피하십시오. 현대적인 Ubuntu 시스템은 리포지토리별 키링(keyring)과 signed-by를 사용해야 합니다.

더 나은 패턴은 다음과 같습니다:

sudo install -d -m 0755 /etc/apt/keyrings

curl -fsSL https://example.com/repo-key.gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/example.gpg

echo "deb [signed-by=/etc/apt/keyrings/example.gpg] https://example.com/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/example.list

sudo apt update

URL 및 리포지토리 줄을 벤더의 공식 지침으로 대체하십시오.

중요한 부분은 다음과 같습니다:

signed-by=/etc/apt/keyrings/example.gpg

signed-by 줄은 키를 하나의 리포지토리에 바인딩하므로, 모든 서드파티 키를 전역 신뢰 저장소에 넣는 것보다 더 깔끔하고 안전합니다.

잘못된 PPA 또는 Release 파일 오류

PPA 실패는 종종 다음과 같이 보입니다:

The repository does not have a Release file.

또는:

404 Not Found

흔한 원인:

  • PPA가 사용 중인 Ubuntu 릴리스를 지원하지 않음.
  • Ubuntu를 업그레이드했지만 PPA가 여전히 오래된 코드네임을 가리킴.
  • PPA가 삭제됨.
  • 관리자가 패키지 게시를 중단함.
  • 다른 Ubuntu 버전을 위한 PPA를 추가함.

코드네임을 확인하십시오:

. /etc/os-release
echo "$VERSION_CODENAME"

서드파티 소스 파일을 나열하십시오:

ls /etc/apt/sources.list.d/

이를 검사하십시오:

grep -R "^deb" /etc/apt/sources.list /etc/apt/sources.list.d/

의심스러운 소스를 이름 변경으로 비활성화하십시오:

sudo mv /etc/apt/sources.list.d/example.list /etc/apt/sources.list.d/example.list.disabled
sudo apt update

파일을 비활성화한 후 APT가 작동하면 문제의 소스를 찾은 것이므로 이를 수정하거나 영구적으로 제거할 수 있습니다.

안전한 APT 문제 해결 워크플로우

단계 1: 메타데이터 새로 고침

sudo apt update

이 명령이 실패하면 패키지 복구 시도 전에 리포지토리를 수정하십시오. APT는 패키지 색인이陈旧하거나 불완전한 경우 종속성을 올바르게 해결할 수 없습니다.

다음 내용을 포함하는 줄을 찾으십시오:

NO_PUBKEY
Release file
404 Not Found
does not have a Release file
The repository is not signed

이는 리포지토리 또는 신뢰 문제이며, 패키지 복구를 시도하기 전에 수정해야 합니다.

단계 2: 중단된 패키지 구성 완료

패키지 설치가 중단된 경우, dpkg는 파일을 추출했지만 패키지를 구성하지 않았을 수 있습니다.

다음을 실행하십시오:

sudo dpkg --configure -a

성공하면 계속 진행하십시오:

sudo apt --fix-broken install

실패하면 패키지 이름과 오류를 주의 깊게 읽으십시오. 오류 하단에 있는 패키지 이름이 원래 설치하려 했던 패키지보다 더 중요할 수 있습니다.

단계 3: APT에 종속성 복구 요청

sudo apt --fix-broken install

이 명령은 누락된 종속성을 설치하거나 충족할 수 없는 패키지를 제거하여 APT가 종속성 문제를 수정하도록 요청합니다. 특히 제거 대상 목록을 포함한 제안된 작업을 주의 깊게 읽으십시오.

APT가 다음을 제거하려 하면 주의하십시오:

  • ubuntu-desktop
  • ubuntu-server
  • linux-generic
  • 디스플레이 관리자 패키지
  • 네트워크 패키지
  • 데이터베이스 패키지
  • 컨테이너 런타임 패키지
  • 데스크톱 환경 패키지

때때로 메타패키지를 제거하는 것은 무해합니다. 때로는 패키지 소스가 나쁘게 혼합되었음을 나타내는 경고 신호일 수 있습니다. 이해하지 못한 채로 대규모 제거를 수용하지 마십시오.

단계 4: 보류(Hold)된 패키지 확인

apt-mark showhold

보류된 패키지가 업그레이드를 막고 있다면 이를 검사하십시오:

apt-cache policy package-name

더 이상 보류가 필요하지 않으면:

sudo apt-mark unhold package-name
sudo apt update
sudo apt upgrade

보류가 의도적인 경우 APT와 싸우지 마십시오. 보호를 제거하는 대신 보류 주변의 리포지토리 또는 패키지 선택을 수정하십시오.

단계 5: 패키지 버전 검사

종속성 문제가 있는 패키지의 경우:

apt-cache policy package-name

이는 다음을 보여줍니다:

  • 설치된 버전
  • 후보 버전
  • 사용 가능한 버전
  • 각 버전을 제공하는 리포지토리

apt-cache policy는 각 사용 가능한 버전의 출처를 보여주므로 가장 유용한 APT 디버깅 명령 중 하나입니다.

예시:

apt-cache policy docker-ce

후보 버전이 예상치 못한 PPA 또는 오래된 리포지토리에서 온 경우, 종속성 충돌의 원인을 찾은 것입니다.

단계 6: 혼합 리포지토리 탐색

활성화된 소스를 나열하십시오:

grep -R "^deb" /etc/apt/sources.list /etc/apt/sources.list.d/

다음을 찾아보십시오:

  • 오래된 Ubuntu 코드네임
  • Ubuntu의 Debian 리포지토리
  • 다른 Ubuntu 릴리스용 PPA
  • 중복 벤더 리포지토리
  • 동일한 도구에 대해 Snap 및 APT 지침이 혼합됨
  • 소프트웨어 제거 후 남은 오래된 .list 파일

흔한 안티패턴은 벤더 리포지토리에서 도구를 설치한 후 나중에 겹치는 라이브러리를 제공하는 PPA 또는 수동 .deb를 추가하는 것입니다. APT는 많은 소스를 처리할 수 있지만, 사용자가 리포지토리를 정렬하지 않는 한 충돌하는 의도를 조정할 수 없습니다.

단계 7: 설치 또는 업그레이드 시뮬레이션 시도

변경 사항을 만들기 전에 시뮬레이션하십시오:

apt -s install package-name

또는:

apt -s full-upgrade

-s 옵션은 작업을 시뮬레이션합니다. 시스템을 변경하지 않고 APT가 무엇을 할지 보고 싶을 때 유용합니다.

보류(Hold)된 패키지 수정

보류된 패키지 나열

apt-mark showhold

아무것도 인쇄되지 않으면 apt-mark로 보류된 패키지가 없으며 종속성 또는 리포지토리 확인으로 넘어갈 수 있습니다.

의도적으로 패키지 보류

sudo apt-mark hold package-name

패키지를 보류해야 하는 좋은 이유:

  • 하드웨어와 호환되는 커널 버전이 알려져 있음.
  • 데이터베이스 업그레이드가 계획이 필요함.
  • 드라이버 업데이트가 GPU를 깨뜨림.
  • 런타임 버전이 프로덕션과 일치해야 함.
  • 벤더 패키지가 최신 종속성과 호환되지 않음.

패키지를 보류해서는 안 되는 나쁜 이유:

  • 오래된 가이드에서 명령을 복사함.
  • 왜 보류되었는지 잊어버림.
  • 이해하지 못한 채로 종속성 오류를 피함.

보류 제거

sudo apt-mark unhold package-name

그런 다음 업데이트 및 업그레이드하십시오:

sudo apt update
sudo apt upgrade

패키지가 여전히 업그레이드되지 않으면, 이는 보류 문제만이 아닙니다. 정책을 확인하십시오:

apt-cache policy package-name

깨진 종속성 수정

표준 복구 시퀀스

패키지 설치 또는 업그레이드가 중간에 실패한 경우 이 시퀀스를 사용하십시오:

sudo apt update
sudo dpkg --configure -a
sudo apt --fix-broken install
sudo apt upgrade

이 순서가 중요합니다. 각 단계가 다음 단계를 위한 기반을 마련하기 때문입니다: apt update는 리포지토리 메타데이터를 새로 고치고, dpkg --configure -a는 추출된 패키지의 구성을 완료하며, apt --fix-broken install은 APT가 누락되거나 충돌하는 종속성을 조정하도록 하고, apt upgrade는 정상적인 패키지 업그레이드를 재개합니다.

잘못 설치된 로컬 패키지 제거

다운로드된 .deb를 설치한 후 문제가 발생했다면 이를 검사하십시오:

dpkg -l | grep package-name
apt-cache policy package-name

제거하십시오:

sudo apt remove package-name

구성 파일도 문제를 일으키고 있다면:

sudo apt purge package-name

그런 다음 복구하십시오:

sudo apt --fix-broken install

손상된 패키지 재설치

패키지가 설치되었지만 손상된 경우:

sudo apt install --reinstall package-name

이는 파일이 누락되거나 손상되었지만 패키지 소스는 다른 면에서 건강하며 버전 변경 없이 설치된 파일을 새로 고치고 싶을 때 유용합니다.

PPA 및 서드파티 리포지토리 문제 수정

PPA 및 서드파티 리포지토리 찾기

ls /etc/apt/sources.list.d/

활성 리포지토리 줄을 표시하십시오:

grep -R "^deb" /etc/apt/sources.list /etc/apt/sources.list.d/

새로운 Ubuntu 시스템에서는 deb822 형식을 사용하는 .sources 파일도 볼 수 있습니다:

ls /etc/apt/sources.list.d/*.sources

이를 표시하십시오:

cat /etc/apt/sources.list.d/*.sources

PPA 안전하게 비활성화

소스 파일 이름을 변경하십시오:

sudo mv /etc/apt/sources.list.d/example.list /etc/apt/sources.list.d/example.list.disabled
sudo apt update

deb822 파일의 경우:

sudo mv /etc/apt/sources.list.d/example.sources /etc/apt/sources.list.d/example.sources.disabled
sudo apt update

소스 파일 이름 변경은 리포지토리 구성을 즉시 삭제하는 것보다 가역적이고 안전합니다. 잘못된 소스를 비활성화한 경우 다시 이름을 변경할 수 있기 때문입니다.

PPA에서 패키지 제거

PPA를 비활성화하면 해당 리포지토리로부터의 향후 패키지 다운로드가 중지됩니다. 이는 이미 해당 PPA에서 설치된 패키지를 자동으로 다운그레이드하지 않습니다.

PPA가 라이브러리 충돌을 일으켰다면, 패키지를 Ubuntu 버전으로 다운그레이드해야 할 수 있습니다.

ppa-purge를 설치하십시오:

sudo apt install ppa-purge

그런 다음 PPA를 정리(purge)하십시오:

sudo ppa-purge ppa:owner/name

ppa-purge를 주의해서 사용하고 수용하기 전에 제안된 변경 사항을 읽으십시오. 이는 여러 관련 패키지를 제거하거나 다운그레이드할 수 있습니다.

릴리스 업그레이드 후

Ubuntu 업그레이드 후, 오래된 PPA는 흔한 오류 원인입니다.

오래된 코드네임을 확인하십시오:

grep -R "jammy\|noble\|oracular\|plucky" /etc/apt/sources.list /etc/apt/sources.list.d/

코드네임을 실제 시스템에 맞게 조정하십시오. 예를 들어 Ubuntu 24.04를 사용 중이라면 코드네임은 noble입니다. 서드파티 소스가 여전히 오래된 코드네임을 가리키면 해당 벤더가 현재 Ubuntu 릴리스를 지원하는지 확인하십시오. 업그레이드를 복구하는 것이 아니라 새 머신을 설정 중이라면, Ubuntu 24.04 설치 가이드는 처음부터 signed-by와 함께 벤더 리포지토리를 추가하는 과정을 안내합니다.

코드네임만 수정하고 최상의 결과를 기대하지 마십시오. 일부 리포지토리는 모든 Ubuntu 버전에 대해 패키지를 게시하지 않으므로, 먼저 릴리스에 대한 벤더 지원을 확인하십시오.

GPG 및 NO_PUBKEY 오류 수정

NO_PUBKEY의 의미

APT 리포지토리는 서명된 메타데이터를 게시하며, 머신은 해당 메타데이터를 검증하기 위해 일치하는 공개 키가 필요합니다. 키가 누락되면 APT는 리포지토리를 신뢰하기를 거부합니다. 이는 원하는 동작입니다 — 오류를 사라지게 하기 위해 서명 검사를 비활성화하지 마십시오.

현대적인 키링 패턴

키링 디렉토리를 생성하십시오:

sudo install -d -m 0755 /etc/apt/keyrings

벤더 키를 다운로드하고 디어모어(dearmor)하십시오:

curl -fsSL https://example.com/repository-key.gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/example.gpg

읽기 권한을 설정하십시오:

sudo chmod 0644 /etc/apt/keyrings/example.gpg

signed-by와 함께 리포지토리를 추가하십시오:

echo "deb [signed-by=/etc/apt/keyrings/example.gpg] https://example.com/linux/ubuntu noble stable" \
  | sudo tee /etc/apt/sources.list.d/example.list

그런 다음 업데이트하십시오:

sudo apt update

필요하면 noble을 Ubuntu 코드네임으로 대체하십시오:

. /etc/os-release
echo "$VERSION_CODENAME"

apt-key가 잘못된 습관인 이유

오래된 가이드는 종종 다음을 사용합니다:

curl -fsSL https://example.com/key.gpg | sudo apt-key add -

새로운 설정에는 apt-key add를 피하십시오. 오래된 apt-key 스타일은 키를 광범위한 신뢰 영역에 추가하여 어떤 키가 어떤 리포지토리에 대해 신뢰되는지 추론하기 어렵게 만듭니다. 반면 현대적인 signed-by 스타일은 키를 특정 리포지토리에 범위를 지정하며, 이는 기본적인 공급망 위생(hygiene)입니다.

레거시 신뢰 키 찾기

아직 다음에 오래된 키가 있을 수 있습니다:

/etc/apt/trusted.gpg
/etc/apt/trusted.gpg.d/

파일을 나열하십시오:

ls -l /etc/apt/trusted.gpg.d/

키를 임의로 삭제하지 마십시오. 먼저 각 키를 리포지토리에 매핑한 후, 한 번에 하나의 리포지토리를 /etc/apt/keyringssigned-by로 마이그레이션하십시오.

흔한 GPG 실수

NO_PUBKEY 오류를 수정할 때 키서버를 첫 번째 선택으로 사용하지 마십시오.

더 나은 순서:

  1. 벤더의 공식 설치 문서 사용.
  2. 벤더의 공식 HTTPS URL에서 키 다운로드.
  3. /etc/apt/keyrings에 저장.
  4. signed-by로 바인딩.
  5. sudo apt update 실행.

다음 단축키를 피하십시오:

sudo apt update --allow-unauthenticated
sudo apt install --allow-unauthenticated package-name

이는 일시적으로 작동할 수 있지만, 조작된 리포지토리 메타데이터로부터 보호하는 서명 검사를 제거합니다.

“리포지토리가 서명되지 않음” 수정

이 오류는 일반적으로 다음 중 하나를 의미합니다:

  • 리포지토리가 서명된 메타데이터를 게시하지 않음.
  • 리포지토리 URL이 잘못됨.
  • 리포지토리가 더 이상 Ubuntu 버전을 지원하지 않음.
  • 프록시 또는 미러가 잘못된 콘텐츠를 반환함.
  • 벤더가 이제 HTTPS를 기대하는 곳에서 HTTP를 사용 중임.
  • 소스 파일에 잘못된 스위트(suite) 또는 컴포넌트가 있음.

실패하는 소스를 찾십시오:

sudo apt update

APT가 URL을 인쇄합니다. 그런 다음 이를 검색하십시오:

grep -R "example.com" /etc/apt/sources.list /etc/apt/sources.list.d/

임시적으로 비활성화하십시오:

sudo mv /etc/apt/sources.list.d/example.list /etc/apt/sources.list.d/example.list.disabled
sudo apt update

파일을 비활성화한 후 APT가 다시 작동하면, 오래된 구성을 다시 활성화하는 대신 벤더의 현재 공식 지침에서 해당 리포지토리를 재설치하십시오.

중복 리포지토리 경고 수정

APT가 대상이 여러 번 구성되었음을 경고할 수 있습니다.

일치하는 항목을 나열하십시오:

grep -R "repo-url-or-domain" /etc/apt/sources.list /etc/apt/sources.list.d/

중복 리포지토리는 종종 벤더 설치 스크립트를 여러 번 실행한 후에 나타납니다.

하나의 소스 파일을 유지하십시오. 다른 것을 비활성화하십시오:

sudo mv /etc/apt/sources.list.d/duplicate.list /etc/apt/sources.list.d/duplicate.list.disabled
sudo apt update

중복 경고는 항상 치명적이지는 않지만, 이는 부실한 구성의 신호이므로 하나의 소스 파일을 유지하고 중복을 비활성화하십시오.

잘못된 Ubuntu 릴리스의 패키지 수정

APT 문제 중 가장 나쁜 것 중 하나는 Ubuntu 릴리스를 혼합하는 것입니다. 예를 들어 Ubuntu 24.04 머신은 Ubuntu 22.04 또는 Debian testing에서 패키지를 가볍게 가져오지 않아야 합니다. 때때로 잠시 동안 작동하지만, 결국 종속성 그래프가 APT가 깔끔하게 해결할 수 없는 퍼즐이 됩니다.

릴리스를 확인하십시오:

. /etc/os-release
echo "$VERSION_CODENAME"

소스를 검색하십시오:

grep -R "^deb" /etc/apt/sources.list /etc/apt/sources.list.d/

활성화된 소스에서 외래 코드네임을 찾고, 영향을 받은 패키지를 검사하십시오:

apt-cache policy package-name

설치된 버전이 오래되거나 외래 리포지토리에서 온 경우, 해당 리포지토리를 비활성화하고 Ubuntu 리포지토리에서 영향을 받은 패키지를 다운그레이드하거나 재설치하십시오.

보수적인 복구 경로는 다음과 같습니다:

sudo apt update
sudo apt install --reinstall package-name

더 깊은 충돌의 경우, 외래 버전 위에 업그레이드를 강제하는 대신 패키지를 제거하고 올바른 소스에서 재설치해야 할 수 있습니다.

APT 캐시 정리 및 사용하지 않는 패키지

APT 캐시 정리는 자체적으로 종속성 수정이 아니지만, 많은 실패한 설치 후 디스크 공간을 회수하고陈旧한 패키지 파일을 지우는 데 도움이 될 수 있습니다.

자동으로 설치되어 더 이상 필요하지 않은 패키지를 제거하십시오:

sudo apt autoremove

다운로드된 패키지 파일을 정리하십시오:

sudo apt clean

또는 오버랩된 패키지 파일만 제거하십시오:

sudo apt autoclean

서버 및 수동으로 설치된 드라이버 스택이 있는 데스크톱에서 autoremove를 주의해서 사용하고, 수용하기 전에 제거 목록을 읽으십시오.

실용적인 APT 문제 해결 레시피

레시피: 패키지가 유지(Kept Back)됨

sudo apt update
apt list --upgradable
apt-mark showhold
sudo apt full-upgrade

APT가 시뮬레이션 후 합리적인 변경을 제안하면 수용하십시오. 대규모 제거를 제안하면 중단하고 검사하십시오:

apt-cache policy package-name

레시피: 보류(Hold)된 패키지가 업그레이드를 차단함

apt-mark showhold
apt-cache policy package-name
sudo apt-mark unhold package-name
sudo apt upgrade

프로덕션 소프트웨어를 보호하는 보류가 중단된 업그레이드를 트리거할 수 있으므로, 보류가 더 이상 의도적이지 않은 경우에만 보류를 해제하십시오.

레시피: 중단된 설치

sudo dpkg --configure -a
sudo apt --fix-broken install
sudo apt upgrade

레시피: NO_PUBKEY 오류

  1. sudo apt update에서 리포지토리 식별.
  2. 벤더의 현재 공식 설치 지침 찾기.
  3. 키를 /etc/apt/keyrings에 설치.
  4. 소스 파일에서 signed-by 사용.
  5. sudo apt update 실행.

예시 구조:

sudo install -d -m 0755 /etc/apt/keyrings

curl -fsSL https://example.com/key.gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/example.gpg

sudo chmod 0644 /etc/apt/keyrings/example.gpg

echo "deb [signed-by=/etc/apt/keyrings/example.gpg] https://example.com/ubuntu noble main" \
  | sudo tee /etc/apt/sources.list.d/example.list

sudo apt update

레시피: PPA에 Release 파일이 없음

sudo apt update
ls /etc/apt/sources.list.d/
grep -R "ppa.launchpadcontent.net\|launchpad" /etc/apt/sources.list.d/

PPA를 비활성화하십시오:

sudo mv /etc/apt/sources.list.d/example.list /etc/apt/sources.list.d/example.list.disabled
sudo apt update

그런 다음 해당 PPA에서 패키지를 제거, 대체 또는 정리할지 결정하십시오.

레시피: 수동 .deb가 종속성을 깨뜨림

dpkg -l | grep package-name
apt-cache policy package-name
sudo apt remove package-name
sudo apt --fix-broken install

여전히 소프트웨어가 필요한 경우, 시간이 지남에 따라 종속성 충돌이 누적되는 경향이 있는 반복적인 수동 .deb 설치보다 벤더의 현재 APT 리포지토리를 선호하십시오.

필수 APT 문제 해결 명령

리포지토리 및 메타데이터

sudo apt update
grep -R "^deb" /etc/apt/sources.list /etc/apt/sources.list.d/
ls /etc/apt/sources.list.d/

패키지 상태

apt list --installed
apt list --upgradable
apt-mark showhold
dpkg -l | grep package-name

패키지 정책 및 종속성

apt-cache policy package-name
apt-cache depends package-name
apt-cache rdepends package-name

복구

sudo dpkg --configure -a
sudo apt --fix-broken install
sudo apt install --reinstall package-name
sudo apt full-upgrade

정리

sudo apt autoremove
sudo apt autoclean
sudo apt clean

시뮬레이션

apt -s install package-name
apt -s full-upgrade

하지 말아야 할 것

/var/lib/dpkg를 임의로 삭제하지 마십시오

dpkg 상태 파일을 삭제하라는 조언을 보면 의심하십시오. dpkg 데이터베이스는 설치된 패키지의 기록이며, 이를 조각내어 삭제하면 복구 가능한 패키지 문제를 전체 시스템 복구 프로젝트로 만들 수 있습니다.

서명 검사를 비활성화하지 마십시오

다음을 피하십시오:

--allow-unauthenticated

리포지토리를 검증할 수 없으면 키를 수정하거나 리포지토리를 비활성화하여 인증을 우회하지 마십시오.

Ubuntu 릴리스를 가볍게 혼합하지 마십시오

APT 고정(pinning)과 종속성 결과를 이해하지 않는 한 다른 Ubuntu 릴리스용 리포지토리를 추가하지 마십시오.

이는 특히 다음에 적용됩니다:

  • 데스크톱 환경
  • 그래픽 드라이버
  • Python 스택
  • 컨테이너 런타임
  • Kubernetes 패키지
  • 데이터베이스 패키지

PPA를 무해하다고 여기지 마십시오

PPA는 유용하지만, 여전히 라이브러리와 시스템 패키지를 대체할 수 있는 패키지 리포지토리입니다. 이는 사용자의 의도일 수도 있고, 다음 업그레이드가 깨지는 이유일 수도 있습니다. 광범위한 시스템 기반이 아닌 특정 애플리케이션에 PPA를 선호하십시오. 관리자를 신뢰하고 업그레이드 경로를 이해하지 않는 한 말입니다.

APT 문제 해결 결정 트리

다음 멘탈 모델을 사용하십시오:

flowchart TD A["Does sudo apt update fail?"] -->|yes| B["Fix repositories, GPG keys, PPAs, network, or release files"] A -->|no| C["Did an install or upgrade get interrupted?"] C -->|yes| D["Run dpkg --configure -a, then apt --fix-broken install"] C -->|no| E["Are packages held?"] E -->|yes| F["Inspect apt-mark showhold and decide whether to unhold"] E -->|no| G["Are packages kept back?"] G -->|yes| H["Inspect apt full-upgrade simulation and package policy"] G -->|no| I["Is a third-party source involved?"] I -->|yes| J["Inspect apt-cache policy and source files"] I -->|no| K["Inspect the specific package dependency error"]

대부분의 APT 문제는 하나의 큰 오류로 취급하는 것을 중단하고 리포지토리 건강, 패키지 상태, 종속성 해결 및 신뢰 구성을 분리하기 시작하면 관리 가능해집니다. 위의 결정 트리는 이러한 규율의 약어입니다.

개발자 머신을 위한 권장 기준선

깨끗한 Ubuntu 개발자 워크스테이션을 위해 저는 다음 기준선을 선호합니다:

  • Ubuntu 리포지토리를 표준으로 유지.
  • 공식적이고 유지되는 벤더 APT 리포지토리만 사용.
  • 서드파티 리포지토리에 /etc/apt/keyringssigned-by 사용.
  • 오래된 apt-key 지침 피함.
  • 핵심 시스템 라이브러리를 대체하는 PPA 혼합 피함.
  • 빠르게 움직이는 개발자 종속성에 컨테이너, uv, pipx, asdf, mise 또는 언어 네이티브 도구 사용.
  • APT가 운영 체제, 드라이버, 서비스 및 안정적인 CLI 도구를 담당하도록 유지.

데스크톱 소프트웨어의 경우, 샌드박싱된 범용 패키지가 필요할 때 PPA보다 Flatpak 또는 Snap을 선호하십시오. APT는 기본 시스템을 관리할 때 훌륭하지만, 빠르게 움직이는 언어 생태계의 범용 개발자 종속성 관리자로 강제로 작동하게 만들 때 고통스럽습니다.

최종 APT 문제 해결 체크리스트

Ubuntu에서 APT가 깨졌을 때 다음 체크리스트를 따르십시오:

[ ] Run sudo apt update and read the first real error.
[ ] Check Ubuntu codename with /etc/os-release.
[ ] Finish interrupted installs with dpkg --configure -a.
[ ] Repair dependencies with apt --fix-broken install.
[ ] Check held packages with apt-mark showhold.
[ ] Inspect package versions with apt-cache policy.
[ ] Disable broken PPAs or third-party repositories.
[ ] Replace apt-key style repositories with signed-by keyrings.
[ ] Simulate risky operations with apt -s.
[ ] Read removals before accepting full-upgrade or autoremove.

APT는 취약하지 않지만 엄격하며, 이러한 엄격성은 기능입니다: 서명되지 않은 리포지토리, 불가능한 종속성 세트 및 우연한 패키지 대체가 시스템을 조용히 변경하는 것을 방지합니다. APT를 고치는 차분한 방법은 이러한 엄격성을 유지하고, 충돌하는 상태를 찾으며, 실제로 잘못된 가장 작은 것을 복구하는 것입니다.

구독하기

시스템, 인프라, AI 엔지니어링에 관한 새 글을 받아보세요.