화. 8월 12th, 2025

G: 안녕하세요, 개발자 여러분! 🚀 오늘은 클라우드 시대의 필수 도구이자 개발 생산성을 극대화하는 Docker에 대해 깊이 파고들어 볼 시간입니다. 특히, Docker를 자유자재로 다루기 위한 핵심 명령어들을 초보자의 눈높이부터 실무에서 활용하는 팁까지, 이 한 포스팅으로 완벽하게 마스터할 수 있도록 도와드리겠습니다!

💡 왜 Docker를 배워야 할까요?

Docker는 애플리케이션을 컨테이너(Container)라는 격리된 환경에 패키징하여 개발, 배포, 실행을 훨씬 쉽고 일관되게 만들어주는 플랫폼입니다. “내 컴퓨터에서는 되는데, 서버에서는 안 돼요!” 라는 말, 이제 Docker와 함께라면 옛말이 됩니다. ✨

이 글을 통해 여러분은 다음과 같은 질문에 대한 답을 얻게 될 것입니다:

  • Docker의 기본 개념은 무엇인가요?
  • 주요 Docker 명령어는 어떻게 사용하나요?
  • 실무에서 유용하게 쓸 수 있는 팁과 베스트 프랙티스는 무엇인가요?

자, 그럼 Docker의 세계로 함께 떠나볼까요? 🐳


📦 1. Docker, 이게 뭔가요? 핵심 개념 잡기

본격적인 명령어 탐험에 앞서, Docker의 몇 가지 핵심 개념을 명확히 이해하는 것이 중요합니다.

  • 이미지 (Image):

    • 애플리케이션 실행에 필요한 모든 것(코드, 런타임, 시스템 도구, 라이브러리 등)을 포함하는 읽기 전용 템플릿입니다. 📦
    • Java.jar 파일이나 Pythonrequirements.txt와 비슷하지만, 운영체제 환경까지 포함하는 ‘완벽한 스냅샷’이라고 생각하면 됩니다.
    • 예시: ubuntu, nginx, mysql 등의 기본 이미지.
  • 컨테이너 (Container):

    • 이미지의 실행 가능한 인스턴스입니다. 🚀
    • 이미지를 기반으로 격리된 환경에서 애플리케이션이 실제로 동작하는 공간입니다.
    • 가상머신(VM)과 달리, 호스트 OS의 커널을 공유하여 훨씬 가볍고 빠르게 동작합니다.
  • 레지스트리 (Registry):

    • Docker 이미지를 저장하고 공유하는 공간입니다. ☁️
    • 가장 유명한 레지스트리는 Docker Hub입니다. 마치 GitHub처럼 이미지를 업로드(push)하고 다운로드(pull)할 수 있습니다.
  • 볼륨 (Volume):

    • 컨테이너 내에서 생성되거나 사용되는 데이터를 영속적으로 저장하기 위한 메커니즘입니다. 💾
    • 컨테이너가 삭제되어도 데이터는 보존되어야 할 때 사용합니다. (예: 데이터베이스 파일)
  • 네트워크 (Network):

    • 컨테이너 간 또는 컨테이너와 외부 세계 간의 통신을 가능하게 합니다. 🌐
    • 기본적으로 여러 네트워크 유형이 있으며, 필요에 따라 사용자 정의 네트워크를 생성할 수 있습니다.

🛠️ 2. 본격! Docker 핵심 명령어 완전 정복

이제 각 개념을 실제 명령어로 어떻게 다루는지 살펴보겠습니다. 각 명령어마다 사용 예시와 함께 상세히 설명해 드릴게요.

I. 설치 및 기본 확인 명령어

