
📚 목차
🧩 Docker
Docker란?
- Docker: 애플리케이션을 쉽게 만들고, 테스트하고, 배포할 수 있게 도와주는 소프트웨어 플랫폼
- 애플리케이션을 컨테이너라는 가볍고 이식성 있는 패키지로 실행할 수 있음
- Docker 이미지: 애플리케이션을 실행하는 데 필요한 모든 것을 포함 (코드, 런타임, 시스템 도구, 시스템 라이브러리 등)
- 주요 특징
- 컨테이너화: 애플리케이션과 필요한 모든 것을 하나의 패키지로 묶어 어디서든 실행 가능
- 경량: Docker는 운영 체제의 커널을 공유하므로 가상 머신보다 훨씬 가볍고 빠르게 실행됨
- 이식성: Docker 컨테이너는 어디서든 동일하게 실행됨
- 확장성: Docker를 사용하면 여러 개의 컨테이너를 효율적으로 관리하고 쉽게 확장 가능함
- 주요 키워드
- 이미지: 애플리케이션과 모든 실행에 필요한 파일을 포함한 읽기 전용 템플릿
- 컨테이너: 이미지를 실행하여 동작하는 애플리케이션 인스턴스
- Docker 이미지를 실행한 상태
- 격리된 공간에서 애플리케이션을 실행하며, 필요한 모든 의존성을 포함함
- 하나의 시스템에서 여러 개의 컨테이너를 독립적으로 실행 가능
- Dockerfile: 이미지를 생성하기 위한 명령어가 담긴 스크립트 파일
- Docker Hub: 이미지를 저장하고 공유하는 중앙 저장소
- 볼륨: 컨테이너 데이터를 지속적으로 저장하는 메커니즘
- 컨테이너가 삭제되어도 볼륨에 저장된 데이터는 유지됨
- 데이터를 컨테이너와 독립적으로 관리 가능
- 네트워크: 컨테이너 간의 통신을 관리하는 방식
- Docker 네트워크 종류
- Bridge Network
- 기본적으로 Docker가 컨테이너를 실행할 때 사용하는 네트워크
- 동일한 브리지 네트워크에 연결된 컨테이너들은 서로 통신 가능함
- 외부 네트워크와는 NAT을 통해 통신함 (NAT: 내부 네트워크의 여러 장치가 하나의 공용 IP 주소를 통해 외부 네트워크와 통신할 수 있도록 IP 주소를 변환하는 기술)
- 일반적으로 단일 호스트에서 여러 컨테이너를 연결할 때 사용됨
docker network create my-bridge-network docker run -d --name container1 --network my-bridge-network nginx docker run -d --name container2 --network my-bridge-network nginx
- Host Network
- 컨테이너가 호스트의 네트워크 스택을 직접 사용함
- 네트워크 격리가 없기 때문에 성능상 이점이 있지만 보안 및 네트워크 충돌 위험이 있음
- 일반적으로 성능이 중요한 애플리케이션에 사용됨
docker run -d --network host nginx
- Overlay Network
- 여러 Docker 호스트에 걸쳐 있는 컨테이너를 연결할 때 사용됨
- Swarm 모드나 Kubernetes 같은 오케스트레이션 도구와 함께 사용됨 (Swarm: Docker 컨테이너의 오케스트레이션과 클러스터링을 지원하여 여러 호스트에서 컨테이너를 관리하고 배포할 수 있는 기능)
- 데이터 센터 또는 클라우드 환경에서 분산 시스템을 구축할 때 유용함
- Bridge Network
Docker vs VM
가상 머신(VM): 하이퍼바이저를 통해 물리적 하드웨어 위에 가상화된 운영 체제를 실행하는 기술
하이퍼바이저: 여러 운영 체제를 동시에 실행할 수 있도록 물리적 하드웨어를 가상화하는 소프트웨어
- Docker의 장점
- 빠른 시작과 낮은 오버헤드
- 높은 이식성과 확장성
- Docker의 단점
- 보안 격리가 VM보다 약함
- 운영 체제 종속성 존재 (리눅스 친화적)
- VM의 장점
- 격리된 환경 제공
- 다양한 운영 체제 실행 가능
- VM의 단점
- 오버헤드가 크고 느린 부팅 시간
- 높은 리소스 소비
Docker는 언제 사용하면 좋을까?
- 일관된 개발 환경이 필요할 때: 모든 환경에서 동일한 컨테이너를 실행 가능함
- 애플리케이션을 빠르게 배포하고 싶을 때: Docker 이미지를 빌드하고 컨테이너로 실행하면 필요한 모든 구성 요소가 포함되어 있어 별도의 설치 과정 없이 바로 실행 가능함
- MSA를 도입할 때: 각 서비스가 독립적으로 배포되고 실행될 수 있어 여러 개의 컨테이너를 통해 다양한 서비스를 쉽게 관리 가능함
- CI/CD 파이프라인을 구축할 때: 코드를 변경할 때마다 자동으로 빌드, 테스트, 배포할 수 있도록 설정 가능함
- 리소스 효율성을 높이고 싶을 때: 운영 체제의 커널을 공유하므로 더 많은 애플리케이션을 동일한 하드웨어에서 실행 가능함
- 애플리케이션 격리가 필요할 때: 각 컨테이너가 서로 격리되어 실행됨
- 쉽게 스케일링하고 싶을 때: 필요한 만큼 컨테이너를 추가하여 수평 확장이 가능하며, 오케스트레이션 도구와 결합하여 자동 확장도 가능함
- Kubernetes와 함께 사용하고자 할 때: 쿠버네티스는 다수의 Docker 컨테이너를 관리하고 자동 배포, 확장, 운영을 지원함
Docker 명령어
이미지 관련 명령어
- 이미지 빌드: 현재 디렉토리의 Dockerfile을 기반으로 myapp이라는 이름의 이미지를 생성함
docker build -t myapp:latest .
- 이미지 가져오기
docker pull postgres
- 이미지 목록 보기
docker images
- 이미지 삭제
docker rmi myapp:latest
컨테이너 관련 명령어
- 컨테이너 실행:
-d→ 백그라운드 실행 /-p 8080:80→ 호스트의 8080 포트를 컨테이너의 80 포트에 매핑
docker run -d -p 8080:80 myapp:latest

