본문 바로가기
개발환경 & 도구

Docker 설치부터 컨테이너 실행까지

by 코드파일럿 2026. 4. 26.

Docker 설치부터 컨테이너 실행까지

이 글에서 다루는 내용

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 모두에서 동일한 환경을 재현할 수 있는 점이 가장 큰 가치입니다.

 


태그: #Docker #도커 #컨테이너 #Dockerfile #compose #인프라 #개발환경 #이미지 #DevOps #2026