
이 글에서 다루는 내용
Docker를 처음 설치하고 첫 컨테이너를 실행하는 흐름부터, 이미지 빌드와 docker compose로 여러 서비스를 한 번에 띄우는 단계까지 정리합니다. 서버에 직접 패키지를 설치하는 방식이 아닌 컨테이너 기반 개발로 넘어가려는 개발자에게 맞춘 실무 가이드입니다.
1. Docker 설치
1-1. Ubuntu / WSL2
sudo apt update
sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
1-2. 현재 사용자에게 권한 부여
sudo usermod -aG docker $USER
newgrp docker
docker run hello-world
1-3. macOS / Windows
공식 Docker Desktop을 설치하는 것이 가장 간단합니다. 다만 상업 라이선스 조건(사내 규모에 따른 유료화)이 있으므로 회사 환경에서는 사전 확인이 필요합니다.
⚠️ 라이선스 이슈를 피하려면 macOS에선
colima, Windows에선 WSL2 내부 Docker Engine 조합이 무료 대안입니다.
2. 핵심 개념 정리
| 개념 | 한줄 설명 |
|---|---|
| 이미지(Image) | 컨테이너를 만들기 위한 읽기 전용 템플릿 |
| 컨테이너(Container) | 이미지를 실행한 살아있는 프로세스 |
| 볼륨(Volume) | 컨테이너와 별도로 보관되는 데이터 |
| 네트워크 | 컨테이너들 간 통신 경로 |
| 레지스트리 | 이미지를 저장·공유하는 저장소 (Docker Hub, GHCR 등) |
"이미지는 클래스, 컨테이너는 인스턴스"라는 비유가 이해에 도움이 됩니다.
3. 첫 컨테이너 실행
3-1. Nginx 띄우기
docker run -d --name web -p 8080:80 nginx
옵션 해석은 다음과 같습니다.
-d: 백그라운드 실행--name web: 컨테이너 이름 지정-p 8080:80: 호스트 8080 포트를 컨테이너 80 포트로 포워드
이제 브라우저에서 http://localhost:8080을 열면 Nginx 기본 페이지가 보입니다.
3-2. 상태 확인과 정리
docker ps # 실행 중 컨테이너
docker ps -a # 종료된 것 포함
docker logs web # 로그 확인
docker stop web
docker rm web
4. Dockerfile로 이미지 만들기
4-1. FastAPI 샘플
app.py:
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
def read_root():
return {"hello": "docker"}
requirements.txt:
fastapi==0.110.0
uvicorn==0.27.1
Dockerfile:
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]
4-2. 빌드와 실행
docker build -t my-api:0.1 .
docker run -d --name api -p 8000:8000 my-api:0.1
curl http://localhost:8000
예상 응답
{"hello":"docker"}
💡 이미지 용량을 줄이고 싶다면
slim대신alpine베이스, 또는 멀티스테이지 빌드를 적용합니다. 다만 Python + alpine 조합은 glibc 호환 문제로 의존성 빌드가 깨질 수 있어 초보 단계에서는slim이 무난합니다.
5. docker compose로 여러 서비스 묶기
5-1. compose.yml
API + Redis 조합 예시입니다.
services:
api:
build: .
ports:
- "8000:8000"
depends_on:
- cache
environment:
REDIS_URL: redis://cache:6379
cache:
image: redis:7-alpine
volumes:
- cache_data:/data
volumes:
cache_data:
5-2. 실행
docker compose up -d
docker compose ps
docker compose logs -f api
docker compose down
여러 컨테이너를 한꺼번에 올리고 내리는 데 이만큼 편한 도구가 없습니다.
6. 자주 쓰는 패턴
# 로컬 파일을 컨테이너에 실시간 반영 (개발용)
docker run -it -v $(pwd):/app -w /app python:3.12-slim bash
# 이미지 정리
docker image prune -f
docker system prune -a # 주의: 전부 삭제
# 컨테이너 안으로 접속
docker exec -it api bash
트러블슈팅
문제 1: permission denied while trying to connect to the Docker daemon
docker 그룹에 소속돼 있지 않은 경우입니다.
sudo usermod -aG docker $USER
newgrp docker
로그아웃·재로그인이 필요할 수 있습니다.
문제 2: 포트가 이미 사용 중
bind: address already in use
sudo lsof -i :8080
다른 포트로 바꾸거나 기존 프로세스를 종료합니다.
문제 3: WSL에서 컨테이너가 종료되지 않음
Windows에서 Docker Desktop 종료 시 WSL 내부 프로세스가 멈추는 경우가 있습니다. 이때는 wsl --shutdown 후 재시작하면 깔끔해집니다.
문제 4: 이미지가 너무 큼
.dockerignore에 .git, __pycache__, .venv 같은 항목을 꼭 추가합니다. 의외로 이 한 줄로 수백 MB가 줄어드는 경우가 많습니다.
마무리
Docker는 처음엔 "VM의 경량 버전"처럼 느껴지지만, 실제로는 "실행 환경을 한 파일로 고정하는 약속"에 가깝습니다. 한 번 익히면 어떤 언어·어떤 프레임워크든 "이 저장소만 받아 compose up 하면 됩니다"라는 말이 통용됩니다. 서버·개인 PC·CI 모두에서 동일한 환경을 재현할 수 있는 점이 가장 큰 가치입니다.
- 공식 문서: https://docs.docker.com
- 관련 글: WSL2 설치와 Ubuntu 초기 세팅
태그: #Docker #도커 #컨테이너 #Dockerfile #compose #인프라 #개발환경 #이미지 #DevOps #2026
'개발환경 & 도구' 카테고리의 다른 글
| Google Antigravity 설치 가이드 - Windows·macOS 단계별 따라하기 (0) | 2026.05.05 |
|---|---|
| Linux 기본 명령어 실무 정리 (1) | 2026.04.26 |
| Git 초보 탈출 — 실무에서 쓰는 명령어 정리 (1) | 2026.04.22 |
| VS Code 개발 환경 최적화 세팅 (2) | 2026.04.19 |
| Python 가상환경 Anaconda 완벽 정리 (1) | 2026.04.19 |