Pentest Playbook

Docker 기초

Docker 컨테이너와 docker-compose를 다루기 위한 기본 명령어

1. 기본 명령어

# 컨테이너 실행
docker run -it ubuntu:22.04 /bin/bash

# 실행 중인 컨테이너 확인
docker ps 
docker ps -a # 모든 컨테이너 확인

# 이미지 목록
docker images
docker images -a # 모든 이미지 확인

# 특정 컨테이너 로그 확인
docker logs {container_ID}
docker logs -f {Container_ID} # 실시간 로그 확인

# 특정 컨테이너 시스템 접근
docker exec -it {container_ID/NAME} /bin/bash #컨테이너 OS환경에 따라 실행되는 Shell 선택

2. docker-compose

docker-compose.yml 파일이 위치한 디렉터리에서 명령어 입력

2.1. 기본 명령어

명령어 설명
docker-compose up 컨테이너 생성 및 시작
docker-compose up -d 백그라운드(detach) 실행
docker-compose down 컨테이너 중지 및 제거
docker-compose start 중지된 컨테이너 시작
docker-compose stop 컨테이너 중지 (제거 X)
docker-compose restart 컨테이너 재시작

2.2. 빌드/이미지

명령어 설명
docker-compose build 이미지 빌드
docker-compose build --no-cache 캐시 없이 빌드
docker-compose pull 이미지 pull
docker-compose up --build 빌드 후 실행
docker-compose restart [컨테이너명] 특정 컨테이너만 재시작

2.3. 컨테이너 상태 확인

명령어 설명
docker-compose ps 실행 중인 컨테이너 목록
docker-compose logs 전체 로그 출력
docker-compose logs -f 로그 실시간 스트리밍
docker-compose logs [컨테이너명] 특정 서비스 로그
docker-compose top 프로세스 목록

2.4. 실행/접속

명령어 설명
docker-compose exec [컨테이너명] bash 실행 중인 컨테이너에 접속
docker-compose run [컨테이너명] bash 새 컨테이너 실행 후 접속
docker-compose exec [컨테이너명] [명령어] 컨테이너 내 명령 실행

2.5. 정리 옵션

명령어 설명
docker-compose down -v 컨테이너 + 볼륨 제거
docker-compose down --rmi all 컨테이너 + 이미지 제거
docker-compose rm [컨테이너명] 중지된 컨테이너 제거
docker-compose rm -f [컨테이너명] 실행중인 컨테이너 강제 제거

3. Docker Compose

여러 컨테이너를 정의하고 관리할 수 있는 docker-compose.yml 파일의 기본 내용

version: '3.8'
services:
  web:
    image: nginx
    ports:
      - "80:80"
  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: secret

4. 기타

4.1. 도커 이미지 조회/삭제 시, 판단

도커를 올려서 사용하다보면, build를 많이 사용하게되면 이전 이미지가 재빌드되면서 태그를 덮어쓰게 되고 image가 계속해서 쌓이게 된다. 이때 이미지들은 <none>이라는 이름을 가지고 생성되게 되는데, 현재 사용중인 컨테이너에 참조되는 경우도 있고 참조되지 않는 경우도 있다.
데이터가 남아있다면, 서비스의 용량을 차지하게 될 수 있어 주기적으로 삭제해야 한다.

Linux 환경이라면 crontab을 이용해서 주기적으로 정리되도록 설정할 수 있다.

crontab -e

# 매주 일요일 새벽 3시에 dangling 이미지 자동 정리
0 3 * * 0 docker image prune -f >> /var/log/docker-prune.log 2>&1

그 외에 빌드 직후 삭제할 수도 있지만, docker를 많이 재빌드하는 하는 경우가 있다면 작업완료 후 한 번만 정리해줘도 된다. - 참조되는 컨테이너를 제외한 <none> 이미지를 전부 제거하는 코드

#!/bin/bash

# <none> 이미지 ID 배열로 수집
mapfile -t NONE_IDS < <(docker images -a | awk '$1 == "<none>" {print $3}')

