G: 안녕하세요, 개발자 여러분! 👋
오늘날 소프트웨어 개발 및 배포 환경에서 도커(Docker)는 필수적인 도구로 자리매김했습니다. “내 컴퓨터에서는 되는데, 저 서버에서는 안 되네?” 라는 비극적인 상황을 해결해주고, 애플리케이션을 빠르고 일관성 있게 배포할 수 있도록 돕는 마법 같은 기술이죠! ✨
하지만 도커를 처음 접하거나 깊이 있게 사용해보지 않았다면, 수많은 명령어와 개념들이 다소 복잡하게 느껴질 수 있습니다. 걱정 마세요! 이 글에서는 도커의 핵심 구성 요소인 이미지(Image), 컨테이너(Container), 그리고 네트워크(Network)를 중심으로 가장 중요하고 자주 사용되는 명령어들을 총체적으로 파헤쳐 보겠습니다. 이 가이드를 통해 여러분은 도커를 자유자재로 다루는 능력자가 될 수 있을 거예요! 💪
1. 도커 이미지: 컨테이너의 청사진 🖼️
도커 이미지는 컨테이너를 생성하기 위한 읽기 전용 템플릿입니다. 쉽게 말해, 애플리케이션과 그에 필요한 모든 것(코드, 런타임, 시스템 도구, 라이브러리 등)을 포함하는 패키지라고 생각할 수 있습니다. 이미지는 여러 계층(layer)으로 구성되어 있어 효율적인 재사용과 빠른 빌드가 가능합니다.
1.1. 이미지 가져오기: docker pull
⬇️
도커 허브(Docker Hub)와 같은 레지스트리에서 이미지를 다운로드합니다.
docker pull [이미지명]:[태그]
예시:
- 최신 우분투 이미지 다운로드:
docker pull ubuntu:latest
👉
latest
태그는 기본값이므로 생략할 수 있습니다:docker pull ubuntu
- 특정 버전의 Nginx 이미지 다운로드:
docker pull nginx:1.21.0
👉 특정 버전이나 태그를 명시하여 원하는 이미지를 정확히 가져올 수 있습니다.
1.2. 이미지 빌드하기: docker build
🏗️
Dockerfile
이라는 텍스트 파일을 기반으로 사용자 정의 이미지를 생성합니다.
docker build -t [이미지명]:[태그] [Dockerfile 경로]
예시:
- 현재 디렉토리의 Dockerfile로
my-web-app:1.0
이미지 빌드:# Dockerfile 예시 FROM ubuntu:20.04 RUN apt-get update && apt-get install -y nginx COPY ./index.html /var/www/html/ EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
docker build -t my-web-app:1.0 .
👉
.
은 Dockerfile이 현재 디렉토리에 있음을 의미합니다.-t
옵션으로 이미지 이름과 태그를 지정합니다.
1.3. 로컬 이미지 목록 확인: docker images
또는 docker image ls
📜
로컬 시스템에 저장된 모든 이미지 목록을 보여줍니다.
docker images
# 또는
docker image ls
예시 출력:
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 54c9d81cbb44 3 weeks ago 77.8MB
nginx 1.21.0 d3b4e9e0b82b 2 months ago 133MB
my-web-app 1.0 a1b2c3d4e5f6 2 hours ago 150MB
1.4. 이미지 삭제: docker rmi
또는 docker image rm
🗑️
더 이상 필요 없는 이미지를 삭제합니다. 해당 이미지로 생성된 컨테이너가 실행 중이거나 존재하면 삭제되지 않습니다.
docker rmi [이미지명]:[태그]
# 또는 이미지 ID로 삭제
docker rmi [이미지 ID]
예시:
my-web-app:1.0
이미지 삭제:docker rmi my-web-app:1.0
- 강제로 이미지 삭제 (사용 중인 컨테이너가 있더라도):
docker rmi -f [이미지 ID]
👉
-f
(force) 옵션은 주의해서 사용해야 합니다! ⚠️
1.5. 이미지 저장/로드: docker save
& docker load
💾
이미지를 .tar
파일로 저장하거나, .tar
파일에서 로드합니다. 인터넷 연결이 제한된 환경에서 유용합니다.
-
이미지 저장:
docker save -o [저장할 파일명.tar] [이미지명]:[태그]
예시:
docker save -o my-nginx.tar nginx:latest
👉
my-nginx.tar
파일로nginx:latest
이미지를 저장합니다. -
이미지 로드:
docker load -i [로드할 파일명.tar]
예시:
docker load -i my-nginx.tar
👉
my-nginx.tar
파일에서 이미지를 로드하여 로컬 이미지 목록에 추가합니다.
2. 도커 컨테이너: 실행 가능한 인스턴스 🚀
도커 컨테이너는 이미지의 실행 가능한 인스턴스입니다. 이미지가 설계도라면, 컨테이너는 그 설계도를 바탕으로 만들어진 실제 건물이라고 비유할 수 있습니다. 각 컨테이너는 호스트 시스템으로부터 격리된 환경에서 독립적으로 실행됩니다.
2.1. 컨테이너 생성 및 실행: docker run
✨
이미지를 사용하여 새로운 컨테이너를 생성하고 실행합니다. 가장 중요하고 많이 사용되는 명령어입니다.
docker run [옵션] [이미지명]:[태그] [실행할 명령어]
주요 옵션:
-d
,--detach
: 컨테이너를 백그라운드에서 실행합니다. (데몬 모드)-p
,--publish
: 호스트와 컨테이너 간의 포트 매핑을 설정합니다.[호스트 포트]:[컨테이너 포트]
-v
,--volume
: 호스트와 컨테이너 간의 볼륨(디렉토리) 마운트를 설정합니다.[호스트 경로]:[컨테이너 경로]
--name
: 컨테이너에 이름을 부여합니다. (이름을 지정하지 않으면 무작위 이름이 할당됨)-it
: 컨테이너와 상호작용 가능한 터미널을 연결합니다. (Interactive + TTY)--rm
: 컨테이너 종료 시 자동으로 삭제합니다. (임시 컨테이너에 유용)--network
: 컨테이너를 특정 네트워크에 연결합니다.
예시:
-
Nginx 웹 서버 컨테이너 백그라운드 실행:
docker run -d -p 80:80 --name my-nginx nginx:latest
👉
nginx:latest
이미지를 사용하여my-nginx
라는 이름의 컨테이너를 생성하고, 호스트의 80번 포트를 컨테이너의 80번 포트에 연결하여 백그라운드에서 실행합니다. -
Ubuntu 컨테이너에 접속하여 Bash 쉘 사용:
docker run -it --rm ubuntu:latest bash
👉
ubuntu:latest
컨테이너를 생성하고 바로 Bash 쉘에 접속합니다.-it
옵션으로 상호작용이 가능하며,--rm
으로 종료 시 컨테이너를 자동 삭제합니다. -
로컬 디렉토리를 컨테이너에 마운트하여 Nginx 실행:
# 호스트에 'html' 디렉토리를 만들고 안에 index.html 파일 생성 mkdir html && echo " <h1>Hello Docker!</h1>" > html/index.html docker run -d -p 80:80 --name my-custom-nginx -v "$(pwd)/html:/usr/share/nginx/html" nginx:latest
👉 현재 디렉토리의
html
폴더를 Nginx 컨테이너의 웹 루트(usr/share/nginx/html
)에 마운트합니다.
2.2. 실행 중인 컨테이너 목록 확인: docker ps
또는 docker container ls
📋
현재 실행 중인 컨테이너 목록을 보여줍니다.
docker ps
# 또는
docker container ls
- 모든 컨테이너 (실행 중이거나 중지된 것 포함) 확인:
docker ps -a
예시 출력:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a7b8c9d0e1f2 nginx:latest "nginx -g 'daemon of…" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp my-nginx
2.3. 컨테이너 시작/중지/재시작: docker start
, docker stop
, docker restart
⏯️
중지된 컨테이너를 시작하거나, 실행 중인 컨테이너를 중지, 또는 재시작합니다.
docker start [컨테이너 ID 또는 이름]
docker stop [컨테이너 ID 또는 이름]
docker restart [컨테이너 ID 또는 이름]
예시:
my-nginx
컨테이너 중지:docker stop my-nginx
- 중지된
my-nginx
컨테이너 시작:docker start my-nginx
2.4. 컨테이너 삭제: docker rm
또는 docker container rm
🗑️
중지된 컨테이너를 삭제합니다. 실행 중인 컨테이너는 기본적으로 삭제되지 않습니다.
docker rm [컨테이너 ID 또는 이름]
예시:
my-nginx
컨테이너 삭제:docker rm my-nginx
- 실행 중인 컨테이너 강제 삭제:
docker rm -f my-nginx
- 모든 중지된 컨테이너 삭제:
docker rm $(docker ps -aq)
👉
docker ps -aq
는 모든 컨테이너 ID를 출력합니다. 이를docker rm
의 인자로 넘겨 일괄 삭제합니다.
2.5. 컨테이너 내부 명령어 실행: docker exec
⌨️
실행 중인 컨테이너 내부에서 명령어를 실행합니다. 컨테이너 내부로 직접 들어가지 않고 특정 작업만 수행할 때 유용합니다.
docker exec [옵션] [컨테이너 ID 또는 이름] [실행할 명령어]
예시:
my-nginx
컨테이너 내에서 Bash 쉘 실행:docker exec -it my-nginx bash
👉 마치 SSH로 서버에 접속하듯이 컨테이너 내부 터미널로 들어갈 수 있습니다.
my-nginx
컨테이너 내에서 Nginx 설정 파일 내용 확인:docker exec my-nginx cat /etc/nginx/nginx.conf
2.6. 컨테이너 로그 확인: docker logs
📝
컨테이너의 표준 출력(stdout)과 표준 에러(stderr) 로그를 확인합니다.
docker logs [옵션] [컨테이너 ID 또는 이름]
주요 옵션:
-f
,--follow
: 실시간으로 로그를 계속해서 보여줍니다.--tail [숫자]
: 로그의 마지막 [숫자] 줄만 보여줍니다.
예시:
my-nginx
컨테이너의 모든 로그 확인:docker logs my-nginx
my-nginx
컨테이너의 로그를 실시간으로 확인:docker logs -f my-nginx
2.7. 호스트와 컨테이너 간 파일 복사: docker cp
↔️
호스트 시스템과 컨테이너 간에 파일을 복사합니다.
docker cp [원본 경로] [대상 경로]
예시:
- 호스트의
my-file.txt
를my-nginx
컨테이너의/tmp/
로 복사:docker cp my-file.txt my-nginx:/tmp/
my-nginx
컨테이너의/etc/nginx/nginx.conf
를 호스트의 현재 디렉토리로 복사:docker cp my-nginx:/etc/nginx/nginx.conf .
3. 도커 네트워크: 컨테이너 간의 연결고리 🔗
도커 네트워크는 컨테이너들이 서로, 또는 외부와 통신하는 방식을 정의합니다. 도커는 기본적으로 몇 가지 네트워크 드라이버를 제공하며, 가장 흔하게 사용되는 것은 bridge
네트워크입니다. 사용자 정의 네트워크를 생성하여 컨테이너 간의 이름 기반 통신을 가능하게 하는 것이 모범 사례입니다.
3.1. 네트워크 목록 확인: docker network ls
🌐
현재 도커에 생성된 네트워크 목록을 확인합니다.
docker network ls
예시 출력 (기본 네트워크 포함):
NETWORK ID NAME DRIVER SCOPE
63b2f5d91c80 bridge bridge local
5b9b2a7d4e1f host host local
0a1b2c3d4e5f none null local
bridge
: 기본 네트워크. 컨테이너들이 이 네트워크에 연결되면 IP 주소로 통신할 수 있습니다.host
: 컨테이너가 호스트의 네트워크 스택을 공유합니다.none
: 컨테이너가 어떤 네트워크 인터페이스도 갖지 않습니다.
3.2. 네트워크 생성: docker network create
🛠️
사용자 정의 네트워크를 생성합니다. 마이크로서비스 아키텍처나 여러 컨테이너가 서로 통신해야 하는 복합 애플리케이션에 매우 유용합니다.
docker network create [네트워크 이름]
예시:
my-app-network
라는 이름의 브릿지 네트워크 생성:docker network create my-app-network
👉 이 네트워크에 연결된 컨테이너들은 서로 컨테이너 이름을 통해 통신할 수 있습니다. (DNS 이름 해상도 지원)
3.3. 네트워크 정보 확인: docker network inspect
🔍
특정 네트워크의 상세 정보를 확인합니다. 연결된 컨테이너, IP 범위 등을 볼 수 있습니다.
docker network inspect [네트워크 ID 또는 이름]
예시:
my-app-network
의 상세 정보 확인:docker network inspect my-app-network
👉 출력에서 “Containers” 섹션을 보면 현재 이 네트워크에 연결된 컨테이너 목록과 그들의 IP 주소를 확인할 수 있습니다.
3.4. 컨테이너를 네트워크에 연결/해제: docker network connect
/ docker network disconnect
🔌
실행 중인 컨테이너를 특정 네트워크에 연결하거나 해제합니다. docker run
시 --network
옵션으로 처음부터 연결하는 것이 일반적이지만, 나중에 추가/제거할 수도 있습니다.
-
컨테이너 연결:
docker network connect [네트워크 이름] [컨테이너 ID 또는 이름]
예시:
# 먼저 컨테이너를 기본 네트워크로 실행 docker run -d --name my-backend backend-image:latest # my-app-network에 연결 docker network connect my-app-network my-backend
-
컨테이너 연결 해제:
docker network disconnect [네트워크 이름] [컨테이너 ID 또는 이름]
예시:
docker network disconnect my-app-network my-backend
3.5. 네트워크 삭제: docker network rm
🗑️
더 이상 사용하지 않는 네트워크를 삭제합니다.
docker network rm [네트워크 ID 또는 이름]
예시:
my-app-network
삭제:docker network rm my-app-network
4. 추가적인 유용 명령어 및 팁 💡
4.1. 도커 시스템 정리: docker system prune
🧹
사용하지 않는 도커 리소스(중지된 컨테이너, 사용되지 않는 이미지, 볼륨, 네트워크 등)를 일괄적으로 삭제하여 디스크 공간을 확보합니다. 주기적으로 실행하여 시스템을 깨끗하게 유지하는 것이 좋습니다.
docker system prune
- 모든 사용하지 않는 리소스 삭제 (볼륨 포함):
docker system prune -a --volumes
👉
-a
는 모든 사용하지 않는 이미지(컨테이너에 의해 참조되지 않는 이미지)를 포함합니다.--volumes
는 사용되지 않는 볼륨도 삭제합니다. 주의해서 사용하세요! 🚨
4.2. 도커 정보 확인: docker info
& docker version
ℹ️
-
도커 시스템 정보:
docker info
👉 도커 엔진의 상세 정보 (컨테이너/이미지 수, 스토리지 드라이버, 네트워크 드라이버 등)를 보여줍니다.
-
도커 버전 정보:
docker version
👉 도커 클라이언트와 서버(Daemon)의 버전을 확인할 수 있습니다.
마치며 🎉
지금까지 도커 이미지, 컨테이너, 네트워크의 핵심 명령어들을 자세한 설명과 풍부한 예시를 통해 살펴보았습니다. 이 명령어들은 도커를 사용하는 데 있어 가장 기본적이면서도 강력한 도구들입니다.
도커를 익히는 것은 단순히 명령어를 외우는 것을 넘어, 여러분의 애플리케이션 개발, 배포, 운영 워크플로우를 혁신하는 일입니다. 환경 불일치 문제를 해결하고, 일관된 개발 환경을 구축하며, CI/CD 파이프라인을 자동화하는 데 도커는 핵심적인 역할을 수행합니다.
이 가이드가 여러분의 도커 여정에 훌륭한 나침반이 되기를 바랍니다. 꾸준히 연습하고, 다양한 시나리오에 적용해보면서 도커의 진정한 힘을 경험하시길 응원합니다! 🚀 다음에는 도커 컴포즈(Docker Compose)나 도커 볼륨(Docker Volume)에 대해서도 자세히 알아보는 시간을 가져보는 건 어떨까요?
궁금한 점이 있다면 언제든지 질문해주세요! Happy Dockering! 🐳✨