Bootcamp/Fundamentals

Docker와 Docker Compose

개발자 오리 2026. 7. 21. 15:31

💡  오늘 학습 키워드

  • Docker
  • Docker Compose

 

 

🎯  학습 내용 정리

1. Docker

개발을 하다 보면 가장 자주 발생하는 문제 중 하나가 환경 차이(Environment Difference) 이다.

개발자의 PC에서는 정상적으로 실행되던 애플리케이션이 테스트 서버나 운영 서버에서는 실행되지 않는 경우가 자주 발생한다. 운영체제, 라이브러리 버전, 런타임 환경 등이 서로 다르기 때문이다.

 

Docker는 이러한 문제를 해결하기 위해 등장한 컨테이너 기반 가상화 플랫폼이다.

애플리케이션과 실행에 필요한 모든 요소를 하나의 이미지(Image)로 만들고, 이를 컨테이너(Container) 형태로 실행하여 어느 환경에서든 동일한 실행 결과를 보장한다.

 

기존의 가상 머신(VM)처럼 운영체제를 통째로 올리는 것이 아니라 호스트 운영체제의 커널을 공유하기 때문에 매우 가볍고 실행 속도가 빠르다.

 

대표적인 특징은 다음과 같다.

  • 환경에 관계없이 동일하게 실행 가능
  • 빠른 실행 속도
  • 적은 리소스 사용
  • 쉬운 배포
  • 높은 확장성

 

 

Docker를 이해하기 위해 반드시 알아야 하는 개념들이 있다.

 

Image

Image는 컨테이너를 생성하기 위한 설계도이다.

애플리케이션 실행에 필요한 코드, 라이브러리, 런타임, 설정 파일 등을 모두 포함하고 있는 읽기 전용 템플릿이다.

컨테이너는 항상 이미지로부터 생성된다.

 

Container

Container는 이미지를 실제로 실행한 상태이다.

이미지가 설계도라면 컨테이너는 실제 실행 중인 프로그램이라고 볼 수 있다.

동일한 이미지로 여러 개의 컨테이너를 생성할 수도 있으며 서로 독립적으로 동작한다.

 

Dockerfile

Dockerfile은 이미지를 생성하기 위한 스크립트이다.

Dockerfile 내부에는 이미지 생성 과정이 순서대로 작성된다.

예를 들어 다음과 같은 Dockerfile은 Spring Boot 애플리케이션을 실행하는 이미지를 생성한다.

FROM eclipse-temurin:17-jre

