새벽 3시 22분, CI 서버에서 빌드 파이프라인이 멈췄다는 알림이 왔습니다. 에러 메시지는 no space left on device 한 줄뿐이었습니다.
빌드마다 생긴 이미지와 캐시가 정리되지 않은 채 쌓였고, 50GB 디스크는 조용히 가득 찼습니다. 어떤 이미지를 지워도 되는지, 어떤 태그로 롤백할 수 있는지, 폐쇄망에는 이미지를 어떻게 옮길지 정해두지 않으면 이미지도 운영 장애의 원인이 됩니다.
Docker 이미지 운영 — 정리·태그 전략·아카이빙
새벽 3시 22분, 슬랙 알림이 울렸습니다. CI 서버에서 빌드 파이프라인이 죽었습니다. 에러 메시지는 딱 한 줄이었습니다 — no space left on device. 빌드마다 생성되던 이미지들이 정리되지 않은 채 쌓였고, 50GB 디스크는 조용히 가득 찼습니다. 로그는 못 쓰고, 새 이미지는 빌드가 안 되고, 서비스 배포는 전면 중단이었습니다. 이 상황을 겪고 나서야 "이미지 운영"이 개발만큼 중요하다는 걸 알게 됩니다. 이미지를 어떻게 쌓이게 둘 것인지, 어떤 기준으로 지울 것인지, 태그는 어떻게 관리할 것인지 — 이 챕터는 그 실무를 다룹니다.
CI 서버 디스크가 꽉 차거나 롤백이 안 되는 상황을 예방하는 실무 이미지 운영 기술을 익힙니다. 정리·태그·아카이빙 세 축을 모두 다룹니다.
- 1docker system df와 docker system df -v로 Docker 디스크 사용 구조 파악
- 2dangling 이미지 vs unused 이미지의 차이 — prune과 prune -a 영향 범위
- 3안전한 정리 순서 — image → volume → system, 데이터 손실 없이 공간 회수
- 4이미지 태그 전략 — latest 금지, git SHA + 날짜 조합, immutable tag 원칙
- 5CI cron 자동 정리 — docker image prune --filter until=72h 설정
- 6docker save / load로 이미지 아카이빙 — 폐쇄망 전달과 백업
이미 Docker를 사용 중인 환경이라면 system df 출력에서 실제 사용량을 바로 확인할 수 있습니다. 이미지가 없는 깨끗한 환경이라면 실습용 이미지 pull 단계를 먼저 진행하세요.
docker --versiondocker system dfdocker pull nginx:1.24 && docker pull nginx:1.25 && docker pull alpine:3.18mkdir -p ~/image-ops-lab && cd ~/image-ops-labdocker system prune -a --volumes -f
docker system df — 디스크 사용 구조를 한눈에 파악하기
CI 서버 디스크가 갑자기 꽉 찼습니다. 어디서 공간을 잡아먹고 있는지 모른 채 무작정 파일을 지우면 실행 중인 컨테이너나 중요한 볼륨 데이터까지 날릴 수 있습니다. docker system df는 Docker가 사용하는 공간을 유형별로 정리해서 보여주는 진단 명령입니다. 먼저 전체 그림을 파악하고, 그다음 어디를 정리할지 판단해야 안전합니다. 이 ConceptBlock에서는 docker system df와 -v 플래그의 출력을 읽는 방법과 각 항목의 의미를 다룹니다.

