Notice
Recent Posts
Recent Comments
Link
관리 메뉴

look-forest

Docker Compose를 활용해 컨테이너 관리하기 본문

Infra/Docker

Docker Compose를 활용해 컨테이너 관리하기

studyHub 2025. 8. 15. 23:28

Docker Copmose란? 

여러 개의 Docker 컨테이너들을 하나의 서비스로 정의하고 구성해 하나의 묶음으로 관리할 수 있게 도와주는 툴이다. 

 

Docker Compose를 사용하는 이유

1. 여러 개의 컨테이너를 관리하는 데 용이

여러 개의 컨테이너로 이루어진 복잡한 애플리케이션을 한 번에 관리할 수 있게 해준다. 여러 컨테이너를 하나의 환경에서 실행하고 관리하는 데 도움이 된다. 

 

2. 복잡한 실행 명령어 간소화

이전에 MySQL 이미지를 컨테이너로 실행시킬 때 아래와 같은 명령어를 실행시켰다. 

$ docker run -e MYSQL_ROOT_PASSWORD=password123 -p 3306:3306 
-v /Users/jaeseong/Documents/Develop/docker-mysql/mysql_data:/var/lib/mysql -d mysql



너무 복잡하지 않은가? Docker Compose를 사용하면 위와 같이 컨테이너를 실행시킬 때마다 복잡한 명령어를 입력하지 않아도 된다. 단순히 `docker compose up` 명령어만 실행시키면 된다.

 


Docker Compose CLI 명령

compose.yml

docker compose는 compose.yml을 기반으로 동작한다.

services:
	my-web-server:
		container_name: webserver
		image: nginx
		ports: 
			- 80:80
  • services: my-web-server : Docekr Compose에서 하나의 컨테이너를 서비스(service)라고 부른다.
  • container_name: web-server : 컨테이너를 띄울 때 붙이는 별칭. CLI에서 --name web-server 역할.
  • image: nginx : 컨테이너를 실행시킬 때 어떤 이미지를 사용할 지 정의하는 명령어. $ docker run [이미지명]와 동일한 역할.
  • ports : 포트 매핑은 어떻게 할 지를 설정하는 옵션. CLI에서-p 80:80 역할.

compose.yml에서 정의한 컨테이너 실행

$ docker compose up    # 포그라운드에서 실행
$ docker compose up -d # 백그라운드에서 실행

 

Docker Compose로 실행시킨 컨테이너 확인하기

# compose.yml에 정의된 컨테이너 중 실행 중인 컨테이너만 보여준다. 
$ docker compose ps 

# compose.yml에 정의된 모든 컨테이너를 보여준다.
$ docker compose ps -a

 

Docker Compose 로그 확인하기

# compose.yml에 정의된 모든 컨테이너의 로그를 모아서 출력한다.
$ docker compose logs

 

컨테이너를 실행하기 전에 이미지 재빌드하기

$ docker compose up --build # 포그라운드에서 실행
$ docker compose up --build -d # 백그라운드에서 실행

compose.yml에서 정의한 이미지 파일에서 코드가 변경 됐을 경우, 이미지를 다시 빌드해서 컨테이너를 실행시켜야 코드 변경된 부분이 적용된다. 그러므로 이럴 때에는 --build 옵션을 추가해서 사용해야 한다. 

 

docker compose up vs docker compose up --build
 - docker compose up : 이미지가 없을 때만 빌드해서 컨테이너를 실행시킨다. 이미지가 이미 존재하는 경우 이미지를 빌드하지 않고 컨테이너를 실행시킨다. 즉, 업데이트가 안된다.
 - docker compose up --build : 이미지가 있건 없건 무조건 빌드를 다시해서 컨테이너를 실행시킨다.

 

이미지 다운받기 / 업데이트하기

$ docker compose pull

compose.yml에서 정의된 이미지를 다운 받거나 업데이트 한다.

  • 로컬 환경에 이미지가 없다면 이미지를 다운 받는다.
  • 로컬 환경에 이미 이미지가 있는데, Dockerhub의 이미지와 다른 이미지일 경우 이미지를 업데이트 한다.

Docker Compose에서 이용한 컨테이너 종료하기

# 완전히 종료(컨테이너 제거)
$ docker compose down

