본문 바로가기
Docker + CI,CD/Docker

Docker 완벽 가이드: 컨테이너 기반 개발 환경 구축하기

by JuNo_12 2025. 10. 21.

Docker란 무엇인가?

Docker는 애플리케이션을 컨테이너라는 경량화된 패키지로 실행할 수 있게 해주는 플랫폼입니다. 애플리케이션 실행에 필요한 코드, 런타임, 시스템 도구, 라이브러리를 모두 포함하여 어디서든 동일한 환경에서 실행할 수 있습니다.

 

핵심 특징

컨테이너화 애플리케이션과 의존성을 하나의 패키지로 묶어 환경에 구애받지 않고 실행할 수 있습니다. 개발 환경에서 테스트한 애플리케이션을 운영 환경에 그대로 배포할 수 있죠.

경량성 가상 머신과 달리 운영체제 커널을 공유하기 때문에 시작 시간이 빠르고 리소스 사용량이 적습니다.

이식성 한 번 빌드한 이미지는 Docker가 설치된 어떤 환경에서도 동일하게 동작합니다.


핵심 개념 이해하기

이미지(Image)

애플리케이션 실행에 필요한 모든 요소를 포함한 읽기 전용 템플릿입니다. 컨테이너를 생성하기 위한 청사진 역할을 합니다.

컨테이너(Container)

이미지를 실행한 인스턴스입니다. 격리된 환경에서 애플리케이션이 실행되며, 하나의 시스템에서 여러 컨테이너를 독립적으로 실행할 수 있습니다.

Dockerfile

이미지를 생성하기 위한 스크립트 파일입니다. 이미지 빌드 과정을 자동화하고 일관되게 만들어줍니다.

볼륨(Volume)

컨테이너의 데이터를 영구적으로 저장하는 메커니즘입니다. 컨테이너가 삭제되어도 볼륨의 데이터는 유지됩니다.

네트워크(Network)

컨테이너 간 통신을 관리합니다. Docker는 다양한 네트워크 드라이버를 제공합니다.

브리지 네트워크 Docker의 기본 네트워크 방식입니다. 동일한 브리지 네트워크에 연결된 컨테이너들은 서로 통신할 수 있으며, 외부와는 NAT를 통해 통신합니다.

호스트 네트워크 컨테이너가 호스트의 네트워크를 직접 사용합니다. 성능상 이점이 있지만 격리가 없어 보안 위험이 있습니다.

오버레이 네트워크 여러 Docker 호스트에 걸쳐 있는 컨테이너를 연결할 때 사용합니다. Kubernetes 같은 오케스트레이션 도구와 함께 사용됩니다.


Docker vs 가상 머신

Docker의 강점

  • 빠른 시작 시간과 낮은 오버헤드
  • 뛰어난 이식성과 확장성
  • 효율적인 리소스 활용

Docker의 한계

  • 가상 머신 대비 약한 보안 격리
  • Linux 커널 의존성으로 인한 운영체제 제약

가상 머신의 특징

  • 완전히 격리된 환경 제공
  • 다양한 운영체제 동시 실행 가능
  • 높은 리소스 소비와 느린 부팅 시간

Docker를 사용해야 하는 경우

  • 일관된 개발 환경 구축 개발, 테스트, 운영 환경 간의 차이로 인한 문제를 해결할 수 있습니다.
  • 빠른 배포 이미지 빌드 후 즉시 실행 가능하여 배포 시간을 단축할 수 있습니다.
  • 마이크로서비스 아키텍처 각 서비스를 독립적으로 배포하고 관리할 수 있습니다.
  • CI/CD 파이프라인 자동화된 빌드, 테스트, 배포 파이프라인 구축에 적합합니다.
  • 리소스 효율성 동일한 하드웨어에서 더 많은 애플리케이션을 실행할 수 있습니다.

필수 Docker 명령어

이미지 관리

# Docker Hub에서 이미지 가져오기
docker pull postgres

# 이미지 빌드
docker build -t myapp:latest .

# 로컬 이미지 목록 조회
docker images

# 이미지 삭제
docker rmi myapp:latest

컨테이너 관리

# 컨테이너 실행 (백그라운드)
docker run -d -p 8080:80 myapp:latest

# 실행 중인 컨테이너 조회
docker ps

# 모든 컨테이너 조회 (중지된 컨테이너 포함)
docker ps -a

# 컨테이너 내부 접속
docker exec -it <container_id> /bin/bash

# 컨테이너 중지/시작
docker stop <container_id>
docker start <container_id>

# 컨테이너 삭제
docker rm <container_id>

네트워크 및 볼륨 관리

# 네트워크 생성/조회/삭제
docker network create mynetwork
docker network ls
docker network rm mynetwork

# 볼륨 생성/조회/삭제
docker volume create myvolume
docker volume ls
docker volume rm myvolume

실전 예제: PostgreSQL 컨테이너 실행하기

# PostgreSQL 이미지 가져오기
docker pull postgres

# 컨테이너 실행
docker run -d --name postgres-sample \
  -p 5433:5432 \
  -e POSTGRES_USER=admin \
  -e POSTGRES_PASSWORD=password \
  -e PGDATA=/var/lib/postgresql/data/pgdata \
  -v ${로컬_폴더_경로}:/var/lib/postgresql/data:z \
  postgres

Docker Compose로 멀티 컨테이너 관리하기

여러 컨테이너를 함께 관리해야 할 때 Docker Compose를 사용합니다.

사용자 정의 네트워크 생성

docker network create my-network

Service-b 컨테이너 실행

# 프로젝트 빌드
./gradlew clean bootJar

# Docker 이미지 생성
docker build -t img-service-b .

# 컨테이너 실행
docker run -d --name service-b \
  --network my-network \
  -p 18081:8080 \
  img-service-b

Docker Compose 파일 작성

version: '3.8'
services:
  service-a:
    image: img-service-a
    ports:
      - "18080:8080"
    environment:
      - SERVICE_B_URL=http://service-b:8080
    depends_on:
      - service-b
      
  service-b:
    image: img-service-b
    ports:
      - "18081:8080"

networks:
  default:
    driver: bridge

실행 및 확인

# Docker Compose 실행
docker compose up -d

# 네트워크 확인
docker network ls

Docker Compose는 자동으로 <디렉토리명>_default 형식의 브리지 네트워크를 생성하여 모든 서비스 컨테이너를 연결합니다. 같은 네트워크 내의 컨테이너들은 서비스 이름으로 서로를 호출할 수 있습니다.


마치며

Docker는 현대적인 애플리케이션 개발과 배포에 필수적인 도구입니다. 컨테이너 기반 개발은 일관된 환경 제공, 빠른 배포, 효율적인 리소스 활용이라는 장점을 제공합니다.