docker system df 기본 출력 읽기
# 실습 디렉토리 준비
mkdir -p /tmp/docker/part3/exam_8 && cd /tmp/docker/part3/exam_8
docker system df
출력 예시:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 23 4 8.2GB 6.1GB (74%)
Containers 7 2 124MB 98MB (79%)
Local Volumes 5 3 2.3GB 800MB (34%)
Build Cache - - 1.1GB 1.1GB
각 컬럼의 의미:
| 컬럼 | 의미 |
|---|---|
| TOTAL | Docker가 알고 있는 전체 수량 |
| ACTIVE | 현재 실행 중인 컨테이너에서 사용 중인 수량 |
| SIZE | 해당 유형이 차지하는 디스크 크기 |
| RECLAIMABLE | 지금 당장 정리해도 안전한 공간 (괄호 안은 비율) |
RECLAIMABLE이 높을수록 정리 효과가 크고 위험도는 낮습니다. 위 예시에서는 이미지에서만 6.1GB를 회수할 수 있습니다.
docker system df -v — 항목별 상세 조회
docker system df -v
출력 예시 (일부):
Images space usage:
REPOSITORY TAG IMAGE ID CREATED SIZE SHARED SIZE UNIQUE SIZE CONTAINERS
nginx 1.25 a6bd71249a7e 2 weeks ago 187MB 72.8MB 114MB 0
nginx 1.24 a8758716bb6a 4 months ago 187MB 72.8MB 114MB 0
<none> <none> d1a364dc548d 3 days ago 187MB 72.8MB 114MB 0
alpine 3.18 c1afedef4846 1 month ago 7.34MB 0B 7.34MB 0
Containers space usage:
...
Local Volumes space usage:
...
<none>:<none> 항목이 dangling 이미지입니다. TAG도 없고 REPOSITORY도 없으며 CONTAINERS가 0입니다. 이것들이 가장 먼저 정리할 대상입니다.
-v 출력에서 확인할 핵심 정보:
- CONTAINERS 컬럼이 0인 이미지 — 어떤 컨테이너도 이 이미지를 사용하지 않음
- UNIQUE SIZE — 이 이미지만 차지하는 고유 레이어 크기 (삭제 시 실제 회수량)
- SHARED SIZE — 다른 이미지와 공유하는 레이어 크기 (삭제해도 회수 안 됨)
- docker system df 출력에서 Images, Containers, Local Volumes, Build Cache 항목을 구분했는가?
- RECLAIMABLE 컬럼에서 지금 회수 가능한 공간을 확인했는가?
- docker system df -v 출력에서 <none>:<none> dangling 이미지를 찾을 수 있는가?
- CONTAINERS 컬럼이 0인 이미지와 사용 중인 이미지를 구분했는가?
실습: dangling 이미지 vs unused 이미지 — prune 영향 범위 직접 확인
dangling 이미지와 unused 이미지를 혼동하면 필요한 이미지까지 지우거나, 반대로 지워야 할 이미지를 남길 수 있습니다. 차이를 직접 만들어보고 prune이 각각 어떻게 동작하는지 확인합니다.
dangling 이미지 만들기
동일한 태그로 새 이미지를 빌드하거나 pull하면 이전 이미지는 태그가 떨어져 나가면서 dangling 상태가 됩니다.
# 임시 Dockerfile 생성
cat > /tmp/Dockerfile.test << 'EOF'
FROM alpine:3.18
RUN echo "version 1" > /version.txt
EOF
# 같은 태그로 두 번 빌드 — 첫 번째 이미지가 dangling이 됨
docker build -t test-dangling:latest -f /tmp/Dockerfile.test /tmp
docker build -t test-dangling:latest --no-cache -f /tmp/Dockerfile.test /tmp
# dangling 이미지 확인 (TAG가 <none>인 항목)
docker images -f dangling=true
# REPOSITORY TAG IMAGE ID CREATED SIZE
# <none> <none> a1b2c3d4e5f6 10 seconds ago 7.5MB
docker image prune — dangling만 삭제
# dangling 이미지만 삭제 (태그 있는 이미지는 건드리지 않음)
docker image prune -f
# 출력:
# Deleted Images:
# deleted: sha256:a1b2c3d4e5f6...
# Total reclaimed space: 7.5MB
prune 단독 실행은 안전합니다. 태그가 붙어 있는 이미지는 하나도 삭제되지 않습니다.
docker image prune -a — unused 이미지 전체 삭제
# 현재 컨테이너에서 사용 중이지 않은 이미지를 모두 삭제
# (태그 있어도 사용 중인 컨테이너가 없으면 삭제됨)
docker image prune -a -f
# 출력:
# Deleted Images:
# untagged: nginx:1.24
# deleted: sha256:a8758716bb6a...
# untagged: nginx:1.25
# deleted: sha256:a6bd71249a7e...
# Total reclaimed space: 6.1GB
-a는 강력하지만 다음 빌드 시 베이스 이미지를 다시 pull해야 하는 비용이 생깁니다. CI 서버에서는 유용하지만 개발 머신에서는 신중하게 사용해야 합니다.
두 명령의 차이 정리
| 명령어 | 삭제 대상 | 태그 있는 이미지 | 사용 중 이미지 |
|---|---|---|---|
docker image prune | dangling 이미지만 | 건드리지 않음 | 건드리지 않음 |
docker image prune -a | 사용 중이지 않은 모든 이미지 | 삭제됨 | 건드리지 않음 |
두 경우 모두 현재 실행 중이거나 중지된 컨테이너에서 사용 중인 이미지는 삭제하지 않습니다.
안전한 정리 순서 — 데이터 손실 없이 공간 회수하기
docker system prune -a --volumes를 한 번에 실행하면 가장 많은 공간을 회수할 수 있습니다. 하지만 이 명령은 볼륨 데이터까지 삭제합니다. 데이터베이스 볼륨이 포함되어 있다면 데이터 전체를 잃을 수 있습니다. 안전한 정리는 단계적으로 진행하고, 각 단계에서 무엇이 사라지는지 확인한 다음 넘어가야 합니다. 이 ConceptBlock에서는 위험도가 낮은 순서부터 정리하는 4단계 전략을 다룹니다.