# 잠깐 중지(데이터 유지)
$ docker compose stop

컨테이너를 지운다.


[실습] Docker Compose로 Redis 실행시키기

services:
  my-cache-server:
    image: redis
    ports:
      - 6379:6379

 

[실습] Docker Compose로 mysql 실행시키기

services:
  my-db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: 0000
    volumes:
      - ./mysql_data:/var/lib/mysql
    ports:
      - 3306:3306

 

[실습] Docker Compose로 springboot 실행시키기

services:
  my-server:
    build: .
    ports:
      - 8080:8080

  • build: . : compose.yml이 존재하는 디렉토리(.)에 있는 Dockerfile로 이미지를 생성해 컨테이너를 띄우겠다는 의미이다. 
  • $ docker compose up -d --build 로 실행: jar가 바뀔 수 있으니 image를 업데이트한 후 사용하겠다는 의미이다. 

같은 경로에 있어서 build: . 인 것이다.

 

디렉토리를 분리하고 싶은 경우

services:
  my-server:
    build:
      context: ..                                # COPY는 빌드 컨텍스트 밖의 파일을 복사할 수 없으므로 빌드 컨텍스트를 '루트'로
      dockerfile: docker/Dockerfile  # Dockerfile 경로는 'context' 기준
    ports:
      - 80:8080

 

COPY ../build/libs..라고 하면 오류가 난다. COPY는 빌드 컨텍스트인 /docker 밖의 파일을 복사할 수 없기 때문이다. compose.yml에서 빌드 컨텍스트를 루트로 바꿔주자.


Docker Compose를 활용해 2개 이상의 컨테이너 관리하기

Spring Boot, MySQL 컨테이너 동시에 띄워보기

docker compose 파일에 서비스를 추가해주면 된다.

다만 springboot 컨테이너는 mysql 컨테이너가 기동된 후 실행되어야 하므로, 헬스체크 관련 설정을 추가한다.

 

application.yml에 db url 정보를 입력한다.

 

실행 결과, springboot 서버가 띄워지는 과정에서 mysql 서버와 연결에 실패했다. 

mysql 서버는 정상 기동되었는데, 이유가 뭘까?

Spring Boot 컨테이너의 로그를 열어보면 다음 에러 메시지가 나타난다. DB와 연결이 제대로 이루어지지 않았을 때 발생하는 에러이다.

 

 

컨테이너로 실행시킨 Spring Boot가 MySQL에 연결이 안 되는 이유

각각의 컨테이너는 자신만의 네트워크망과 IP 주소를 가지고 있다. 호스트 컴퓨터 입장에서 localhost는 호스트 컴퓨터를 가리키지만, Spring Boot 컨테이너 입장에서 localhost는 Spring Boot 컨테이너를 가리킨다.

 

그런데 Spring Boot의 코드를 작성할 때 DB 정보를 localhost:3306 으로 입력했었다. Spring Boot가 실행되는 환경인 컨테이너 입장에서 localhost:3306 라는 주소는, Spring Boot 컨테이너 내부에 있는 3306번 포트와 연결을 시도하게 된다. 하지만 Spirng Boot가 실행되는 컨테이너 내부의 3306번 포트에는 아무것도 실행되고 있지 않다. 이러한 구조상의 문제 때문에 Spring Boot가 MySQL에 연결이 안 되고 있었던 것이다.

 

그럼 어떻게 Spring Boot의 컨테이너에서 다른 컨테이너에 존재하는 MySQL에 연결을 할 수 있을까?

▷ docker compose는 compose.yml에서 정의한 Service 이름으로 서로 통신할 수 있도록 기능을 제공한다!

 

compose.yml에 작성한 service 이름컨테이너의 주소를 뜻한다. 해당 컨테이너의 IP 주소와 같은 역할을 한다.


Spring Boot, MySQL, Redis 컨테이너 동시에 띄워보기

 

 

1. mysql을 추가하는 것과 똑같이 docker compose에 redis 이미지를 추가하고, 헬스체크를 한다.

2. service 이름을 ip 대신 application.yml 설정 파일에 넣는다.

서비스 명으로 컨테이너 간 통신이 가능하다! (IP와 같은 역할)

 


 


참고 자료 & 이미지 출처
비전공자도 이해할 수 있는 Docker 입문·실전