G: 안녕하세요, 개발자 여러분! 🚀 복잡한 개발 환경 설정과 배포의 늪에서 벗어나게 해주는 마법 같은 도구, 바로 ‘도커(Docker)’입니다. 도커를 사용하면 내 컴퓨터에서 완벽하게 작동하던 애플리케이션이 다른 컴퓨터에서는 ‘안돼요!’라고 외치는 불상사를 피할 수 있죠. 마치 모든 필요한 도구와 재료가 담긴 ‘조립식 주택’을 만들어 어디든 옮겨 지을 수 있는 것과 같습니다.
하지만 처음 도커를 접하면 수많은 명령어와 개념에 압도당하기 쉽습니다. “컨테이너는 뭐고, 이미지는 또 뭐야? 볼륨은 왜 필요해?” 같은 질문이 꼬리에 꼬리를 물죠. 🤔
걱정 마세요! 이 글은 도커를 실전에서 바로 활용할 수 있도록, 가장 핵심적인 명령어와 유용한 팁들을 ‘치트시트’ 형식으로 정리했습니다. 이 글 하나면 도커의 기본적인 사용법부터 실전 활용까지 마스터할 수 있을 거예요! 💪
🌐 1. Docker 시작하기: 이미지 & 컨테이너 관리의 기초
도커의 모든 것은 ‘이미지’와 ‘컨테이너’에서 시작합니다. 이미지는 애플리케이션 실행에 필요한 모든 것(코드, 런타임, 시스템 도구, 라이브러리 등)을 담은 ‘설계도’ 또는 ‘정지된 스냅샷’이고, 컨테이너는 이 이미지를 기반으로 ‘실행되는 인스턴스’라고 생각하면 됩니다.
📦 1.1 이미지 가져오기 (docker pull
)
원하는 소프트웨어나 운영체제 이미지를 도커 허브(Docker Hub)와 같은 레지스트리에서 다운로드합니다.
- 명령어:
docker pull [이미지 이름]:[태그]
[태그]
는 버전 또는 특정 빌드를 나타내며, 생략하면latest
태그가 기본으로 사용됩니다.
- 예시:
- Nginx 웹 서버 이미지 가져오기:
docker pull nginx
🌐 - 우분투 20.04 이미지 가져오기:
docker pull ubuntu:20.04
🐧
- Nginx 웹 서버 이미지 가져오기:
📋 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
- 컨테이너의 Nginx 설정 파일 로컬로 복사:
🏗️ 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 .
Dockerfile
이my-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! 🐳