1단계: 이미지 정리 (가장 안전)
# dangling 이미지만 삭제 (가장 안전)
docker image prune -f
# 72시간 이상 된 미사용 이미지 삭제 (필터 활용)
docker image prune -a -f --filter "until=72h"
이미지는 컨테이너가 삭제된 뒤에도 남는 캐시 역할을 합니다. 정리해도 필요하면 다시 pull할 수 있어 위험도가 낮습니다.
2단계: 중지된 컨테이너 정리
# 중지된 컨테이너 목록 확인
docker ps -a --filter status=exited
# 중지된 컨테이너 모두 삭제
docker container prune -f
실행 중인 컨테이너는 건드리지 않습니다. 중지된 컨테이너의 로그와 파일시스템 레이어만 삭제됩니다.
3단계: 사용하지 않는 볼륨 정리 (신중하게)
# 어떤 컨테이너에도 연결되지 않은 볼륨 목록 확인 (먼저 확인!)
docker volume ls -f dangling=true
# 볼륨 이름과 용도를 파악한 뒤 삭제 결정
볼륨 정리는 가장 위험한 단계입니다. 데이터베이스 볼륨, 업로드 파일 볼륨이 포함될 수 있습니다. 반드시 docker volume ls -f dangling=true로 목록을 확인하고, 용도를 파악한 뒤 삭제하세요.
4단계: 빌드 캐시 정리
# 빌드 캐시만 삭제 (이미지/컨테이너/볼륨은 건드리지 않음)
docker builder prune -f
# 24시간 이상 된 빌드 캐시만 삭제
docker builder prune --filter "until=24h" -f
한 번에 정리할 때 — system prune
--volumes 플래그는 명시적으로 지정해야만 볼륨을 삭제합니다. 프로덕션 서버나 개발 DB 볼륨이 있는 환경에서는 절대 -a --volumes를 무심코 실행하지 마세요.
정리 단계별 위험도 요약
| 단계 | 명령어 | 위험도 | 복구 가능 여부 |
|---|---|---|---|
| 이미지 | docker image prune | 낮음 | 가능 (재pull) |
| 이미지 전체 | docker image prune -a | 낮음 | 가능 (재pull) |
| 컨테이너 | docker container prune | 낮음 | 불가 (로그 손실 가능) |
| 볼륨 | docker volume prune | 높음 | 불가 (데이터 영구 삭제) |
| 전체 | docker system prune -a --volumes | 매우 높음 | 불가 |
실습: 이미지 태그 전략 — latest 금지, immutable tag 설계
태그 전략이 없으면 롤백이 불가능해집니다. 새 버전이 배포된 뒤 latest만 있다면 이전 버전을 찾을 방법이 없습니다.
latest 태그의 문제
# CI에서 매 빌드마다 latest로 push하는 잘못된 패턴
docker build -t myapp:latest .
docker push myapp:latest
# 문제: 오늘의 latest와 어제의 latest는 다른 이미지
# docker pull myapp:latest ← 항상 가장 최신 이미지를 가져옴
# 특정 시점으로 롤백하려면 어떤 이미지인지 알 수가 없음
git SHA + 날짜 조합 태그 — immutable tag
# git SHA 추출 (단축 7자리)
GIT_SHA=$(git rev-parse --short HEAD)
# 날짜 (YYYYMMDD 형식)
BUILD_DATE=$(date +%Y%m%d)
# 이미지 태그 조합
IMAGE_TAG="${BUILD_DATE}-${GIT_SHA}"
# 빌드 및 태그
docker build -t myapp:${IMAGE_TAG} .
# 예: myapp:20240510-a3f7c91
# 레지스트리 push
docker push myapp:${IMAGE_TAG}
# 참고용으로 latest도 함께 push (운영에서는 SHA 태그만 사용)
docker tag myapp:${IMAGE_TAG} myapp:latest
docker push myapp:latest
latest는 "현재 stable" 참조용으로만 유지하고, 실제 배포와 롤백은 반드시 20240510-a3f7c91처럼 고정된 태그로 합니다.
태그 전략 비교
# 나쁜 패턴 — 무엇이 배포됐는지 알 수 없음
myapp:latest
# 좋은 패턴 — 언제, 어떤 커밋인지 명확
myapp:20240510-a3f7c91
# 더 구체적인 패턴 — 브랜치까지 포함
myapp:main-20240510-a3f7c91
# 시맨틱 버저닝 + SHA 조합
myapp:v2.3.1-a3f7c91
태그로 롤백하기
# 배포된 버전 확인 (태그 목록)
docker images myapp --format "table {{.Tag}}\t{{.CreatedAt}}\t{{.ID}}"
# 특정 시점으로 롤백
docker run -d --name myapp myapp:20240508-b9e2d14
# 또는 레지스트리에서 이전 태그 pull
docker pull myapp:20240508-b9e2d14
CI cron 자동 정리 — 이미지가 쌓이지 않는 파이프라인 만들기
이미지 정리를 수동으로 하면 결국 새벽 3시 경보가 옵니다. CI 서버는 매 빌드마다 이미지를 생성하고, 아무도 정리하지 않으면 디스크는 선형으로 증가합니다. 자동화된 정리 정책이 있어야 이 문제를 예방할 수 있습니다. 이 ConceptBlock에서는 GitHub Actions, Jenkins 등 CI 파이프라인과 시스템 cron에서 이미지 자동 정리를 설정하는 방법을 다룹니다.