Docker가 제대로 설치되었는지 확인하는 가장 기본적인 명령어입니다.

  1. docker version: 설치된 Docker 클라이언트 및 서버(Daemon)의 버전을 확인합니다.

    docker version
    # 예시 출력:
    Client: Docker Engine - Community
     Version:           24.0.5
     ...
    Server: Docker Engine - Community
     Engine:
      Version:          24.0.5
      ...
  2. docker info: Docker 시스템 전반에 대한 자세한 정보를 보여줍니다. 컨테이너, 이미지, 스토리지 드라이버 등의 정보를 확인할 수 있습니다.

    docker info
    # 예시 출력:
    Client:
     Context:    default
     Debug Mode: false
    Server:
     Containers: 10
     Running: 5
     Paused: 0
     Stopped: 5
     Images: 25
     Server Version: 24.0.5
     Storage Driver: overlay2
     ...

II. 이미지 관리 (Image Management)

Docker의 기본이 되는 이미지를 다루는 명령어들입니다.

  1. docker pull [이미지_이름]:[태그]: Docker Hub 등 레지스트리에서 이미지를 다운로드합니다. 태그를 생략하면 latest 태그가 기본으로 적용됩니다.

    docker pull ubuntu:22.04  # Ubuntu 22.04 이미지 다운로드
    docker pull nginx         # 최신 Nginx 이미지 다운로드 (latest 태그)
  2. docker images / docker image ls: 로컬 시스템에 저장된 모든 Docker 이미지를 목록으로 보여줍니다.

    docker images          # 모든 이미지 목록 보기
    docker images -a       # 모든 이미지 (숨겨진 이미지 포함) 목록 보기
    # 예시 출력:
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    ubuntu              22.04               2012ef322588        2 weeks ago         77.8MB
    nginx               latest              b8d4847e06a3        3 weeks ago         187MB
  3. docker build -t [이미지_이름]:[태그] [Dockerfile_경로]: Dockerfile을 사용하여 새로운 Docker 이미지를 생성합니다. -t는 태그를 지정하는 옵션입니다. .은 현재 디렉토리에서 Dockerfile을 찾으라는 의미입니다.

    # 현재 디렉토리의 Dockerfile로 'my-web-app:1.0' 이미지 생성
    docker build -t my-web-app:1.0 .
    • Dockerfile 예시:
      # Dockerfile
      FROM node:18-alpine
      WORKDIR /app
      COPY package*.json ./
      RUN npm install
      COPY . .
      EXPOSE 3000
      CMD ["npm", "start"]
  4. docker rmi [이미지_ID 또는 이미지_이름]:[태그]: 로컬에 있는 하나 이상의 이미지를 삭제합니다. 컨테이너가 해당 이미지를 사용 중이라면 삭제되지 않습니다.

    docker rmi ubuntu:22.04       # 특정 태그 이미지 삭제
    docker rmi b8d4847e06a3     # 이미지 ID로 삭제
    docker rmi -f my-web-app:1.0  # 강제로 삭제 (사용 중인 컨테이너가 있어도 삭제 시도)

    ⚠️ 주의: 이미지를 사용하는 컨테이너가 있다면 삭제되지 않거나 -f 옵션이 필요합니다.

  5. docker save -o [저장_파일명.tar] [이미지_이름]:[태그]: 이미지를 .tar 파일로 내보내어 다른 시스템으로 쉽게 옮길 수 있도록 합니다.

    docker save -o my_nginx_image.tar nginx:latest
  6. docker load -i [불러올_파일명.tar]: docker save로 내보낸 .tar 파일을 다시 Docker 이미지로 불러옵니다.

    docker load -i my_nginx_image.tar

III. 컨테이너 관리 (Container Management)