if [ ${#NONE_IDS[@]} -eq 0 ]; then
    echo "삭제할 <none> 이미지가 없습니다."
    exit 0
fi

# 수집된 ID 출력
echo "=== 삭제 대상 <none> 이미지 ==="
for ID in "${NONE_IDS[@]}"; do
    echo "  - $ID"
done
echo ""

# 삭제 실행
echo "=== 삭제 시작 ==="
FAIL=0
for ID in "${NONE_IDS[@]}"; do
    if docker rmi "$ID" 2>/dev/null; then
        echo "[OK]   $ID"
    else
        # 해당 IMAGE ID를 참조 중인 컨테이너 목록
        CONTAINERS=$(docker ps -a --filter "ancestor=$ID" --format "{{.Names}}({{.Status}})" | tr '\n' ' ')
        if [ -n "$CONTAINERS" ]; then
            echo "[SKIP] $ID → 참조 컨테이너: $CONTAINERS"
        else
            echo "[SKIP] $ID → 참조 컨테이너 없음 (중간 레이어 또는 다른 이미지 의존)"
        fi
        FAIL=$((FAIL + 1))
    fi
done

echo ""
echo "완료: 총 ${#NONE_IDS[@]}개 중 $((${#NONE_IDS[@]} - FAIL))개 삭제, ${FAIL}개 스킵"

4.2. 도커 Clean 작업 코드

현재 상태에서의 실행중인 컨테이너, 이미지, 저장된 볼륨, 캐시 · 네트워크 · dangling 등 전체 제거하는 작업

#!/bin/bash

# ============================================================
#  docker_clean.sh
#  docker-compose 기반 환경 전체 정리 스크립트
#  실행 순서: 컨테이너 → 이미지 → 볼륨 → 시스템 전체
# ============================================================

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

STEP=0
TOTAL=4

step() {
    STEP=$((STEP + 1))
    echo ""
    echo -e "${CYAN}[$STEP/$TOTAL] $1${NC}"
    echo "------------------------------------------------------------"
}

ok()   { echo -e "${GREEN}[OK]${NC}   $1"; }
skip() { echo -e "${YELLOW}[SKIP]${NC} $1"; }
fail() { echo -e "${RED}[FAIL]${NC} $1"; }

echo "============================================================"
echo "  Docker 전체 정리 시작"
echo "  $(date '+%Y-%m-%d %H:%M:%S')"
echo "============================================================"

# ------------------------------------------------------------
# STEP 1. 컨테이너 강제 제거
# ------------------------------------------------------------
step "컨테이너 강제 제거 (docker rm -f)"

mapfile -t CONTAINERS < <(docker ps -aq)

if [ ${#CONTAINERS[@]} -eq 0 ]; then
    skip "제거할 컨테이너 없음"
else
    for ID in "${CONTAINERS[@]}"; do
        NAME=$(docker inspect --format '{{.Name}}' "$ID" 2>/dev/null | sed 's/\///')
        if docker rm -f "$ID" > /dev/null 2>&1; then
            ok "컨테이너 제거: $NAME ($ID)"
        else
            fail "컨테이너 제거 실패: $NAME ($ID)"
        fi
    done
fi

# ------------------------------------------------------------
# STEP 2. 이미지 강제 제거
# ------------------------------------------------------------
step "이미지 강제 제거 (docker rmi -f)"

mapfile -t IMAGES < <(docker images -aq)

if [ ${#IMAGES[@]} -eq 0 ]; then
    skip "제거할 이미지 없음"
else
    # 중복 ID 제거
    mapfile -t IMAGES < <(printf '%s\n' "${IMAGES[@]}" | sort -u)
    for ID in "${IMAGES[@]}"; do
        TAG=$(docker inspect --format '{{index .RepoTags 0}}' "$ID" 2>/dev/null)
        TAG=${TAG:-"<none>"}
        if docker rmi -f "$ID" > /dev/null 2>&1; then
            ok "이미지 제거: $TAG ($ID)"
        else
            fail "이미지 제거 실패: $TAG ($ID)"
        fi
    done
fi

# ------------------------------------------------------------
# STEP 3. 볼륨 제거
# ------------------------------------------------------------
step "볼륨 제거 (docker volume rm)"

mapfile -t VOLUMES < <(docker volume ls -q)

if [ ${#VOLUMES[@]} -eq 0 ]; then
    skip "제거할 볼륨 없음"
else
    for VOL in "${VOLUMES[@]}"; do
        if docker volume rm "$VOL" > /dev/null 2>&1; then
            ok "볼륨 제거: $VOL"
        else
            fail "볼륨 제거 실패 (사용 중): $VOL"
        fi
    done
fi

# ------------------------------------------------------------
# STEP 4. 시스템 전체 정리
# ------------------------------------------------------------
step "시스템 전체 정리 (docker system prune -af --volumes)"

if docker system prune -af --volumes > /dev/null 2>&1; then
    ok "system prune 완료 (캐시/네트워크/dangling 전부 정리)"
else
    fail "system prune 실패"
fi

# ------------------------------------------------------------
# 최종 상태 출력
# ------------------------------------------------------------
echo ""
echo "============================================================"
echo "  정리 완료 - 현재 Docker 상태"
echo "============================================================"
echo ""
echo "[컨테이너]"
docker ps -a 2>/dev/null || echo "  없음"
echo ""
echo "[이미지]"
docker images -a 2>/dev/null || echo "  없음"
echo ""
echo "[볼륨]"
docker volume ls 2>/dev/null || echo "  없음"
echo ""
echo "[디스크 사용량]"
docker system df 2>/dev/null
echo ""
echo -e "${GREEN}완료: $(date '+%Y-%m-%d %H:%M:%S')${NC}"

만약 docker_clean.sh: line 2: $'\r': command not found와 같은 오류가 발생할 경우 \r\n인 Windows에서 편집했을 때 발생하는 CRLF 이슈이기 때문에 아래와 같이 해결하면 된다.

# sed로 \r 제거
sed -i 's/\r//' docker_clean.sh
ESC

💡 검색 팁

  • #T1572 - 태그로 검색
  • persistence - 키워드로 검색