화. 8월 12th, 2025

G: 안녕하세요, 개발자 여러분! 🚀 복잡한 개발 환경 설정과 배포의 늪에서 벗어나게 해주는 마법 같은 도구, 바로 ‘도커(Docker)’입니다. 도커를 사용하면 내 컴퓨터에서 완벽하게 작동하던 애플리케이션이 다른 컴퓨터에서는 ‘안돼요!’라고 외치는 불상사를 피할 수 있죠. 마치 모든 필요한 도구와 재료가 담긴 ‘조립식 주택’을 만들어 어디든 옮겨 지을 수 있는 것과 같습니다.

하지만 처음 도커를 접하면 수많은 명령어와 개념에 압도당하기 쉽습니다. “컨테이너는 뭐고, 이미지는 또 뭐야? 볼륨은 왜 필요해?” 같은 질문이 꼬리에 꼬리를 물죠. 🤔

걱정 마세요! 이 글은 도커를 실전에서 바로 활용할 수 있도록, 가장 핵심적인 명령어와 유용한 팁들을 ‘치트시트’ 형식으로 정리했습니다. 이 글 하나면 도커의 기본적인 사용법부터 실전 활용까지 마스터할 수 있을 거예요! 💪


🌐 1. Docker 시작하기: 이미지 & 컨테이너 관리의 기초

도커의 모든 것은 ‘이미지’와 ‘컨테이너’에서 시작합니다. 이미지는 애플리케이션 실행에 필요한 모든 것(코드, 런타임, 시스템 도구, 라이브러리 등)을 담은 ‘설계도’ 또는 ‘정지된 스냅샷’이고, 컨테이너는 이 이미지를 기반으로 ‘실행되는 인스턴스’라고 생각하면 됩니다.

📦 1.1 이미지 가져오기 (docker pull)

원하는 소프트웨어나 운영체제 이미지를 도커 허브(Docker Hub)와 같은 레지스트리에서 다운로드합니다.

  • 명령어: docker pull [이미지 이름]:[태그]
    • [태그]는 버전 또는 특정 빌드를 나타내며, 생략하면 latest 태그가 기본으로 사용됩니다.
  • 예시:
    • Nginx 웹 서버 이미지 가져오기: docker pull nginx 🌐
    • 우분투 20.04 이미지 가져오기: docker pull ubuntu:20.04 🐧

📋 1.2 이미지 목록 확인하기 (docker images)

내 로컬에 다운로드된 모든 이미지의 목록을 확인할 수 있습니다.

  • 명령어: docker images
  • 예시:
    docker images
    # 출력 예시:
    # REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
    # nginx         latest    f0a0a0a0a0a0   2 weeks ago    133MB
    # ubuntu        20.04     b1b1b1b1b1b1   3 months ago   73.9MB

🏃‍♂️ 1.3 컨테이너 실행하기 (docker run)

가장 중요하고 가장 많이 사용되는 명령어입니다! 이미지를 기반으로 새로운 컨테이너를 생성하고 실행합니다.

  • 명령어: docker run [옵션] [이미지 이름]:[태그] [실행할 명령어]

  • 주요 옵션:

    • -d (detached): 컨테이너를 백그라운드에서 실행하고 터미널을 분리합니다. 🧚‍♀️
      • docker run -d nginx
    • -p [호스트 포트]:[컨테이너 포트] (port mapping): 호스트(내 컴퓨터)의 포트와 컨테이너 내부의 포트를 연결합니다. 외부에서 컨테이너 서비스에 접근할 수 있게 해줍니다. 🔗
      • docker run -d -p 80:80 nginx (호스트의 80번 포트를 컨테이너의 80번 포트에 연결)
      • docker run -d -p 8080:80 nginx (호스트의 8080번 포트를 컨테이너의 80번 포트에 연결)
    • --name [컨테이너 이름] (name): 컨테이너에 알아보기 쉬운 이름을 부여합니다. 이름을 지정하지 않으면 도커가 임의의 이름을 부여합니다. 🏷️
      • docker run -d -p 80:80 --name my-web-server nginx
    • -it (interactive + tty): 컨테이너와 상호작용할 수 있는 터미널을 연결합니다. 주로 컨테이너 내부로 들어가 작업할 때 사용합니다. 🧑‍💻
      • docker run -it ubuntu:latest bash (우분투 컨테이너를 실행하고 bash 셸에 접속)
    • --rm (remove): 컨테이너가 종료될 때 자동으로 컨테이너를 삭제합니다. 임시 컨테이너를 실행할 때 유용합니다. ♻️
      • docker run -it --rm ubuntu:latest bash
    • -v [호스트 경로]:[컨테이너 경로] (volume): 호스트의 특정 디렉토리를 컨테이너 내부의 디렉토리와 연결하여 데이터를 영구적으로 저장하거나 공유합니다. 💾
      • docker run -d -p 3000:3000 --name my-app -v /Users/user/my-data:/app/data my-custom-app-image (로컬 /Users/user/my-data를 컨테이너 /app/data에 마운트)
    • --network [네트워크 이름] (network): 컨테이너를 특정 네트워크에 연결합니다. 🤝
      • docker run -d --name my-db --network my-app-network postgres

