Debian 계열에서 패키지를 올릴 때 설정 파일이 사용자에 의해 수정돼 있으면 dpkg 가 어느 쪽을 남길지 묻는다. 입력을 받을 수 없는 환경(컨테이너 빌드, CI, 스크립트)에서는 그 질문에 답할 수 없어 설치가 통째로 실패한다.
Configuration file '/etc/sysctl.conf'
==> File on system created by you or by a script.
==> File also in package provided by package maintainer.
What would you like to do about it ? Your options are:
Y or I : install the package maintainer's version
N or O : keep your currently-installed version
D : show the differences between the versions
Z : start a shell to examine the situation
The default action is to keep your current version.
*** sysctl.conf (Y/I/N/O/D/Z) [default=N] ? dpkg: error processing package procps (--configure):
end of file on stdin at conffile prompt
E: Sub-process /usr/bin/dpkg returned an error code (1)
end of file on stdin at conffile prompt 이 핵심이다. 질문은 떴는데 표준 입력이 닫혀 있어 EOF 를 읽었다는 뜻이다.
터미널이 있으면 그냥 다시 실행해 답한다.
sudo dpkg --configure -a
무엇이 달라졌는지 보고 정하려면 프롬프트에서 D 를 누르거나, 나중에 새 버전 파일과 직접 비교한다. dpkg 는 채택하지 않은 쪽을 남겨 둔다 — 기존 파일을 유지하면 배포판 버전이 .dpkg-dist 로, 새 버전을 채택하면 기존 파일이 .dpkg-old 로 남는다.
diff -u /etc/sysctl.conf /etc/sysctl.conf.dpkg-dist
스크립트나 Dockerfile 에서는 미리 정책을 정해 준다.
export DEBIAN_FRONTEND=noninteractive
sudo apt-get -y \
-o Dpkg::Options::="--force-confdef" \
-o Dpkg::Options::="--force-confold" \
install -f
| 옵션 | 뜻 |
|---|---|
--force-confold |
기존 파일을 유지한다 |
--force-confnew |
패키지의 새 파일로 덮는다 |
--force-confdef |
기본 동작이 정해져 있으면 묻지 않고 그대로 따른다 |
confdef 와 confold 를 같이 주는 것이 관례다. 기본 동작이 정의된 항목은 조용히 넘기고, 판단이 필요한 항목은 기존 파일을 남긴다. 설정을 손댄 적이 없는 이미지 빌드에서는 confnew 가 더 맞을 때도 있다.
Dockerfile 에서는 아예 프롬프트가 나올 여지를 없애 둔다.
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
-o Dpkg::Options::="--force-confdef" \
-o Dpkg::Options::="--force-confold" \
procps ca-certificates \
&& rm -rf /var/lib/apt/lists/*
DEBIAN_FRONTEND 는 ENV 로 이미지 전체에 박기보다 ARG 로 빌드 중에만 주는 편이 낫다. 이미지 사용자가 나중에 대화형으로 패키지를 설치할 때 영향을 받지 않는다.
앞선 apt 프로세스가 비정상 종료하면 잠금 파일이 남아 다음 실행이 막힌다.
sudo fuser -v /var/lib/dpkg/lock-frontend
sudo fuser -v /var/lib/apt/lists/lock
먼저 정말로 도는 프로세스가 없는지 확인한다. 자동 업데이트(unattended-upgrades)가 백그라운드에서 돌고 있는 경우가 흔하고, 그 상태에서 잠금 파일을 지우면 패키지 데이터베이스가 깨진다. 아무 프로세스도 잡히지 않을 때만 지운다.
sudo rm -f /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock
sudo dpkg --configure -a
sudo apt-get -f install
sudo apt-get check