G: 안녕하세요, 개발자 여러분! 🚀 오늘은 클라우드 시대의 필수 도구이자 개발 생산성을 극대화하는 Docker
에 대해 깊이 파고들어 볼 시간입니다. 특히, Docker를 자유자재로 다루기 위한 핵심 명령어들을 초보자의 눈높이부터 실무에서 활용하는 팁까지, 이 한 포스팅으로 완벽하게 마스터할 수 있도록 도와드리겠습니다!
💡 왜 Docker를 배워야 할까요?
Docker는 애플리케이션을 컨테이너(Container)라는 격리된 환경에 패키징하여 개발, 배포, 실행을 훨씬 쉽고 일관되게 만들어주는 플랫폼입니다. “내 컴퓨터에서는 되는데, 서버에서는 안 돼요!” 라는 말, 이제 Docker와 함께라면 옛말이 됩니다. ✨
이 글을 통해 여러분은 다음과 같은 질문에 대한 답을 얻게 될 것입니다:
- Docker의 기본 개념은 무엇인가요?
- 주요 Docker 명령어는 어떻게 사용하나요?
- 실무에서 유용하게 쓸 수 있는 팁과 베스트 프랙티스는 무엇인가요?
자, 그럼 Docker의 세계로 함께 떠나볼까요? 🐳
📦 1. Docker, 이게 뭔가요? 핵심 개념 잡기
본격적인 명령어 탐험에 앞서, Docker의 몇 가지 핵심 개념을 명확히 이해하는 것이 중요합니다.
-
이미지 (Image):
- 애플리케이션 실행에 필요한 모든 것(코드, 런타임, 시스템 도구, 라이브러리 등)을 포함하는 읽기 전용 템플릿입니다. 📦
Java
의.jar
파일이나Python
의requirements.txt
와 비슷하지만, 운영체제 환경까지 포함하는 ‘완벽한 스냅샷’이라고 생각하면 됩니다.- 예시:
ubuntu
,nginx
,mysql
등의 기본 이미지.
-
컨테이너 (Container):
- 이미지의 실행 가능한 인스턴스입니다. 🚀
- 이미지를 기반으로 격리된 환경에서 애플리케이션이 실제로 동작하는 공간입니다.
- 가상머신(VM)과 달리, 호스트 OS의 커널을 공유하여 훨씬 가볍고 빠르게 동작합니다.
-
레지스트리 (Registry):
- Docker 이미지를 저장하고 공유하는 공간입니다. ☁️
- 가장 유명한 레지스트리는
Docker Hub
입니다. 마치 GitHub처럼 이미지를 업로드(push)하고 다운로드(pull)할 수 있습니다.
-
볼륨 (Volume):
- 컨테이너 내에서 생성되거나 사용되는 데이터를 영속적으로 저장하기 위한 메커니즘입니다. 💾
- 컨테이너가 삭제되어도 데이터는 보존되어야 할 때 사용합니다. (예: 데이터베이스 파일)
-
네트워크 (Network):
- 컨테이너 간 또는 컨테이너와 외부 세계 간의 통신을 가능하게 합니다. 🌐
- 기본적으로 여러 네트워크 유형이 있으며, 필요에 따라 사용자 정의 네트워크를 생성할 수 있습니다.
🛠️ 2. 본격! Docker 핵심 명령어 완전 정복
이제 각 개념을 실제 명령어로 어떻게 다루는지 살펴보겠습니다. 각 명령어마다 사용 예시와 함께 상세히 설명해 드릴게요.
I. 설치 및 기본 확인 명령어
Docker가 제대로 설치되었는지 확인하는 가장 기본적인 명령어입니다.
-
docker version
: 설치된 Docker 클라이언트 및 서버(Daemon)의 버전을 확인합니다.docker version
# 예시 출력: Client: Docker Engine - Community Version: 24.0.5 ... Server: Docker Engine - Community Engine: Version: 24.0.5 ...
-
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의 기본이 되는 이미지를 다루는 명령어들입니다.
-
docker pull [이미지_이름]:[태그]
: Docker Hub 등 레지스트리에서 이미지를 다운로드합니다. 태그를 생략하면latest
태그가 기본으로 적용됩니다.docker pull ubuntu:22.04 # Ubuntu 22.04 이미지 다운로드 docker pull nginx # 최신 Nginx 이미지 다운로드 (latest 태그)
-
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
-
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"]
- Dockerfile 예시:
-
docker rmi [이미지_ID 또는 이미지_이름]:[태그]
: 로컬에 있는 하나 이상의 이미지를 삭제합니다. 컨테이너가 해당 이미지를 사용 중이라면 삭제되지 않습니다.docker rmi ubuntu:22.04 # 특정 태그 이미지 삭제 docker rmi b8d4847e06a3 # 이미지 ID로 삭제 docker rmi -f my-web-app:1.0 # 강제로 삭제 (사용 중인 컨테이너가 있어도 삭제 시도)
⚠️ 주의: 이미지를 사용하는 컨테이너가 있다면 삭제되지 않거나
-f
옵션이 필요합니다. -
docker save -o [저장_파일명.tar] [이미지_이름]:[태그]
: 이미지를.tar
파일로 내보내어 다른 시스템으로 쉽게 옮길 수 있도록 합니다.docker save -o my_nginx_image.tar nginx:latest
-
docker load -i [불러올_파일명.tar]
:docker save
로 내보낸.tar
파일을 다시 Docker 이미지로 불러옵니다.docker load -i my_nginx_image.tar
III. 컨테이너 관리 (Container Management)
Docker의 핵심인 컨테이너를 생성, 실행, 관리하는 명령어들입니다.
-
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
- 주요 옵션:
-
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
-
docker start [컨테이너_ID 또는 이름]
: 중지된 컨테이너를 다시 시작합니다.docker start my-nginx docker start a1b2c3d4e5f6
-
docker stop [컨테이너_ID 또는 이름]
: 실행 중인 컨테이너를 정상적으로 종료합니다. (SIGTERM 시그널 전송)docker stop my-nginx
-
docker restart [컨테이너_ID 또는 이름]
: 컨테이너를 중지했다가 다시 시작합니다.docker restart my-nginx
-
docker rm [컨테이너_ID 또는 이름]
: 하나 이상의 컨테이너를 삭제합니다. 실행 중인 컨테이너는 삭제되지 않습니다.docker rm my-nginx # 특정 컨테이너 삭제 docker rm -f my-nginx # 실행 중인 컨테이너 강제 삭제 docker rm $(docker ps -aq) # 모든 컨테이너 삭제 (실행 중인 컨테이너는 오류 발생)
⚠️ 주의: 데이터 볼륨이 연결되어 있다면
docker rm -v
옵션을 사용하여 볼륨도 함께 삭제할 수 있습니다. -
docker exec -it [컨테이너_ID 또는 이름] [명령어]
: 실행 중인 컨테이너 내부에서 명령어를 실행합니다. 컨테이너 내부로 접속할 때 주로 사용됩니다.# my-nginx 컨테이너 내부로 bash 쉘 접속 docker exec -it my-nginx bash # my-app 컨테이너 내부에서 ls /app 명령어 실행 docker exec my-app ls /app
-
docker logs [컨테이너_ID 또는 이름]
: 컨테이너의 표준 출력(stdout) 및 표준 에러(stderr) 로그를 확인합니다.docker logs my-nginx # 모든 로그 출력 docker logs -f my-nginx # 실시간으로 로그를 계속해서 출력 (follow) docker logs --tail 100 my-nginx # 마지막 100줄만 출력
-
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
- 호스트 -> 컨테이너:
-
docker inspect [컨테이너_ID 또는 이름]
: 컨테이너의 상세 정보를 JSON 형식으로 출력합니다. IP 주소, 볼륨 마운트 정보 등을 확인할 때 유용합니다.docker inspect my-nginx docker inspect --format='{{.NetworkSettings.IPAddress}}' my-nginx # IP 주소만 추출
-
docker attach [컨테이너_ID 또는 이름]
: 실행 중인 컨테이너의 STDIN, STDOUT, STDERR에 다시 연결합니다.-d
옵션 없이 실행된 컨테이너의 출력을 보고 싶을 때 유용합니다.docker attach my-interactive-container
⚠️ 주의:
-d
로 실행된 컨테이너에attach
하면 Ctrl+C로 종료 시 컨테이너도 같이 종료될 수 있으니 유의하세요. 빠져나올 때는Ctrl+P + Ctrl+Q
를 사용하세요.
IV. 볼륨 관리 (Volume Management)
컨테이너의 데이터를 영속적으로 유지하기 위한 볼륨을 다룹니다.
-
docker volume create [볼륨_이름]
: 이름이 지정된 볼륨을 생성합니다.docker volume create my-database-data
-
docker volume ls
: 로컬에 생성된 모든 볼륨 목록을 보여줍니다.docker volume ls
-
docker volume inspect [볼륨_이름]
: 특정 볼륨의 상세 정보를 확인합니다.docker volume inspect my-database-data
-
docker volume rm [볼륨_이름]
: 특정 볼륨을 삭제합니다. 사용 중인 볼륨은 삭제되지 않습니다.docker volume rm my-database-data
-
docker run -v [볼륨_이름]:[컨테이너_경로] [이미지_이름]
: 컨테이너 실행 시 미리 생성한 볼륨을 연결합니다.docker run -d --name my-db -v my-database-data:/var/lib/mysql mysql:8.0
V. 네트워크 관리 (Network Management)
컨테이너 간의 통신을 제어하는 네트워크를 다룹니다.
-
docker network create [네트워크_이름]
: 사용자 정의 브릿지 네트워크를 생성합니다. (기본bridge
,host
,none
외에 직접 생성)docker network create my-app-network
-
docker network ls
: 로컬에 생성된 모든 Docker 네트워크 목록을 보여줍니다.docker network ls
-
docker network inspect [네트워크_이름]
: 특정 네트워크의 상세 정보를 확인합니다. 연결된 컨테이너 정보도 볼 수 있습니다.docker network inspect my-app-network
-
docker network rm [네트워크_이름]
: 특정 네트워크를 삭제합니다.docker network rm my-app-network
-
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-server
로http://backend-server:port
와 같이 이름으로 통신 가능! 🌐
VI. 시스템 관리 및 정리 (System Management & Cleanup)
사용하지 않는 자원들을 정리하여 디스크 공간을 확보하는 명령어입니다.
-
docker system prune
: 사용하지 않는(dangling) 모든 컨테이너, 이미지(캐시 이미지 포함), 볼륨, 네트워크를 삭제합니다. 디스크 공간 확보에 매우 유용합니다. 🗑️docker system prune # 종료된 컨테이너, 사용되지 않는 이미지, 네트워크 삭제 docker system prune -a # 위 항목 + 사용되지 않는 모든 이미지 (캐시 포함) 삭제 docker system prune --volumes # 위 항목 + 사용되지 않는 볼륨도 함께 삭제 (가장 강력한 정리)
⚠️ 주의: 이 명령어는 삭제할 항목을 물어보므로, 잘 확인하고 실행하세요! 특히
--volumes
는 중요한 데이터를 날릴 수도 있습니다. -
docker stats
: 실행 중인 컨테이너들의 CPU, 메모리, 네트워크 사용량 등 실시간 리소스 사용 현황을 보여줍니다. 📈docker stats
VII. 기타 유용한 명령어
-
docker login
/docker logout
: Docker Hub와 같은 레지스트리에 로그인/로그아웃합니다. 이미지를push
하기 위해 필요합니다.docker login # username, password 입력 프롬프트가 나옵니다. docker logout
-
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! 🐳✨