📊 1.4 실행 중인 컨테이너 확인 (docker ps)

현재 실행 중인 컨테이너 목록을 보여줍니다.

  • 명령어: docker ps
  • 모든 컨테이너 확인 (실행 중 + 종료된 것 포함): docker ps -a 🧐
  • 예시:
    docker ps
    # CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                  NAMES
    # a1b2c3d4e5f6   nginx     "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes   0.0.0.0:80->80/tcp     my-web-server

🛑 1.5 컨테이너 제어하기 (docker stop, docker start, docker restart)

컨테이너를 정지, 시작, 재시작합니다. [컨테이너 이름 또는 ID]를 사용합니다.

  • 정지: docker stop my-web-server ⏸️
  • 시작: docker start my-web-server ▶️
  • 재시작: docker restart my-web-server 🔄

🗑️ 1.6 컨테이너 삭제하기 (docker rm)

정지된 컨테이너를 삭제합니다. 실행 중인 컨테이너는 -f (강제 삭제) 옵션을 사용해야 삭제 가능합니다.

  • 명령어: docker rm [컨테이너 이름 또는 ID]
  • 예시:
    • docker rm my-web-server
    • 실행 중인 컨테이너 강제 삭제: docker rm -f my-web-server 💥

🧹 1.7 이미지 삭제하기 (docker rmi)

로컬에 저장된 이미지를 삭제합니다. 이 이미지를 기반으로 실행 중인 컨테이너가 없어야 삭제 가능합니다.

  • 명령어: docker rmi [이미지 이름 또는 ID]
  • 예시:
    • docker rmi nginx
    • 강제 삭제: docker rmi -f nginx (관련된 컨테이너가 있더라도 삭제) ⛔

🧑‍💻 2. 컨테이너와 상호작용하기

실행 중인 컨테이너 내부로 들어가거나, 컨테이너의 로그를 확인하고 싶을 때 유용한 명령어들입니다.

🚶‍♀️ 2.1 컨테이너 내부에서 명령어 실행하기 (docker exec)

실행 중인 컨테이너 내부에 새로운 프로세스를 생성하여 명령어를 실행합니다. 컨테이너 내부 환경을 직접 확인하거나 문제를 디버깅할 때 주로 사용합니다.

  • 명령어: docker exec [옵션] [컨테이너 이름 또는 ID] [실행할 명령어]
  • 주요 옵션:
    • -it: 상호작용 터미널을 연결하여 마치 컨테이너 내부에 접속한 것처럼 사용할 수 있게 합니다.
  • 예시:
    • 실행 중인 my-web-server 컨테이너의 /etc/nginx 디렉토리 내용 확인: docker exec my-web-server ls -la /etc/nginx 📄
    • 실행 중인 my-web-server 컨테이너의 bash 셸에 접속: docker exec -it my-web-server bash (또는 sh) 🚪
      • 컨테이너 내부에서 작업 후 exit를 입력하면 호스트 터미널로 돌아옵니다.

📜 2.2 컨테이너 로그 확인하기 (docker logs)

컨테이너가 출력하는 표준 출력(stdout) 및 표준 에러(stderr) 로그를 확인합니다. 애플리케이션의 동작 상태나 에러를 파악할 때 필수적입니다.

  • 명령어: docker logs [옵션] [컨테이너 이름 또는 ID]
  • 주요 옵션:
    • -f (follow): 실시간으로 추가되는 로그를 계속해서 출력합니다. tail -f와 유사합니다. 📈
    • --tail [숫자]: 로그의 마지막 특정 줄만 출력합니다. 🔢
      • docker logs --tail 100 my-web-server (마지막 100줄만)
    • --since [시간] / --until [시간]: 특정 시간 이후/이전의 로그만 출력합니다. ⏳
  • 예시:
    • docker logs my-web-server
    • docker logs -f my-web-server

📂 2.3 컨테이너와 호스트 간 파일 복사 (docker cp)

컨테이너 내부의 파일을 호스트로 복사하거나, 호스트의 파일을 컨테이너 내부로 복사합니다.

  • 명령어:
    • 컨테이너 -> 호스트: docker cp [컨테이너 이름 또는 ID]:[컨테이너 경로] [호스트 경로]
    • 호스트 -> 컨테이너: docker cp [호스트 경로] [컨테이너 이름 또는 ID]:[컨테이너 경로]
  • 예시:
    • 컨테이너의 Nginx 설정 파일 로컬로 복사: docker cp my-web-server:/etc/nginx/nginx.conf . (현재 디렉토리로)
    • 로컬의 새 설정 파일을 컨테이너로 복사: docker cp new-nginx.conf my-web-server:/etc/nginx/nginx.conf