Docker의 핵심인 컨테이너를 생성, 실행, 관리하는 명령어들입니다.

  1. docker run [옵션] [이미지_이름]:[태그] [명령어]: 새로운 컨테이너를 생성하고 실행합니다. 가장 많이 사용되는 명령어입니다.

    • 주요 옵션:
      • -d (detached): 컨테이너를 백그라운드에서 실행합니다. 터미널을 점유하지 않습니다.
      • -p [호스트포트]:[컨테이너포트] (publish): 호스트 포트를 컨테이너 포트에 연결하여 외부에서 접근할 수 있도록 합니다.
      • --name [이름] : 컨테이너에 알아보기 쉬운 이름을 부여합니다. (생략 시 무작위 이름 할당)
      • -v [호스트경로]:[컨테이너경로] (volume): 호스트의 디렉토리나 파일을 컨테이너 내부에 마운트하여 데이터를 영속적으로 저장합니다.
      • -it (interactive, tty): 컨테이너와 상호작용 가능한 터미널을 연결합니다. (예: 컨테이너 내부로 bash 쉘 접속)
      • --rm: 컨테이너 종료 시 자동으로 삭제합니다. (임시 컨테이너에 유용)
      • --network [네트워크_이름]: 특정 네트워크에 컨테이너를 연결합니다.
    # 1. Nginx 웹 서버 컨테이너를 백그라운드로 실행하고, 호스트의 80포트를 컨테이너의 80포트에 연결
    docker run -d -p 80:80 --name my-nginx nginx:latest
    
    # 2. Ubuntu 컨테이너를 대화형 모드로 실행하고 bash 쉘 접속
    docker run -it ubuntu:latest bash
    
    # 3. 로컬 디렉토리(/home/user/my_data)를 컨테이너 내부(/app/data)에 마운트하여 웹 앱 실행
    docker run -d -p 3000:3000 --name my-data-app -v /home/user/my_data:/app/data my-web-app:1.0
    
    # 4. 일회성 테스트를 위한 컨테이너 실행 (종료 시 자동 삭제)
    docker run --rm hello-world
  2. docker ps: 현재 실행 중인 모든 컨테이너 목록을 보여줍니다.

    docker ps        # 실행 중인 컨테이너 목록
    docker ps -a     # 모든 컨테이너 목록 (실행 중이거나 종료된 컨테이너 모두)
    # 예시 출력:
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                   NAMES
    a1b2c3d4e5f6        nginx:latest        "nginx -g 'daemon of…"   10 minutes ago      Up 10 minutes       0.0.0.0:80->80/tcp      my-nginx
  3. docker start [컨테이너_ID 또는 이름]: 중지된 컨테이너를 다시 시작합니다.

    docker start my-nginx
    docker start a1b2c3d4e5f6
  4. docker stop [컨테이너_ID 또는 이름]: 실행 중인 컨테이너를 정상적으로 종료합니다. (SIGTERM 시그널 전송)

    docker stop my-nginx
  5. docker restart [컨테이너_ID 또는 이름]: 컨테이너를 중지했다가 다시 시작합니다.

    docker restart my-nginx
  6. docker rm [컨테이너_ID 또는 이름]: 하나 이상의 컨테이너를 삭제합니다. 실행 중인 컨테이너는 삭제되지 않습니다.

    docker rm my-nginx         # 특정 컨테이너 삭제
    docker rm -f my-nginx      # 실행 중인 컨테이너 강제 삭제
    docker rm $(docker ps -aq) # 모든 컨테이너 삭제 (실행 중인 컨테이너는 오류 발생)

    ⚠️ 주의: 데이터 볼륨이 연결되어 있다면 docker rm -v 옵션을 사용하여 볼륨도 함께 삭제할 수 있습니다.

  7. docker exec -it [컨테이너_ID 또는 이름] [명령어]: 실행 중인 컨테이너 내부에서 명령어를 실행합니다. 컨테이너 내부로 접속할 때 주로 사용됩니다.

    # my-nginx 컨테이너 내부로 bash 쉘 접속
    docker exec -it my-nginx bash
    
    # my-app 컨테이너 내부에서 ls /app 명령어 실행
    docker exec my-app ls /app
  8. docker logs [컨테이너_ID 또는 이름]: 컨테이너의 표준 출력(stdout) 및 표준 에러(stderr) 로그를 확인합니다.

    docker logs my-nginx      # 모든 로그 출력
    docker logs -f my-nginx   # 실시간으로 로그를 계속해서 출력 (follow)
    docker logs --tail 100 my-nginx # 마지막 100줄만 출력
  9. docker cp [원본_경로] [대상_경로]: 호스트와 컨테이너 간에 파일을 복사합니다.

    • 호스트 -> 컨테이너: docker cp ./index.html my-nginx:/usr/share/nginx/html/index.html
    • 컨테이너 -> 호스트: docker cp my-nginx:/var/log/nginx/access.log ./access.log
  10. docker inspect [컨테이너_ID 또는 이름]: 컨테이너의 상세 정보를 JSON 형식으로 출력합니다. IP 주소, 볼륨 마운트 정보 등을 확인할 때 유용합니다.

    docker inspect my-nginx
    docker inspect --format='{{.NetworkSettings.IPAddress}}' my-nginx # IP 주소만 추출
  11. docker attach [컨테이너_ID 또는 이름]: 실행 중인 컨테이너의 STDIN, STDOUT, STDERR에 다시 연결합니다. -d 옵션 없이 실행된 컨테이너의 출력을 보고 싶을 때 유용합니다.

    docker attach my-interactive-container

    ⚠️ 주의: -d로 실행된 컨테이너에 attach하면 Ctrl+C로 종료 시 컨테이너도 같이 종료될 수 있으니 유의하세요. 빠져나올 때는 Ctrl+P + Ctrl+Q를 사용하세요.