--filter until 플래그로 안전하게 정리
docker image prune -a -f는 모든 미사용 이미지를 삭제합니다. --filter "until=72h"를 추가하면 72시간 이내에 생성된 이미지는 보존하고 그보다 오래된 이미지만 삭제합니다.
# 72시간 이상 된 미사용 이미지 삭제
docker image prune -a -f --filter "until=72h"
# 24시간 이상 된 dangling 이미지 삭제
docker image prune -f --filter "until=24h"
# 라벨 기준 필터링 — 특정 프로젝트 이미지만 정리
docker image prune -a -f --filter "label=project=myapp"
GitHub Actions에서 자동 정리
# .github/workflows/cleanup.yml
name: Docker Image Cleanup
on:
schedule:
- cron: '0 2 * * *' # 매일 새벽 2시 실행
workflow_dispatch: # 수동 실행도 허용
jobs:
cleanup:
runs-on: self-hosted # CI 서버 러너 (self-hosted)
steps:
- name: Remove unused images older than 72h
run: |
docker image prune -a -f --filter "until=72h"
docker builder prune -f --filter "until=24h"
- name: Show disk status after cleanup
run: docker system df
시스템 cron으로 자동 정리 (Linux 서버)
# crontab -e 로 추가
# 매일 새벽 3시에 72시간 이상 된 미사용 이미지 정리
0 3 * * * /usr/bin/docker image prune -a -f --filter "until=72h" >> /var/log/docker-cleanup.log 2>&1
# 매주 일요일 새벽 4시에 빌드 캐시 정리
0 4 * * 0 /usr/bin/docker builder prune -f >> /var/log/docker-cleanup.log 2>&1
Jenkins 파이프라인 마지막 단계에 정리 추가
// Jenkinsfile (선언형 파이프라인)
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'docker build -t myapp:${BUILD_DATE}-${GIT_COMMIT[0..6]} .'
}
}
stage('Push') {
steps {
sh 'docker push myapp:${BUILD_DATE}-${GIT_COMMIT[0..6]}'
}
}
}
post {
always {
// 빌드 완료 후 dangling 이미지 정리
sh 'docker image prune -f'
}
cleanup {
// 워크스페이스 정리
cleanWs()
}
}
}
post { always { } } 블록에 docker image prune -f를 넣으면 빌드 성공·실패에 관계없이 항상 dangling 이미지를 정리합니다.
실습: docker save / load로 이미지 아카이빙
인터넷이 차단된 폐쇄망 환경, 오프라인 납품, 이미지 백업이 필요할 때 docker save와 docker load를 사용합니다.
이미지를 tar 파일로 저장
# 단일 이미지 저장
docker save -o nginx-alpine.tar nginx:alpine
# 저장된 파일 확인
ls -lh nginx-alpine.tar
# -rw------- 1 user user 8.1M ... nginx-alpine.tar
# gzip으로 압축하여 크기 줄이기
docker save nginx:alpine | gzip > nginx-alpine.tar.gz
ls -lh nginx-alpine.tar.gz
# -rw-r--r-- 1 user user 3.2M ... nginx-alpine.tar.gz (약 60% 압축)
여러 이미지를 하나의 파일로 묶기
# nginx와 redis를 하나의 tar에 저장
docker save -o app-bundle.tar nginx:alpine redis:7-alpine
# gzip 압축까지
docker save nginx:alpine redis:7-alpine | gzip > app-bundle.tar.gz
# 파일 전송 (scp 예시)
scp app-bundle.tar.gz deploy@192.168.1.100:/tmp/
다른 호스트에서 이미지 복원
# tar 파일에서 이미지 로드
docker load -i nginx-alpine.tar
# 출력:
# Loaded image: nginx:alpine
# gzip 압축 파일 로드
docker load -i nginx-alpine.tar.gz
# 또는 파이프 사용
gunzip -c nginx-alpine.tar.gz | docker load
# 복원 확인
docker images nginx
# REPOSITORY TAG IMAGE ID CREATED SIZE
# nginx alpine c1afedef4846 2 weeks ago 41.4MB
이미지 무결성 검증 (폐쇄망 납품 시)
# 전송 전: 이미지 다이제스트(sha256) 기록
docker inspect nginx:alpine --format '{{.Id}}'
# sha256:c1afedef4846b6c6a93f62f4db7af...
# 전송 후 복원된 이미지의 다이제스트와 비교
docker inspect nginx:alpine --format '{{.Id}}'
# 동일한 sha256이면 전송 중 손상 없음
빌드 또는 pull 중 no space left on device 에러가 발생했습니다. CI 파이프라인이 멈춘 상태에서 빠르게 공간을 확보해야 합니다.
즉시 진단
# Docker 공간 사용 현황 파악
docker system df
# 호스트 디스크 전체 상태 확인
df -h /var/lib/docker
빠른 공간 확보 (순서대로)
# 1단계: dangling 이미지 삭제 (가장 안전, 즉시 실행)
docker image prune -f
# 2단계: 중지된 컨테이너 삭제
docker container prune -f
# 3단계: 빌드 캐시 삭제
docker builder prune -f
# 공간 확인
docker system df && df -h /var/lib/docker
빠른 효과가 필요할 때 (볼륨 제외)
Docker 미사용 리소스 긴급 정리
안전한 실행 조건: CI 서버 디스크 부족처럼 긴급 공간 확보가 필요하고 볼륨 삭제가 포함되지 않는 경우에만 실행합니다.
실행 전 반드시 확인
- docker system df로 회수 가능 공간을 확인했다
- 실행 중인 서비스에 필요한 이미지가 영향을 받지 않는지 확인했다
- 볼륨 삭제가 포함되지 않는 명령임을 확인했다
docker system prune -a -f위 항목을 모두 확인한 후 복사할 수 있습니다
이미지, 컨테이너, 네트워크, 빌드 캐시를 한 번에 삭제합니다. 볼륨은 건드리지 않으므로 --volumes를 붙이지 않으면 데이터는 안전합니다.
근본 원인 해결 — 예방 정리 설정
# crontab -e 에 추가 (매일 새벽 3시)
0 3 * * * /usr/bin/docker image prune -a -f --filter "until=72h"
이 에러가 다시 발생하지 않도록 CI 서버에 정기 정리 cron을 반드시 추가하세요.
증상
로컬에서 태그를 붙이고 push했는데, 레지스트리에서 해당 이미지를 찾을 수 없습니다.
docker tag myapp:latest myapp:v1.0.0
docker push myapp:v1.0.0
# Using default tag: latest
# The push refers to repository [docker.io/library/myapp]
# denied: requested access to the resource is denied
원인 진단
# 현재 이미지 태그 확인
docker images | grep myapp
# myapp v1.0.0 abc123 2 min ago 512MB
# → 레지스트리 prefix 없이 로컬 이름만 있음
# docker.io/library/ 는 Docker Hub 공식 이미지 경로
# 개인/조직 이미지는 docker.io/<username>/<image> 형식이어야 함
해결
# 올바른 태그 형식으로 다시 태깅
# Docker Hub: docker.io/<username>/<image>:<tag>
docker tag myapp:v1.0.0 myusername/myapp:v1.0.0
docker push myusername/myapp:v1.0.0
# GHCR: ghcr.io/<org>/<image>:<tag>
docker tag myapp:v1.0.0 ghcr.io/myorg/myapp:v1.0.0
docker push ghcr.io/myorg/myapp:v1.0.0
# ECR: <account>.dkr.ecr.<region>.amazonaws.com/<repo>:<tag>
docker tag myapp:v1.0.0 123456789.dkr.ecr.ap-northeast-2.amazonaws.com/myapp:v1.0.0
docker push 123456789.dkr.ecr.ap-northeast-2.amazonaws.com/myapp:v1.0.0
증상
오프라인 환경에 이미지를 전달하려고 docker save로 내보내고 docker load로 불러왔는데, 이미지 이름이 사라집니다.
# 내보내기
docker save abc123 > myapp.tar # 이미지 ID로 저장
# 다른 서버에서 불러오기
docker load < myapp.tar
# Loaded image ID: sha256:abc123...
docker images
# REPOSITORY TAG IMAGE ID
# <none> <none> abc123... ← 이름이 없음
원인
docker save에 이미지 ID만 지정하면 이름/태그 정보가 포함되지 않습니다. 이름과 태그는 이미지 메타데이터에 저장되는데, ID만으로 저장하면 그 정보가 빠집니다.
해결
# 올바른 방법: 이미지 이름:태그 형식으로 저장
docker save myapp:v1.0.0 > myapp-v1.tar
# 불러오기
docker load < myapp-v1.tar
# Loaded image: myapp:v1.0.0
# 여러 이미지를 한 파일에 저장
docker save myapp:v1.0.0 myapp:v1.1.0 > myapp-versions.tar
# 또는 gzip 압축
docker save myapp:v1.0.0 | gzip > myapp-v1.tar.gz
docker load < myapp-v1.tar.gz
CI/CD 파이프라인에서 이미지 정리 정책 설정하는 실무
인프라 엔지니어나 DevOps 엔지니어로 일하면 "CI 서버 디스크 관리"가 반복적인 운영 업무가 됩니다. 빌드가 빠를수록 이미지는 더 빨리 쌓이고, 팀이 커질수록 문제가 심해집니다.
실무에서 적용하는 이미지 운영 정책의 핵심은 세 가지입니다.
첫째, 태그 규약을 팀 전체가 따르도록 Makefile이나 CI 스크립트에 고정합니다. make build를 실행하면 자동으로 $(date +%Y%m%d)-$(git rev-parse --short HEAD) 형식의 태그가 붙도록 합니다. 개발자가 수동으로 태그를 결정하면 규칙이 흐트러집니다.
둘째, 정리 cron은 CI 서버 초기 세팅 시 반드시 포함합니다. 나중에 추가하려면 이미 터진 디스크 사고를 수습하면서 해야 합니다. ansible-playbook이나 terraform으로 서버를 프로비저닝할 때 crontab 설정을 같이 넣으면 빠뜨리지 않습니다.
셋째, 레지스트리 retention policy를 함께 설정합니다. ECR(AWS), GCR(GCP), GHCR(GitHub)은 모두 이미지 보관 정책을 지원합니다. "최근 10개만 보관", "30일 이상 된 이미지 삭제" 같은 정책을 레지스트리에서도 적용하면 CI 서버와 레지스트리 양쪽에서 불필요한 이미지가 쌓이는 것을 막을 수 있습니다.
# AWS ECR 예시 — 30일 이상 된 이미지 자동 삭제 정책
aws ecr put-lifecycle-policy \
--repository-name myapp \
--lifecycle-policy-text '{
"rules": [{
"rulePriority": 1,
"description": "Keep last 10 images",
"selection": {
"tagStatus": "any",
"countType": "imageCountMoreThan",
"countNumber": 10
},
"action": { "type": "expire" }
}]
}'
이미지 운영 정책이 없으면 인프라 엔지니어는 주기적으로 수동 정리를 해야 하고, 결국 어느 날 새벽에 파이프라인 장애로 불려 나오게 됩니다. 처음 설정할 때 10분을 쓰면 그 이후의 새벽 비상 대응을 막을 수 있습니다.
다음 모듈에서는 컨테이너의 휘발성을 다루고, Named Volume과 Bind Mount로 데이터가 컨테이너 삭제 후에도 유지되도록 설계합니다.