🏗️ 3. 나만의 이미지 만들기 (docker build)

기존 이미지를 사용하는 것을 넘어, 나만의 애플리케이션을 위한 이미지를 직접 만들 수 있습니다. Dockerfile이라는 텍스트 파일을 작성하여 이미지 빌드 과정을 정의합니다.

  • 명령어: docker build [옵션] [Dockerfile이 있는 경로]
    • -t [이미지 이름]:[태그] (tag): 빌드된 이미지에 이름과 태그를 부여합니다. 🏷️
  • Dockerfile 예시 (./my-app/Dockerfile):

    # 기반 이미지 설정
    FROM node:18-alpine
    
    # 작업 디렉토리 설정
    WORKDIR /app
    
    # 의존성 파일 복사 및 설치
    COPY package.json .
    RUN npm install
    
    # 애플리케이션 코드 복사
    COPY . .
    
    # 포트 노출 (문서화 목적)
    EXPOSE 3000
    
    # 컨테이너 시작 시 실행될 명령어
    CMD ["npm", "start"]
  • 이미지 빌드 예시:
    • Dockerfile이 현재 디렉토리(. )에 있을 때: docker build -t my-nodejs-app:1.0 .
    • Dockerfilemy-app 디렉토리에 있을 때: docker build -t my-nodejs-app:1.0 ./my-app

🔗 4. 네트워크 & 볼륨 관리

도커 컨테이너는 기본적으로 격리되어 있지만, 서로 통신하거나 영구적인 데이터를 저장하기 위한 메커니즘이 필요합니다.

🤝 4.1 Docker 네트워크 관리 (docker network)

컨테이너 간 통신을 위한 가상 네트워크를 생성하고 관리합니다.

  • 네트워크 생성: docker network create [네트워크 이름]
    • docker network create my-app-network
  • 네트워크 목록 확인: docker network ls
  • 네트워크 정보 확인: docker network inspect [네트워크 이름]
  • 컨테이너를 네트워크에 연결/분리:
    • 연결: docker network connect [네트워크 이름] [컨테이너 이름 또는 ID]
    • 분리: docker network disconnect [네트워크 이름] [컨테이너 이름 또는 ID]
  • 활용 팁: 애플리케이션 컨테이너와 데이터베이스 컨테이너를 같은 네트워크에 연결하면 컨테이너 이름으로 서로를 호출할 수 있어 편리합니다.
    • docker run -d --name my-db --network my-app-network postgres
    • docker run -d --name my-app --network my-app-network my-nodejs-app
    • 이제 my-app 컨테이너에서 my-db라는 호스트 이름으로 데이터베이스에 접근할 수 있습니다. 🥳

💾 4.2 Docker 볼륨 관리 (docker volume)

컨테이너가 삭제되어도 데이터가 유실되지 않도록 영구적으로 데이터를 저장하는 데 사용됩니다.

  • 볼륨 생성: docker volume create [볼륨 이름]
    • docker volume create my-data-volume
  • 볼륨 목록 확인: docker volume ls
  • 볼륨 정보 확인: docker volume inspect [볼륨 이름]
  • 볼륨을 사용하여 컨테이너 실행: docker run -v [볼륨 이름]:[컨테이너 경로] ...
    • docker run -d --name my-db -v my-data-volume:/var/lib/postgresql/data postgres (PostgreSQL 데이터가 my-data-volume에 저장)
  • 볼륨 삭제: docker volume rm [볼륨 이름] ⚠️ 볼륨 내 데이터가 완전히 삭제되므로 주의하세요!

🧹 5. 유용한 Docker 시스템 관리 팁

도커를 오래 사용하다 보면 불필요한 이미지, 컨테이너, 볼륨 등이 쌓여 저장 공간을 차지하게 됩니다. 이럴 때 유용한 청소 명령어입니다.

🧹 5.1 시스템 정리 (docker system prune)

사용되지 않는 모든 도커 리소스(정지된 컨테이너, 사용되지 않는 네트워크, dangling 이미지 및 빌드 캐시)를 한 번에 제거합니다. ✨

  • 명령어: docker system prune
  • 옵션:
    • -a (all): 사용하지 않는 모든 이미지까지 포함하여 제거합니다. (주의: 한 번도 사용되지 않은 이미지도 삭제될 수 있습니다.)
    • --volumes: 사용되지 않는 볼륨까지 함께 제거합니다. (주의: 데이터 유실 가능성!)
  • 예시:
    • docker system prune
    • docker system prune -a
    • docker system prune --volumes
    • 항상 y를 입력하기 전에 어떤 항목들이 삭제될지 꼼꼼히 확인하세요!