- 컨테이너 내부 접속:
-i→ 컨테이너의 표준 입력(STDIN)을 열어 사용자 입력을 받을 수 있음 /-t→ 가상 터미널 할당
docker exec -it container_id /bin/shell
- 실행 중인 컨테이너 목록 보기
docker ps
- 모든 컨테이너 목록 보기
# 중지된 컨테이너 포함 모든 컨테이너 목록 표시
docker ps -a
# 마지막으로 실행된 컨테이너를 먼저 나열
docker ps -al
- 컨테이너 중지
docker stop container_id
- 컨테이너 시작
docker start container_id
- 컨테이너 삭제
docker rm container_id
Docker 네트워크 및 볼륨 관련
- 네트워크 생성
docker network create mynetwork
- 네트워크 목록 보기
docker network ls
- 네트워크 삭제
docker nework rm mynetwork
- 볼륨 생성
docker volume create myvolume
- 볼륨 목록 보기
docker volume ls
- 볼륨 삭제
docker volume rm myvolume
실습: PostgreSQL 컨테이너 2개 실행하기
- 이미지 받기
docker pull postgres
- 컨테이너 실행하기 (리눅스)
docker run -d --name postgres-sample \
-p 5433:5432 \
-e POSTGRES_USER=admin1 \
-e POSTGRES_PASSWORD=admin2 \
-e PGDATA=/var/lib/postgresql/data/pgdata \
-v ${로컬_바인딩_폴더}:/var/lib/postgresql/data:z \
postgres
- 컨테이너 실행하기 (윈도우)
docker run -d --name postgres-sample `
-p 5433:5432 `
-e POSTGRES_USER=admin1 `
-e POSTGRES_PASSWORD=admin2 `
-e PGDATA=/var/lib/postgresql/data/pgdata `
-v "${로컬_바인딩_폴더}:/var/lib/postgresql/data:z" `
postgres