IV. 볼륨 관리 (Volume Management)

컨테이너의 데이터를 영속적으로 유지하기 위한 볼륨을 다룹니다.

  1. docker volume create [볼륨_이름]: 이름이 지정된 볼륨을 생성합니다.

    docker volume create my-database-data
  2. docker volume ls: 로컬에 생성된 모든 볼륨 목록을 보여줍니다.

    docker volume ls
  3. docker volume inspect [볼륨_이름]: 특정 볼륨의 상세 정보를 확인합니다.

    docker volume inspect my-database-data
  4. docker volume rm [볼륨_이름]: 특정 볼륨을 삭제합니다. 사용 중인 볼륨은 삭제되지 않습니다.

    docker volume rm my-database-data
  5. docker run -v [볼륨_이름]:[컨테이너_경로] [이미지_이름]: 컨테이너 실행 시 미리 생성한 볼륨을 연결합니다.

    docker run -d --name my-db -v my-database-data:/var/lib/mysql mysql:8.0

V. 네트워크 관리 (Network Management)

컨테이너 간의 통신을 제어하는 네트워크를 다룹니다.

  1. docker network create [네트워크_이름]: 사용자 정의 브릿지 네트워크를 생성합니다. (기본 bridge, host, none 외에 직접 생성)

    docker network create my-app-network
  2. docker network ls: 로컬에 생성된 모든 Docker 네트워크 목록을 보여줍니다.

    docker network ls
  3. docker network inspect [네트워크_이름]: 특정 네트워크의 상세 정보를 확인합니다. 연결된 컨테이너 정보도 볼 수 있습니다.

    docker network inspect my-app-network
  4. docker network rm [네트워크_이름]: 특정 네트워크를 삭제합니다.

    docker network rm my-app-network
  5. docker run --network [네트워크_이름] [이미지_이름]: 컨테이너를 특정 네트워크에 연결하여 실행합니다. 동일 네트워크에 있는 컨테이너는 컨테이너 이름으로 서로 통신할 수 있습니다.

    # 1. 백엔드 서버 컨테이너를 'my-app-network'에 연결
    docker run -d --name backend-server --network my-app-network my-backend-image
    
    # 2. 프론트엔드 서버 컨테이너를 'my-app-network'에 연결 (백엔드와 통신 가능)
    docker run -d -p 80:80 --name frontend-server --network my-app-network my-frontend-image
    • frontend-server에서 backend-serverhttp://backend-server:port와 같이 이름으로 통신 가능! 🌐

VI. 시스템 관리 및 정리 (System Management & Cleanup)