ℹ️ 5.2 Docker 시스템 정보 확인 (docker info, docker version)

  • 도커 시스템 전체 정보: docker info (컨테이너 수, 이미지 수, 스토리지 드라이버 등 자세한 정보)
  • 도커 클라이언트 및 서버 버전 확인: docker version

💡 6. 실전 활용 팁 & 베스트 프랙티스

도커를 더욱 효율적으로 사용하기 위한 몇 가지 팁입니다.

🐳 6.1 Docker Compose 활용하기 (다중 컨테이너 관리)

단일 컨테이너는 docker run으로 충분하지만, 웹 서비스처럼 여러 컨테이너(웹 서버, 데이터베이스, 백엔드 API 등)가 유기적으로 연결되어야 할 때는 docker-compose를 사용하는 것이 훨씬 편리합니다. docker-compose.yml 파일 하나로 여러 컨테이너의 설정, 네트워크, 볼륨 등을 한 번에 정의하고 관리할 수 있습니다.

  • 설치: 별도로 설치해야 할 수 있습니다. (Docker Desktop에는 포함되어 있습니다.)
  • 간단한 docker-compose.yml 예시:
    version: '3.8'
    services:
      web:
        build: . # 현재 디렉토리의 Dockerfile로 이미지 빌드
        ports:
          - "80:80"
        networks:
          - app-network
      db:
        image: postgres:latest
        environment:
          POSTGRES_DB: mydb
          POSTGRES_USER: user
          POSTGRES_PASSWORD: password
        volumes:
          - db-data:/var/lib/postgresql/data
        networks:
          - app-network
    networks:
      app-network:
        driver: bridge
    volumes:
      db-data:
  • 실행: docker-compose up -d (백그라운드에서 모든 서비스 시작)
  • 종료: docker-compose down (모든 서비스 종료 및 리소스 삭제)
  • 로그 보기: docker-compose logs -f
  • 컨테이너 내부 접속: docker-compose exec web bash

⚙️ 6.2 자원 제한 (--memory, --cpus)

컨테이너가 호스트의 자원을 너무 많이 사용하지 않도록 제한할 수 있습니다.

  • 메모리 제한: docker run -d --memory 512m my-app (512MB)
  • CPU 제한: docker run -d --cpus 0.5 my-app (0.5개의 CPU 코어)

🐛 6.3 문제 해결 팁

  • 컨테이너가 예상대로 실행되지 않을 때:
    • docker logs [컨테이너 이름]으로 로그를 확인합니다.
    • docker inspect [컨테이너 이름]으로 컨테이너의 상세 정보를 확인합니다. (네트워크 설정, 볼륨 마운트 등)
    • docker exec -it [컨테이너 이름] bash로 내부 접속하여 수동으로 명령어를 실행해봅니다.
  • 포트 충돌: docker: Error response from daemon: driver failed programming external connectivity: Error starting userland proxy: listen tcp 0.0.0.0:80: bind: address already in use. 이런 에러는 호스트의 해당 포트가 이미 사용 중임을 의미합니다. 다른 포트를 사용하거나, 해당 포트를 사용 중인 프로세스를 종료해야 합니다. (예: Apache, Nginx 등)
  • 이미지 빌드 실패: Dockerfile의 각 RUN 명령어를 분리하여 단계별로 실행해보고, 어떤 단계에서 에러가 발생하는지 확인합니다.

맺음말

지금까지 도커를 실전에서 사용할 때 가장 많이 쓰이는 명령어들과 유용한 팁들을 자세히 알아봤습니다. 이 치트시트가 여러분의 도커 여정에 든든한 나침반이 되기를 바랍니다. 🧭

처음에는 어렵고 낯설게 느껴질 수 있지만, 꾸준히 사용하고 직접 여러 상황에 적용해보면서 금방 익숙해질 거예요. 도커는 개발 및 배포 워크플로우를 혁신적으로 개선해 줄 수 있는 강력한 도구입니다.

더 나아가 docker-compose를 통해 여러 컨테이너를 통합 관리하고, 쿠버네티스(Kubernetes)와 같은 오케스트레이션 도구로 확장한다면 더욱 복잡하고 거대한 시스템도 효율적으로 운영할 수 있게 됩니다.

오늘 배운 명령어들을 직접 터미널에 입력해보면서 도커와 친해지는 시간을 가져보세요! 궁금한 점이 있다면 언제든지 검색하고, 커뮤니티의 도움을 받는 것을 주저하지 마세요. 🚀 Happy Dockering! 🐳

답글 남기기

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