COPY build/libs/*.jar app.jar

ENTRYPOINT ["java","-jar","/app.jar"]

 

Docker Hub

Docker Hub는 Docker 이미지 저장소이다.

공개 이미지(PostgreSQL, Redis, Nginx, MySQL 등)를 내려받거나 자신이 만든 이미지를 업로드하여 공유할 수 있다.

예를 들어 PostgreSQL 이미지는 다음 명령어로 받을 수 있다.

docker pull postgres

 

 

Volume

컨테이너는 삭제되면 내부 데이터도 함께 사라진다.

이를 해결하기 위해 사용하는 것이 Volume이다.

Volume을 사용하면 컨테이너가 삭제되어도 데이터는 유지된다.

대표적으로 데이터베이스(PostgreSQL, MySQL)의 데이터를 저장할 때 사용된다.

 

Network

Docker 컨테이너들은 네트워크를 통해 서로 통신한다.

대표적인 네트워크 종류는 다음과 같다.

 

Bridge Network

가장 많이 사용하는 기본 네트워크이다.

같은 Bridge Network에 연결된 컨테이너들은 컨테이너 이름으로 서로 통신할 수 있다.

docker network create my-network

 

 

Host Network

호스트의 네트워크를 그대로 사용한다.

네트워크 성능은 좋지만 컨테이너 격리가 사라진다.

 

Overlay Network

여러 Docker Host에 걸쳐 컨테이너를 연결하는 네트워크이다.

Docker Swarm이나 Kubernetes에서 많이 사용된다.

 

 

Docker와 VM은 모두 애플리케이션을 실행하기 위한 가상화 기술이지만 구조가 다르다.

Docker Virtual Machine
커널 공유 운영체제 포함
가볍다 무겁다
빠르게 실행 부팅 시간이 길다
리소스 사용이 적다 리소스 사용이 많다
확장이 쉽다 확장이 어렵다

Docker는 운영체제를 공유하기 때문에 성능과 효율성이 뛰어나지만, VM에 비해 격리 수준은 다소 낮다.

 

 

그렇다면 Docker는 언제 사용할까?

Docker는 다음과 같은 상황에서 매우 효과적이다.

  • 개발 환경과 운영 환경을 동일하게 유지하고 싶을 때
  • 빠른 배포가 필요할 때
  • CI/CD 파이프라인을 구축할 때
  • 마이크로서비스(MSA)를 구성할 때
  • 여러 서비스를 독립적으로 실행할 때
  • Kubernetes 환경에서 서비스를 운영할 때

 

 

상황별로 자주 사용하는 Docker 명령어를 정리해보면 다음과 같다.

 

이미지

이미지 생성

# 이미지 생성
docker build -t myapp .

# 이미지 다운로드
docker pull postgres

# 이미지 조회
docker images

# 이미지 삭제
docker rmi myapp

 

 

 

컨테이너

# 컨테이너 실행
docker run -d -p 8080:80 myapp

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

# 전체 컨테이너 조회
docker ps -a

# 컨테이너 접속
docker exec -it 컨테이너ID /bin/bash

# 컨테이너 중지
docker stop 컨테이너ID

# 컨테이너 삭제
docker rm 컨테이너ID

 

 

네트워크

# 네트워크 생성
docker network create my-network

# 네트워크 조회
docker network ls

# 네트워크 삭제
docker network rm my-network

 

볼륨

# 볼륨 생성
docker volume create my-volume

# 볼륨 조회
docker volume ls

# 볼륨 삭제
docker volume rm my-volume

 

 

 

2. Docker Compose

실제 서비스에서는 하나의 컨테이너만 사용하는 경우는 거의 없다.

예를 들어 Spring Boot 프로젝트를 운영한다고 가정하면 다음과 같은 컨테이너가 함께 실행된다.

  • Spring Boot
  • PostgreSQL
  • Redis
  • Nginx

각 컨테이너를 docker run으로 하나씩 실행하는 것은 매우 번거롭다.

이를 해결하기 위해 사용하는 것이 Docker Compose이다.

Docker Compose는 여러 컨테이너를 하나의 docker-compose.yml 파일에서 정의하고 함께 실행할 수 있도록 해준다.

 

 

Docker Compose를 사용하면 다음과 같은 장점이 있다.

  • 여러 컨테이너를 한 번에 실행 가능
  • 네트워크 자동 생성
  • 볼륨 자동 연결
  • 환경 변수 관리 가능
  • 서비스 의존성 설정 가능
  • 프로젝트 전체를 하나의 파일로 관리 가능

 

 

docker-compose.yml 구조의 가장 기본적인 형태는 다음과 같다.

services:
  app:
    build: .
    ports:
      - "8080:8080"

  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: example

 

주요 항목은 다음과 같다.

항목 설명
services 실행할 컨테이너 정의
image 사용할 이미지
build Dockerfile을 이용해 이미지 생성
ports 포트 매핑
environment 환경 변수
depends_on 서비스 실행 순서
volumes 데이터 저장소 연결
networks 컨테이너 네트워크

 

 

자주 사용하는 Docker Compose 주요 명령어를 정리해보면 다음과 같다.

# 서비스 실행
docker compose up -d

# 서비스 종료
docker compose down

# 이미지 빌드
docker compose build

# 실행 중인 서비스 조회
docker compose ps

# 로그 확인
docker compose logs

이 중에서도 실행과 종료를 주로 사용하며, 이미지 빌드와 실행 중인 서비스 조회, 로그 확인 등의 명령어는 이러한 명령어가 있다는 것을 알아두는 정도로도 충분하다.

 

 

Docker의 네트워크 기능을 이용하면 컨테이너 이름으로 서로 통신할 수 있다.

 

예를 들어 다음과 같이 두 개의 Spring Boot 서비스를 구성할 수 있다.

service-a:8080
  |
Feign Client
  ↓
service-b:8081

 

기존 로컬 환경에서는 다음과 같이 호출한다.

service.b.url=http://localhost:8081

 

하지만 Docker에서는 컨테이너 이름을 사용할 수 있다.

service.b.url=http://service-b:8080

이처럼 Docker Network에서는 DNS가 자동으로 제공되기 때문에 컨테이너 이름만으로도 통신이 가능하다.

 

 

Docker Compose로 실행하기

서비스를 각각 실행하는 대신 하나의 Compose 파일만 작성하면 된다.

services:
  service-a:
    image: img-service-a
    ports:
      - "8080:8080"
    depends_on:
      - service-b

  service-b:
    image: img-service-b
    ports:
      - "8081:8080"

 

이후 아래 명령어 하나만 실행하면 된다.

docker compose up -d

 

Compose는 자동으로

  • 네트워크 생성
  • 컨테이너 생성
  • 서비스 실행
  • 서비스 간 연결

까지 모두 처리해 준다.

또한 프로젝트를 종료할 때도 다음 명령어 하나면 된다.

docker compose down

 

 

 

Docker Compose를 실행하면 별도로 네트워크를 생성하지 않아도 자동으로 Bridge Network가 만들어진다.

네트워크 이름은 일반적으로 다음과 같은 형태로 생성된다.

프로젝트명_default

 

이를 통해 같은 Compose 파일에 정의된 서비스들은 모두 같은 네트워크에 연결되며, 컨테이너 이름으로 자유롭게 통신할 수 있다.

예를 들어 service-a에서는 다음과 같이 service-b를 호출할 수 있다.

service.b.url=http://service-b:8080

 

 

별도의 IP 주소를 관리할 필요가 없으며, 컨테이너가 재생성되어 IP가 변경되더라도 서비스 이름은 그대로 유지되므로 안정적으로 통신할 수 있다.

 

 

Docker는 애플리케이션과 실행 환경을 하나의 컨테이너로 패키징하여 어디서나 동일한 실행 환경을 제공하는 플랫폼이다. 개발 환경과 운영 환경의 차이를 줄이고, 빠른 배포와 높은 이식성을 제공한다.

Docker Compose는 이러한 여러 컨테이너를 하나의 설정 파일로 관리하는 도구이다. 복잡한 서비스 구성을 간단하게 만들고, 네트워크와 볼륨을 자동으로 구성하며, 여러 서비스를 한 번의 명령으로 실행하고 종료할 수 있게 해준다.

 

실무에서는 Spring Boot, PostgreSQL, Redis, Nginx 등을 함께 사용하는 경우가 많기 때문에 Docker와 Docker Compose는 함께 사용하는 것이 일반적이며, 이후 Kubernetes와 같은 컨테이너 오케스트레이션 환경으로 확장하는 기반 기술로도 활용된다.

 

 

📚  한줄 정리

1. Docker란 애플리케이션을 어디서나 동일한 환경에서 실행할 수 있도록 컨테이너로 패키징하는 플랫폼이다.

2. Docker Compose란 여러 Docker 컨테이너를 하나의 YAML 파일로 정의하고 함께 관리하는 도구이다.

'Bootcamp > Fundamentals' 카테고리의 다른 글

Redis  (0) 2026.07.23
CI/CD와 GitLab CI + AWS ECS 자동배포  (1) 2026.07.22
Event Driven Architecture와 Kubernetes  (0) 2026.07.05
Spring Cloud Config와 분산 추적  (0) 2026.07.04
API Gateway와 OAuth2 / JWT  (0) 2026.07.03