사용하지 않는 자원들을 정리하여 디스크 공간을 확보하는 명령어입니다.

  1. docker system prune: 사용하지 않는(dangling) 모든 컨테이너, 이미지(캐시 이미지 포함), 볼륨, 네트워크를 삭제합니다. 디스크 공간 확보에 매우 유용합니다. 🗑️

    docker system prune          # 종료된 컨테이너, 사용되지 않는 이미지, 네트워크 삭제
    docker system prune -a       # 위 항목 + 사용되지 않는 모든 이미지 (캐시 포함) 삭제
    docker system prune --volumes # 위 항목 + 사용되지 않는 볼륨도 함께 삭제 (가장 강력한 정리)

    ⚠️ 주의: 이 명령어는 삭제할 항목을 물어보므로, 잘 확인하고 실행하세요! 특히 --volumes는 중요한 데이터를 날릴 수도 있습니다.

  2. docker stats: 실행 중인 컨테이너들의 CPU, 메모리, 네트워크 사용량 등 실시간 리소스 사용 현황을 보여줍니다. 📈

    docker stats

VII. 기타 유용한 명령어

  1. docker login / docker logout: Docker Hub와 같은 레지스트리에 로그인/로그아웃합니다. 이미지를 push하기 위해 필요합니다.

    docker login
    # username, password 입력 프롬프트가 나옵니다.
    
    docker logout
  2. docker push [이미지_이름]:[태그]: 로컬에 있는 이미지를 Docker Hub와 같은 레지스트리에 업로드합니다.

    docker push myusername/my-web-app:1.0
    • : docker build로 생성한 이미지에 docker tag로 레지스트리 이름을 붙여야 push할 수 있습니다. docker tag my-web-app:1.0 myusername/my-web-app:1.0

💡 3. Docker 명령어 활용 팁 & 베스트 프랙티스

이제 배운 명령어들을 더 효율적으로 사용하는 팁들을 알려드릴게요.

  • --help를 생활화하세요!: 어떤 명령어든 docker [명령어] --help를 입력하면 자세한 옵션과 사용법을 확인할 수 있습니다. docker run --help를 입력해보세요!
  • 컨테이너 이름 지정은 필수! (--name): docker run--name 옵션으로 의미 있는 이름을 지정하면 docker ps, docker stop, docker exec 등 모든 명령어에서 컨테이너 ID 대신 이름을 사용하여 훨씬 편리하고 가독성이 높아집니다.
  • 데이터는 볼륨으로!: 컨테이너가 삭제되어도 데이터는 보존되어야 한다면 반드시 볼륨(named volume 또는 bind mount)을 사용하세요. 컨테이너 내부의 데이터는 컨테이너와 생명 주기를 같이 합니다.
  • docker-compose 활용: 여러 개의 컨테이너가 함께 동작하는 복잡한 애플리케이션의 경우, docker-compose.yml 파일을 사용하여 한 번의 명령으로 전체 애플리케이션 스택을 쉽게 관리할 수 있습니다. (이 글의 범위를 넘어서지만, 실무 필수 스킬입니다!)
  • 정기적인 정리 (docker system prune): 개발/테스트 과정에서 불필요하게 생성된 이미지나 컨테이너 잔여물이 디스크 공간을 많이 차지할 수 있습니다. 주기적으로 docker system prune을 실행하여 깔끔하게 관리하세요. (특히 --volumes 옵션 사용 시 주의!)
  • 공식 문서 활용: 가장 정확하고 최신 정보는 언제나 Docker 공식 문서에 있습니다. 모르는 것이 있다면 주저하지 말고 공식 문서를 찾아보는 습관을 들이세요. 📚

🎉 마무리하며

지금까지 Docker의 핵심 개념부터 이미지, 컨테이너, 볼륨, 네트워크 관리, 그리고 시스템 정리 명령어까지 모두 살펴보았습니다. 이 명령어들을 손에 익히고 자유자재로 활용할 수 있다면, 여러분은 이미 Docker 전문가의 길을 걷고 계신 겁니다! 🏆

Docker는 DevOps, 클라우드 환경에서 개발자의 필수 역량이 되어가고 있습니다. 오늘 배운 명령어들을 바탕으로 꾸준히 실습하고, 다양한 상황에 적용해보면서 여러분의 개발 역량을 한 단계 더 성장시키시길 바랍니다.

궁금한 점이 있다면 언제든지 댓글로 남겨주세요! Happy Dockering! 🐳✨

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다