
git까지 정리했으니 이번엔 Docker입니다. "내 컴퓨터에서는 되는데 서버에서는 안 된다"는 상황을 한 번이라도 겪어봤다면 Docker가 왜 등장했는지 바로 이해가 됩니다. 환경 차이에서 오는 문제를 없애는 게 핵심입니다.
처음엔 개념이 좀 낯설어서 막막한 느낌이 있는데, 이미지와 컨테이너의 관계만 잡히면 나머지 명령어들은 자연스럽게 연결됩니다.
1편에서는 Docker의 핵심 개념, 이미지 관련 명령어, 컨테이너 실행과 관리를 다룹니다.
핵심 개념
Docker를 이해할 때 가장 먼저 잡아야 할 게 이미지(Image)와 컨테이너(Container)의 차이입니다.
이미지는 컨테이너를 만들기 위한 읽기 전용 템플릿입니다. 어떤 OS, 어떤 라이브러리, 어떤 코드가 들어갈지를 정의한 설계도입니다. 파일이지만 실행되지는 않습니다.
컨테이너는 이미지를 실행한 인스턴스입니다. 이미지 하나로 컨테이너를 여러 개 만들 수 있고, 각 컨테이너는 독립적으로 실행됩니다.
클래스와 인스턴스 관계로 생각하면 비슷합니다. 이미지가 클래스, 컨테이너가 인스턴스.
VM과의 차이
VM(가상 머신)은 OS 전체를 가상화하기 때문에 무겁습니다. Docker는 호스트 OS의 커널을 공유하고, 그 위에 필요한 것들만 격리해서 올립니다. 가볍고 빠른 대신 완전한 OS 격리는 아닙니다.
VM: 하드웨어 → 하이퍼바이저 → [Guest OS → App]
Docker: 하드웨어 → Host OS → Docker Engine → [Container(App)]
이미지 관련 명령어
이미지 받아오기
docker pull ubuntu # 최신 버전
docker pull ubuntu:22.04 # 특정 버전 (태그)
docker pull python:3.11-slim # slim = 최소화 버전
Docker Hub(hub.docker.com)에서 공식 이미지를 받아옵니다. 태그를 지정하지 않으면 latest를 받습니다. latest는 항상 최신이라 재현성이 필요할 때는 버전을 명시하는 게 좋습니다.
이미지 목록 확인
docker images # 로컬에 저장된 이미지 목록
docker images -a # 중간 레이어 이미지까지 포함
docker image ls # 위와 같음 (새로운 문법)
이미지 삭제
docker rmi 이미지명 # 이미지 삭제
docker rmi 이미지ID # ID로 삭제
docker image prune # 사용하지 않는 이미지 전체 삭제
docker image prune -a # 컨테이너에서 참조되지 않는 이미지 전체 삭제
이미지 상세 정보
docker image inspect 이미지명 # 이미지 상세 정보 (JSON)
docker history 이미지명 # 이미지 레이어 히스토리
컨테이너 실행 — docker run
docker run이 Docker 명령어 중 가장 옵션이 많습니다. 자주 쓰는 것들을 정리했습니다.
자주 쓰는 옵션
docker run -it ubuntu bash # -i(interactive) -t(tty) : 터미널 연결
docker run -d nginx # -d(detach) : 백그라운드 실행
docker run --name mycontainer nginx # 컨테이너 이름 지정
docker run --rm ubuntu echo "hello" # 종료 후 컨테이너 자동 삭제
포트 연결
docker run -p 8080:80 nginx # 호스트 8080 → 컨테이너 80 포트 연결
docker run -p 127.0.0.1:8080:80 nginx # 로컬호스트만 허용
-p 호스트포트:컨테이너포트 형식입니다. 호스트에서 8080으로 접속하면 컨테이너 안의 80 포트로 연결됩니다.
볼륨 연결
docker run -v /host/path:/container/path nginx # 호스트 경로 마운트
docker run -v $(pwd):/app python:3.11 python app.py # 현재 디렉토리 마운트
docker run -v myvolume:/data postgres # named volume 사용
컨테이너는 종료하면 내부 파일이 사라집니다. 데이터를 유지하려면 볼륨으로 연결해야 합니다.
환경 변수
docker run -e DB_HOST=localhost -e DB_PORT=5432 myapp
docker run --env-file .env myapp # .env 파일에서 읽어오기
종합 예시
실제로 쓸 때는 옵션이 여러 개 붙는 게 일반적입니다.
docker run -d \
--name postgres \
-p 5432:5432 \
-e POSTGRES_PASSWORD=secret \
-v pgdata:/var/lib/postgresql/data \
--restart unless-stopped \
postgres:16
--restart unless-stopped는 Docker 데몬이 재시작될 때 컨테이너도 자동으로 시작하게 합니다.
컨테이너 관리
목록 확인
docker ps # 실행 중인 컨테이너
docker ps -a # 중지된 것 포함 전체
docker ps -q # ID만 출력 (다른 명령어와 조합할 때)
시작 / 중지 / 재시작
docker start 컨테이너명 # 중지된 컨테이너 시작
docker stop 컨테이너명 # 정상 종료 (SIGTERM 후 대기)
docker restart 컨테이너명 # 재시작
docker kill 컨테이너명 # 강제 종료 (SIGKILL)
stop은 컨테이너가 종료 처리를 마칠 시간을 줍니다. 기본 10초를 기다리고 그래도 안 끝나면 강제 종료합니다. 즉시 끝내려면 kill을 씁니다.
삭제
docker rm 컨테이너명 # 중지된 컨테이너 삭제
docker rm -f 컨테이너명 # 실행 중이어도 강제 삭제
docker rm $(docker ps -aq) # 전체 컨테이너 삭제
docker container prune # 중지된 컨테이너 전체 삭제
컨테이너 내부 접속
docker exec -it 컨테이너명 bash # 실행 중인 컨테이너에 bash 쉘 연결
docker exec -it 컨테이너명 sh # bash 없으면 sh
docker exec 컨테이너명 ls /app # 명령어 하나만 실행
docker run -it는 컨테이너를 새로 만들 때 터미널 연결, docker exec -it는 이미 실행 중인 컨테이너에 접속합니다.
로그 확인
docker logs 컨테이너명 # 전체 로그 출력
docker logs -f 컨테이너명 # 실시간 follow
docker logs --tail 100 컨테이너명 # 마지막 100줄만
docker logs --since 10m 컨테이너명 # 최근 10분 로그
컨테이너 상세 정보
docker inspect 컨테이너명 # 상세 정보 (JSON)
docker stats # 실시간 리소스 사용량 (CPU, 메모리 등)
docker stats 컨테이너명 # 특정 컨테이너만
docker top 컨테이너명 # 컨테이너 내부 프로세스 목록
볼륨
컨테이너 데이터를 호스트에 저장하거나, 컨테이너 간에 공유할 때 씁니다.
docker volume create myvolume # named volume 생성
docker volume ls # 볼륨 목록
docker volume inspect myvolume # 볼륨 상세 정보 (실제 저장 경로 등)
docker volume rm myvolume # 볼륨 삭제
docker volume prune # 사용하지 않는 볼륨 전체 삭제
볼륨 종류는 두 가지가 주로 쓰입니다.
# Bind mount — 호스트 경로를 직접 연결
-v /host/absolute/path:/container/path
# Named volume — Docker가 관리하는 볼륨
-v myvolume:/container/path
개발할 때는 코드를 실시간으로 반영하려고 bind mount를 씁니다. DB처럼 데이터를 영구 보관해야 할 때는 named volume이 적합합니다.
네트워크
컨테이너끼리 통신하거나 외부와 연결하는 방식을 정의합니다.
docker network ls # 네트워크 목록
docker network create mynetwork # 사용자 정의 네트워크 생성
docker network inspect mynetwork # 네트워크 상세 정보
docker network rm mynetwork # 네트워크 삭제
docker network prune # 사용하지 않는 네트워크 삭제
docker run --network mynetwork 이미지명 # 네트워크 지정해서 실행
같은 네트워크에 있는 컨테이너끼리는 컨테이너 이름으로 서로를 찾을 수 있습니다. 예를 들어 같은 네트워크의 postgres 컨테이너에는 postgres라는 호스트명으로 접근할 수 있습니다.
전체 정리 — system prune
불필요한 리소스를 한꺼번에 정리할 때 씁니다.
docker system prune # 중지 컨테이너 + 미사용 이미지/네트워크/볼륨 정리
docker system prune -a # 실행 중이지 않은 이미지까지 전체 정리
docker system df # 디스크 사용량 확인
정리 표
| 분류 | 명령어 | 동작 |
|---|---|---|
| 이미지 | docker pull |
이미지 받기 |
| 이미지 | docker images |
이미지 목록 |
| 이미지 | docker rmi |
이미지 삭제 |
| 이미지 | docker image prune -a |
미사용 이미지 전체 삭제 |
| 컨테이너 | docker run -d --name -p -v -e |
컨테이너 실행 |
| 컨테이너 | docker ps -a |
전체 컨테이너 목록 |
| 컨테이너 | docker stop / kill |
정상 종료 / 강제 종료 |
| 컨테이너 | docker rm -f |
강제 삭제 |
| 컨테이너 | docker exec -it ... bash |
내부 쉘 접속 |
| 컨테이너 | docker logs -f |
실시간 로그 |
| 컨테이너 | docker stats |
리소스 사용량 |
| 볼륨 | docker volume create |
볼륨 생성 |
| 볼륨 | docker volume prune |
미사용 볼륨 삭제 |
| 네트워크 | docker network create |
네트워크 생성 |
| 전체 정리 | docker system prune -a |
전체 미사용 리소스 삭제 |
2편에서는 Dockerfile 작성법과 Docker Compose를 정리합니다.
'블로그, 컴퓨터 > Cheatsheets' 카테고리의 다른 글
| Shell Script 정리 (1편) — 변수, 조건문, 반복문, 함수 (0) | 2026.05.28 |
|---|---|
| Docker 명령어 정리 (2편) — Dockerfile과 Docker Compose (0) | 2026.05.27 |
| Git 명령어 정리 (2편) — 브랜치, 원격, 되돌리기, stash (0) | 2026.05.26 |
| Git 명령어 정리 (1편) — 기본 개념, 설정, 커밋, 로그 (0) | 2026.05.26 |
| Neovim 설정 정리 (2편) — lazy.nvim, LSP, 주요 플러그인 (0) | 2026.05.25 |