일상 코딩
[윈도우 개발 환경 설정] 7편: Docker Desktop 설치 & 기본 사용법 본문
7편: Docker Desktop 설치 & 기본 사용법
시리즈: 윈도우 네이티브 개발 환경 구축 A to Z — 새 PC부터 클라우드 배포까지
이전 편: 6편에서 pyenv-win으로 Python을 설치하고, FastAPI + Uvicorn Hello World API를 띄워 봤습니다.
들어가며
6편까지 프론트엔드(React SPA)와 백엔드 두 개(Go + Gin, Python + FastAPI)의 런타임을 모두 갖췄습니다. 이제 이 서비스들이 실제로 대화할 데이터베이스, 오브젝트 스토리지, 자동화 엔진 같은 인프라 컴포넌트를 올려야 합니다.
이런 인프라를 윈도우에 하나하나 네이티브로 설치할 수도 있지만, 컨테이너로 올리면 세 가지가 편해집니다.
첫째, 설치와 삭제가 깔끔합니다. 컨테이너를 지우면 흔적이 남지 않습니다. 둘째, 팀원이 같은 docker-compose.yml 하나로 동일한 환경을 재현할 수 있습니다. 셋째, 나중에 리눅스 서버에 배포할 때도 거의 같은 Compose 파일을 그대로 사용할 수 있습니다.
이번 편에서는 Docker Desktop을 설치하고, 컨테이너·이미지·볼륨을 다루는 기본 명령어를 익힌 뒤, Docker Compose로 여러 컨테이너를 한 번에 띄우는 방법까지 다룹니다. 8편부터는 이 위에 PostgreSQL, MinIO, n8n을 차례로 올릴 예정이니, 이번 편에서 기초를 확실히 잡아 두겠습니다.
1. Docker Desktop 설치
1-1. 사전 요구 사항 확인
Docker Desktop은 내부적으로 WSL 2 백엔드 또는 Hyper-V 백엔드를 사용합니다. 최신 버전은 설치 시 WSL 2 커널을 자동으로 구성해 주므로 별도로 WSL 배포판을 설치하거나 WSL 터미널에 들어갈 필요가 없습니다. 우리가 지키는 원칙—"사용자가 WSL 터미널에 직접 들어가지 않는다"—과 충돌하지 않습니다. Docker 명령은 전부 PowerShell에서 실행합니다.
하드웨어 가상화(VT-x / AMD-V)가 BIOS에서 켜져 있어야 합니다. 대부분의 최신 PC는 기본으로 활성화돼 있지만, 설치 후 Docker가 시작되지 않으면 BIOS에서 이 항목을 확인하세요.
1-2. winget으로 설치
PowerShell 7을 관리자 권한으로 열고 아래 명령을 실행합니다.
winget install -e --id Docker.DockerDesktop
설치가 끝나면 재부팅을 요구할 수 있습니다. 재부팅 안내가 나오면 반드시 재부팅하세요.
1-3. 첫 실행 & 초기 설정
재부팅 후 Docker Desktop이 자동 시작됩니다. 시스템 트레이에 고래 아이콘이 나타나고, 상태가 "Docker Desktop is running"으로 바뀌면 준비 완료입니다.
첫 실행 시 라이선스 동의 화면이 나옵니다. 개인 사용자 또는 소규모 팀(직원 250명 미만, 연매출 1,000만 달러 미만)은 무료 Personal 플랜으로 사용할 수 있습니다. 회사 규모가 이를 초과한다면 유료 구독이 필요하니 확인하세요.
Settings → General에서 다음 두 가지를 확인합니다.
Use the WSL 2 based engine 항목이 체크돼 있는지 확인합니다. 이것은 Docker 엔진의 백엔드를 WSL 2 위에서 돌린다는 뜻이며, 사용자가 WSL 터미널에 진입하는 것과는 관계없습니다. 성능이 좋으므로 켜 두세요.
Start Docker Desktop when you sign in to Windows 항목은 개발 중이라면 켜 두는 편이 편합니다. 리소스가 아까우면 꺼도 됩니다.
1-4. 설치 확인
PowerShell에서 버전을 확인합니다.
docker --version
Docker version 27.x.x, build xxxxxxx
docker compose version
Docker Compose version v2.x.x
두 명령 모두 버전이 출력되면 정상입니다. docker compose는 Docker Desktop에 포함된 Compose V2 플러그인이므로 별도 설치가 필요 없습니다. 과거의 docker-compose(하이픈) 명령 대신 docker compose(스페이스)를 사용합니다.
2. Hello World로 동작 확인
Docker가 실제로 컨테이너를 만들고 실행할 수 있는지 확인합니다.
docker run hello-world
아래와 비슷한 메시지가 출력되면 성공입니다.
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
이 명령이 실행되면서 내부적으로 일어나는 일을 순서대로 정리하면 다음과 같습니다. 먼저 로컬에 hello-world 이미지가 없으므로 Docker Hub에서 이미지를 다운로드(pull)합니다. 그 이미지로 컨테이너를 생성하고 실행합니다. 컨테이너 안의 프로그램이 메시지를 출력한 뒤 종료됩니다. 이 흐름—"이미지 → 컨테이너 → 실행 → 종료"—이 Docker의 기본 라이프사이클입니다.
3. 핵심 개념 세 가지: 이미지, 컨테이너, 볼륨
본격적으로 명령어를 다루기 전에, 앞으로 계속 만날 세 가지 개념을 짚고 넘어갑니다.
이미지(Image)는 실행 환경을 담은 읽기 전용 템플릿입니다. "PostgreSQL 16이 설치된 리눅스 환경"처럼 특정 소프트웨어와 설정이 스냅샷으로 굳어진 상태라고 보면 됩니다. Docker Hub 같은 레지스트리에서 내려받거나, Dockerfile을 작성해서 직접 빌드할 수 있습니다.
컨테이너(Container)는 이미지를 바탕으로 실제 실행되는 인스턴스입니다. 하나의 이미지에서 여러 컨테이너를 만들 수 있고, 각 컨테이너는 서로 격리된 파일 시스템과 네트워크를 가집니다. 컨테이너를 삭제하면 그 안에서 변경된 데이터도 함께 사라집니다.
볼륨(Volume)은 컨테이너가 사라져도 데이터를 유지할 수 있게 해 주는 저장 공간입니다. 데이터베이스 파일, 업로드된 파일 등 영속적으로 보관해야 하는 데이터는 반드시 볼륨에 저장해야 합니다. 볼륨을 연결하지 않으면 컨테이너를 지울 때 데이터도 전부 날아갑니다.
4. 이미지 관련 명령어
이미지 검색
docker search nginx
Docker Hub에서 nginx 관련 이미지를 검색합니다. STARS 수와 OFFICIAL 여부를 참고해서 신뢰할 수 있는 이미지를 고릅니다.
이미지 다운로드
docker pull nginx:latest
태그(:latest)를 생략하면 자동으로 latest가 적용됩니다. 프로덕션에서는 nginx:1.27 같이 구체적인 버전 태그를 쓰는 것이 좋습니다. latest는 언제 어떤 버전으로 바뀔지 모르기 때문입니다.
로컬 이미지 목록 확인
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest a8758716bb6a 2 weeks ago 187MB
hello-world latest d2c94e258dcb 12 months ago 13.3kB
이미지 삭제
docker rmi nginx:latest
해당 이미지로 만든 컨테이너가 아직 남아 있으면 삭제가 거부됩니다. 컨테이너를 먼저 지우거나 -f 플래그를 붙여야 합니다.
사용하지 않는 이미지 일괄 정리
docker image prune -a
현재 어떤 컨테이너에서도 사용하지 않는 이미지를 전부 삭제합니다. 디스크 공간을 확보할 때 유용합니다.
5. 컨테이너 관련 명령어
컨테이너 실행
docker run -d --name my-nginx -p 8080:80 nginx:latest
각 옵션의 의미는 다음과 같습니다. -d는 백그라운드(detached) 실행입니다. --name my-nginx는 컨테이너에 이름을 붙여서 나중에 다루기 쉽게 합니다. -p 8080:80은 호스트(윈도우)의 8080 포트를 컨테이너 내부의 80 포트에 연결합니다.
이제 브라우저에서 http://localhost:8080을 열면 Nginx 환영 페이지가 보입니다.
실행 중인 컨테이너 목록
docker ps
모든 컨테이너 목록 (중지된 것 포함)
docker ps -a
컨테이너 로그 확인
docker logs my-nginx
실시간으로 로그를 따라가려면 -f 플래그를 추가합니다.
docker logs -f my-nginx
컨테이너 중지 & 시작
docker stop my-nginx
docker start my-nginx
컨테이너 삭제
docker stop my-nginx
docker rm my-nginx
실행 중인 컨테이너를 바로 지우고 싶으면 docker rm -f my-nginx를 사용할 수 있습니다.
중지된 컨테이너 일괄 정리
docker container prune
6. 볼륨 관련 명령어
볼륨 생성
docker volume create my-data
볼륨 목록 확인
docker volume ls
볼륨을 연결해서 컨테이너 실행
docker run -d --name my-nginx -p 8080:80 -v my-data:/usr/share/nginx/html nginx:latest
-v my-data:/usr/share/nginx/html은 my-data 볼륨을 컨테이너 내부의 /usr/share/nginx/html 경로에 마운트합니다. 컨테이너를 삭제하고 다시 만들어도 볼륨에 저장된 파일은 그대로 남습니다.
볼륨 삭제
docker volume rm my-data
사용하지 않는 볼륨 일괄 정리
docker volume prune
볼륨을 지우면 안에 있던 데이터도 영구적으로 삭제되므로 주의하세요.
7. Docker Compose — 여러 컨테이너를 한 번에 관리하기
지금까지 docker run 명령으로 하나씩 컨테이너를 띄웠습니다. 하지만 실제 프로젝트에서는 웹 서버, 데이터베이스, 캐시 등 여러 컨테이너가 함께 돌아갑니다. 이걸 매번 긴 docker run 명령을 하나하나 입력해서 관리하는 것은 비현실적입니다.
Docker Compose는 docker-compose.yml(또는 compose.yml) 파일에 필요한 컨테이너들의 설정을 선언하고, 명령어 하나로 전부 띄우거나 내릴 수 있게 해 줍니다.
7-1. 실습: Nginx + Redis 구성
간단한 예제로 Compose의 흐름을 익혀 보겠습니다. 적당한 위치에 실습 폴더를 만듭니다.
mkdir ~/docker-practice
cd ~/docker-practice
docker-compose.yml 파일을 생성합니다.
# docker-compose.yml
services:
web:
image: nginx:latest
ports:
- "8080:80"
depends_on:
- cache
cache:
image: redis:alpine
ports:
- "6379:6379"
이 파일이 담고 있는 내용을 설명하겠습니다. services 아래에 web과 cache 두 개의 서비스를 정의했습니다. web은 Nginx를 8080 포트로 노출하고, cache는 Redis를 6379 포트로 노출합니다. depends_on은 web이 cache보다 나중에 시작되도록 순서를 지정합니다. Compose가 자동으로 같은 네트워크를 만들어 주기 때문에 컨테이너끼리는 서비스 이름(web, cache)으로 서로를 찾을 수 있습니다.
7-2. Compose 기본 명령어
해당 폴더에서 실행합니다.
모든 서비스 시작 (백그라운드)
docker compose up -d
처음 실행하면 이미지를 다운로드한 뒤 컨테이너를 생성·시작합니다. 아래와 비슷한 출력을 볼 수 있습니다.
[+] Running 3/3
✔ Network docker-practice_default Created
✔ Container docker-practice-cache-1 Started
✔ Container docker-practice-web-1 Started
서비스 상태 확인
docker compose ps
NAME IMAGE ... STATUS PORTS
docker-practice-cache-1 redis:alpine ... Up 30 seconds 0.0.0.0:6379->6379/tcp
docker-practice-web-1 nginx:latest ... Up 30 seconds 0.0.0.0:8080->80/tcp
로그 확인
docker compose logs
특정 서비스의 로그만 보려면 서비스 이름을 뒤에 붙입니다.
docker compose logs cache
모든 서비스 중지
docker compose stop
컨테이너가 중지되지만 삭제되지는 않습니다. docker compose start로 다시 시작할 수 있습니다.
모든 서비스 중지 + 컨테이너 삭제 + 네트워크 삭제
docker compose down
볼륨까지 함께 삭제하고 싶으면 -v 플래그를 추가합니다.
docker compose down -v
yml 수정 후 반영
docker-compose.yml을 수정한 뒤 다시 docker compose up -d를 실행하면 변경된 서비스만 재생성됩니다. 전체를 처음부터 다시 빌드하고 싶으면 --force-recreate 플래그를 사용합니다.
7-3. 동작 확인
브라우저에서 http://localhost:8080을 열어 Nginx 환영 페이지가 나타나는지 확인합니다.
Redis도 확인해 봅니다. PowerShell에서 아래 명령으로 컨테이너 안의 redis-cli를 실행할 수 있습니다.
docker exec -it docker-practice-cache-1 redis-cli ping
PONG
PONG이 돌아오면 Redis도 정상입니다. 여기서 docker exec는 실행 중인 컨테이너 안에서 명령어를 실행하는 명령입니다. WSL에 들어가는 것이 아니라 PowerShell에서 컨테이너에게 명령을 보내는 것이므로 우리의 원칙에 위배되지 않습니다.
7-4. 실습 정리
확인이 끝났으면 깔끔하게 정리합니다.
docker compose down
8. 자주 쓰는 정리 명령어 모음
개발하다 보면 이미지, 중지된 컨테이너, 사용하지 않는 볼륨이 쌓여서 디스크를 차지합니다. 다음 명령어들을 알아 두면 유용합니다.
전체 한 방 정리 (주의: 사용하지 않는 것을 전부 삭제)
docker system prune -a --volumes
이 명령은 중지된 컨테이너, 사용하지 않는 네트워크, 태그 없는 이미지, 연결되지 않은 볼륨을 한꺼번에 삭제합니다. 필요한 데이터가 날아갈 수 있으니 확인 후 실행하세요.
디스크 사용량 확인
docker system df
어떤 항목이 얼마나 공간을 차지하는지 한눈에 볼 수 있습니다.
9. Docker Desktop GUI 간단 안내
Docker Desktop은 GUI 대시보드도 제공합니다. 시스템 트레이의 고래 아이콘을 더블 클릭하면 열립니다.
Containers 탭에서 실행 중인 컨테이너를 확인하고, 로그를 보거나 중지·삭제할 수 있습니다. Images 탭에서 로컬에 저장된 이미지를 관리할 수 있습니다. Volumes 탭에서 볼륨 목록을 확인하고 삭제할 수 있습니다.
커맨드라인이 익숙하지 않은 분은 GUI로 상태를 확인하면서 작업하면 편합니다. 이 시리즈에서는 재현 가능성과 정확성을 위해 모든 조작을 CLI 명령어로 안내하지만, GUI에서 같은 작업을 할 수 있다는 것도 알아 두세요.
최종 확인 체크리스트
아래 항목을 모두 확인했다면 7편은 완료입니다.
✅ Docker Desktop이 정상 실행된다 (시스템 트레이 고래 아이콘 확인)
✅ docker --version 이 버전 정보를 출력한다
✅ docker compose version 이 버전 정보를 출력한다
✅ docker run hello-world 가 성공 메시지를 출력한다
✅ docker-compose.yml로 Nginx + Redis를 띄우고 접속할 수 있다
✅ docker compose down 으로 깔끔하게 정리할 수 있다
다음 편 예고
Docker의 기본 사용법을 익혔으니, 이제 실제 프로젝트에 필요한 인프라를 올릴 차례입니다. 8편: PostgreSQL 컨테이너 설정에서는 Docker Compose로 PostgreSQL을 구동하고, 초기 데이터베이스와 사용자를 생성한 뒤, DBeaver에서 접속을 확인합니다. 그리고 5편에서 만든 Go(Gin) 서버와 6편에서 만든 Python(FastAPI) 서버가 PostgreSQL에 연결되는 것까지 테스트해 보겠습니다.
'Windows 개발환경 세팅' 카테고리의 다른 글
| [윈도우 개발 환경 설정] 9편: MinIO 컨테이너 설정 (0) | 2026.03.31 |
|---|---|
| [윈도우 개발 환경 설정] 8편: PostgreSQL 컨테이너 설정 (0) | 2026.03.31 |
| [윈도우 개발 환경 설정] 6편: Python & FastAPI 환경 구축 (0) | 2026.03.31 |
| [윈도우 개발 환경 설정] 5편: Go & Gin 환경 구축 (0) | 2026.03.31 |
| [윈도우 개발 환경 설정] 4편: Node.js & React SPA 환경 구축 (0) | 2026.03.31 |