🧩 Docker Compose
Docker Compose란?
- Docker Compose: 다중 컨테이너 Docker 애플리케이션을 정의하고 실행하기 위한 도구
docker-compose.yaml파일 하나로 애플리케이션의 서비스, 네트워크, 볼륨 등을 정의할 수 있음- 20.10 버전부터 기본적으로 설치되며,
docker compose로 실행 가능함
docker-compose.yaml 파일 구조
version: '3'
services:
web:
image: nginx
ports:
- "8080:80"
app:
build: .
ports:
- "8081:8080"
depends_on:
- db
db:
image: postgres
environment:
POSTGRES_PASSWORD: example
version: Docker Compose 파일 버전services: 애플리케이션의 각 서비스를 정의web,app,db: 각 서비스의 이름image: 서비스를 실행할 Docker 이미지build: Dockerfile이 있는 디렉토리 경로를 지정해 이미지를 빌드함ports: 호스트와 컨테이너 간의 포트를 매핑함depends_on: 다른 서비스가 먼저 실행되어야 하는 순서를 지정함environment: 컨테이너의 환경 변수를 설정함
Docker Compose 명령어
docker compose up- YAML 파일에 정의된 서비스를 빌드하고 시작함
- 백그러운드에서 실행하려면
-d옵션을 추가함
docker compose up -d
docker compose -f /path/to/your/project/docker-compose.yml up
docker compose down: 실행중인 모든 서비스를 중지하고 컨테이너, 네트워크, 볼륨 등을 정리함
Dockerfile 작성 예시
FROM amazoncorretto:17
COPY target/myapp.jar /app/myapp.jar
WORKDIR /app
ENTRYPOINT ["java", "-jar", "myapp.jar"]
🧩 실습하기
애플리케이션 생성
- [B]
BController
@RestController
public class BController {
@GetMapping("hello")
public String hello(){
return "hello";
}
}
- [A]
AController
@RestController
@RequiredArgsConstructor
public class AController {
private final BServiceClient bServiceClient;
@GetMapping("hi")
public String hi(){
String hello = bServiceClient.getHello();
return "A: hi B: " + hello;
}
}
- [A]
BServiceClient
@FeignClient(name = "service-b", url = "${service.b.url}")
public interface BServiceClient {
@GetMapping("/hello")
public String getHello();
}

Docker 사용 실습
application.properties수정- 기존에는 service-a가 18080, service-b가 18081로 서로 다른 포트 번호를 사용했지만, Docker를 사용하면 서로 독립적인 환경이 되기 때문에 포트를 8080로 통일해도 상관 없다.
- 같은 Docker 네트워크 내에서는 Docker 컨테이너의 이름으로 호출할 수 있다.
spring.application.name=service-a
server.port=8080
service.b.url=http://service-b:8080
spring.application.name=service-b
server.port=8080
- Dockerfile 생성
FROM amazoncorretto:17
VOLUME /tmp
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
- Docker 네트워크 생성: 도커끼리 컨테이너 이름으로 호출하기 위해선 기본 브리지 네트워크가 아닌 사용자 정의 네트워크에서 진행해야 한다.
docker network create my-network
- 프로젝트 빌드 및 도커 이미지 생성
./gradlew clean bootJar
docker build -t img-service-a .
./gradlew clean bootJar
docker build -t img-service-a .
- 컨테이너 생성
docker run -d --name service-a `
--network my-network `
-p 18080:8080 `
-e SERVICE_B_URL=http://service-b:8080 `
img-service-a
docker run -d --name service-b `
--network my-network `
-p 18081:8080 `
img-service-b



Docker Compose 사용 실습
- 컨테이너 삭제
- 일반적으로는 아래처럼 강제 삭제가 아니라 컨테이너를 정지시킨 후에 삭제를 진행해야 한다.
- 필자는 Docker Desktop 상에서 삭제를 진행했다. (위 이미지에서 빨간색 휴지통 아이콘)
docker rm -f 서비스_A_컨테이너_아이디
docker rm -f 서비스_B_컨테이너_아이디
docker-compose.yml파일 생성
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는 기본적으로 새 브리지 네트워크를 생성하여 각 서비스 컨테이너를 그 네트워크에 연결한다.

'내일배움캠프' 카테고리의 다른 글
| [내일배움캠프] Github Actions와 CI/CD (0) | 2026.05.06 |
|---|---|
| [내일배움캠프] CI/CD와 AWS ECS (0) | 2026.05.05 |
| [내일배움캠프] Controller와 Service를 분리해야 하는 이유 (0) | 2026.04.20 |
| [내일배움캠프] Spring MVC 기초 정리 (0) | 2026.04.17 |
| [내일배움캠프] 개발 프로세스 가이드 (0) | 2026.04.16 |