[ 살펴보기 ] Docker - Compose
![[ 살펴보기 ] Docker - Compose](https://cdn.hashnode.com/res/hashnode/image/upload/v1719646842031/965356b1-9d93-47a1-914d-a298b5e54afc.jpeg)
지난 포스트를 통해 Docker image 생성과 container의 실행 그리고 네트워크 연결과 volume을 통한 데이터 관리등 여러가지 기능을 살펴보았다. 이제 이 모든 과정을 하나의 파일에서 관리할 수 있는 compose에 대해 살펴보자
Docker compose는 YAML 문법을 통해 작성하고 version, services, network와 같은 top-level element를 통해 실행할 application의 상세 내용을 구성하고 compose를 실행하면 compose YAML 파일에 정의한 구성대로 실행된다
Docker Compose 파일 생성
다음 예를 살펴보자
version: "1.0.0"
services:
mysql-container:
container_name: mysql-container
image: mysql:8
ports:
- 3306:3306
networks:
- test-volume-network
volumes:
- volume-mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=12345
backend-container:
container_name: backend-container
image: test-volume-backend
ports:
- 4000:4000
networks:
- test-volume-network
depends_on:
- mysql-container
volumes:
volume-mysql:
name: volume-mysql
external: true
networks:
test-volume-network:
name: test-volume-network
external: true
지난 포스트에서 살펴본 mysql + volume, backend application을 compose로 구성한 예제이다.
위의 예제에서는 4개의 top-level element가 사용되었다. version, services, volumes, networks.
services에서는 우리가 compose를 통해 실행할 container에 대한 정보를 기입하고 volumes과 network는 해당 container가 사용할 volumes과 networks에 대한 정보를 선언한다
사용된 top level element를 하나씩 살펴보자
volumes:
volume-mysql: // compose 파일 안에서 volume을 구분하기 위한 이름
name: volume-mysql
external: true
compose 실행 시 사용할 volume에 대한 정보를 기입한다. external:true는 이미 생성되어 있는 volume을 사용하겠다는 의미이며 위의 예제에서는 volume-mysql volume을 사용한다 ( name: volume-mysql )
volumes 구문 바로 아래 쪽에 있는 volume-mysql라는 이름은 생성된 volume 이름과는 별개로 compose 파일 안에서 volume을 구분하기 위한 이름이다
다음은 networks 구문을 살펴보자
networks:
test-volume-network: // compose 파일 안에서 network를 구분하기 위한 이름
name: test-volume-network
external: true
networks 구문에서도 역시 external을 통해 이미 존재하는 network를 사용하며 사용하는 network의 이름은 test-volume-network다 ( name: test-volume-network )
마찬가지로 networks 구문 바로 아래 쪽에 있는 test-volume-network라는 이름은 생성된 network 이름과는 별대로 compose 파일 안에서 network를 구분하기 위한 이름이다
다음은 services 구분이다
services:
mysql-container:
container_name: mysql-container
image: mysql:8
ports:
- 3306:3306
networks:
- test-volume-network
volumes:
- volume-mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=12345
backend-container:
container_name: backend-container
image: test-volume-backend
ports:
- 4000:4000
networks:
- test-volume-network
depends_on:
- mysql-container
services 구문에서 우리가 실행할 container의 상세 정보를 기입한다.
우선 mysql-container라는 service를 살펴보자
mysql-container:
container_name: mysql-container
image: mysql:8
ports:
- 3306:3306
networks:
- test-volume-network
volumes:
- volume-mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=12345
container 기반이 되는 image는 mysql:8를 사용하고 port는 3306으로 mapping한다. network는 compose파일 아래 선언해 두었던 test-volume-network 라는 network를 사용한다
volume 역시 compose 파일 아래 선언해 두었던 volume-mysql라는 volume을 사용하여 실행될 container의 /var/lib/mysql 폴더에 해당 volume을 마운트한다 그리고 contianer가 실행될 때 전달할 환경변수는 environment를 통해 전달한다. 위의 예제에서는 MYSQL_ROOT_PASSWORD 환경변수를 선언하고 있다.
이제 backend-container service를 살펴보자
backend-container:
container_name: backend-container
image: test-volume-backend
ports:
- 4000:4000
networks:
- test-volume-network
depends_on:
- mysql-container
내용은 mysql-container service와 크게 다를게 없지만 depends_on을 통해 해당 container의 의존 관계를 표현할 수 있다. 즉, backend-container가 정상 작동하기 위해서 mysql-container가 먼저 작동 하고 있어야 하므로 위 처럼 depends_on에 mysql-container를 설정해두면 compose를 통해 application을 실행할 때 mysql-container가 구동된 다음 backend-container가 구동된다 ( backend application에서 mysql 접속 설정시 host 는 mysql container 이름으로 설정 되어야 한다. ( [ 살펴보기 ] Docker - Volume 포스트 참고 )
Docker Container 사이의 통신
도커 컨테이너가 생성되면 도커 엔진은 해당 컨테이너에 가상 IP를 부여한다. 도커 네트워크에 연결된 컨테이너는 이 네트워크 범위에 포한되는 IP를 부여 받게 되는데 이를 통해 컨테이너는 서로 통신할 수 있게 된다.
그리고 도커 자체에 DNS 서비스가 내장되어 있다. 컨테이너 이름을 조회하여 컨테이너의 IP를 찾을 수 있기에 컨테이너가 삭제되고 새로 생성되어 해당 컨테이너 IP가 변경되더라도 컨테이너 이름으로 IP를 찾기에 문제없이 다른 컨테이너와 통신할 수 있다
Docker Compose 실행하기
이제 작성한 compose를 작동시켜 보자. compose 파일의 이름을 docker-compose.yml로 만들고 compose 파일이 있는 위치에서 다음 명렁어를 실행한다
docker compose up
위의 명령어를 실행하면 default로 현재 위치의 docker-compose.yml 파일을 기준으로 compose 리소스를 생성한다. 하지만 다른 위치에 있거나 다음 이름의 compose파일을 사용하고자 한다면 아래와 같이 -f 명령어를 사용한다
docker compose -f docker-compose-dev.yml up
background mode로 compose를 실행하고자 한다면 다음과 같이 -d 옵션을 추가해주자
docker compose up -d
위의 command를 실행 시키는 디렉터리에 docker-compose.yml가 있으면 해당 파일을 기준으로 실행한다
만약 docker-compose가 아니라 다른 이름의 compose 파일을 사용해서 application을 실행시키고자 한다면 다음과 같이 -f option을 사용한다
docker compose -f docker-compose-frontend.yml
compose 파일 구성에 이상이 없다면 다음과 같이 compose 파일 아래 선언한 container들이 정상적으로 생성되어 운영되는 걸 확인할 수 있다.

compose를 통해 생성된 container를 종료하고 삭제하는 command는 다음과 같다
docker compose down
환경변수 따로 관리하여 전달하기
Compose config 파일에 값을 바로 작성할 수 없는 환경변수가 있다면 환경변수를 관리하는 .env 파일을 따로 작성하여 compose를 실행할 때 함께 넘길 수 있다. 다음 예제를 살펴보자
// docker-compose.yml
version: "1.0.0"
services:
mysql-container:
container_name: mysql-container
image: mysql:8
ports:
- 3306:3306
networks:
- test-volume-network
volumes:
- volume-mysql:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
...
// .env.dev
MYSQL_ROOT_PASSWORD=12345
위의 예제와 같이 compose 파일의 환경변수를 .env.dev 파일에서 받아 사용할 수 있도록 변경되었다. 그리고 compose를 실행할 때 --env-file 옵션을 통해 우리가 따로 작성한 .env.dev 파일에 선언된 환경변수를 넘겨줄 수 있다
docker compose --env-file .env.dev up
다음과 같이 compose 파일에서 어떤 env 파일을 통해 환경 변수를 가져올 것인지 설정할 수 도 있다
// docker-compose.yml
version: "1.0.0"
services:
mysql-container:
container_name: mysql-container
image: mysql:8
ports:
- 3306:3306
networks:
- test-volume-network
volumes:
- volume-mysql:/var/lib/mysql
env_file:
- .env.dev
...
위의 예제처럼 environment 속성 대신 env_file 속성에 env 파일을 선언해주면 해당 env 파일에 선언된 환경 변수가 사용되며 docker compose를 실행할 때 --env-file option을 별도로 줄 필요도 없다.
![[ 살펴보기 ] RDB - Relationships](https://cdn.hashnode.com/res/hashnode/image/upload/v1739711556668/48dc9e84-a621-42aa-9c9f-5fc5c436f0ec.jpeg)
![[ 살펴보기 ] MySQL - Data types](https://cdn.hashnode.com/res/hashnode/image/upload/v1739593589113/530f8704-4d27-42c9-a451-bb5c63150b99.jpeg)
![[ 살펴보기 ] TypeORM - Transactions, Migration](https://cdn.hashnode.com/res/hashnode/image/upload/v1739106042581/980b8133-61d4-406a-a026-65be9c28eace.jpeg)
![[ 살펴보기 ] TypeORM - Relations](https://cdn.hashnode.com/res/hashnode/image/upload/v1738666874402/b688bd0b-b6bb-4f43-87d8-c1b46b59f1b7.jpeg)
![[ 살펴보기 ] TypeORM - Basics](https://cdn.hashnode.com/res/hashnode/image/upload/v1738666803591/bef5df17-7dc7-4123-ae55-004d5042df39.jpeg)