일반적으로 웹서비스는 3tier 구조를 갖는다
WEB - WAS - DB
위와 같은 구조를 docker container run 을 이용하여 구성하게 되면
- 복잡하다
- 동일 구조를 다시 만드는데 오랜 시간이 걸린다
- 변경이 용이하지 않다.
위와 같은 구조를 하나의 명세서에 작성하는 방법을 도커에서 제공하는데 이를 docker-compose 라 부른다. docker-compose는 docker에서 제공하는 기본서비스가 아니므로 별도로 추가 설치가 필요하다.
단, docker-compose는 클러스터 환경에서의 사용이 아니라 1대의 도커 서버에서 동작한다. 실제 클러스터 환경에서는 docker-compose + 클러스터 환경(docker swarm) = "docker stack"
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
vi ~/.bashrc # alias 지정 위함
alias dc='docker-compose'
docker-compose.yml 파일 내에는 version, sevice, network, volume 네 가지 항목을 정의한다.
- 컴포즈는 특정 서비스를 제공하기 위하여 컨테이너들의 묶음이라고 할 수 있는 "service" 단위로 배포한다.
- version: 버전별로 지원되는 옵션이 달라진다. 지원이 되지 않는등의 문제가 있다면 해당 버전을 홈페이지에서 반드시 확인해야 한다. yml 파일 가장 앞부분에 위치.
- 예전버전에서는 지원이 됐으나 지금은 지원되지 않는 옵션
--volumes-from: 컨테이너의 디렉토리를 다른 컨테이너의 디렉토리와 마운트 하는 것- services: 실제로 서비스를 제공하는 컨테이너에 대한 정의
- services 하위 옵션
- ports: 서비스 내부 포트와 외부 호스트 포트를 지정하여 바인드. docker run의 -p 옵션과 동일
ports: - "80" <- host의 랜덤포트 부여하고 컨테이너 80번 포트와 연결 ports: - "8001-8002:80" host 8001~ 8002 사이 포트 부여하고 컨테이너 80번 포트와 연결 ports: - "8001:80"
- depends_on: 서비스 간의 종속성을 의미하며 먼저 실행해야 하는 서비스를 지정하여 순서 지정. 이 옵션에 지정된 서비스가 먼저 시작됨
- environment: 서비스 내부 환경 변수 설정.
- command: 서비스가 구동 이후 실행할 명령어 작성.
- volumes: 컨테이너에 연결할 볼륨을 정의한다. (필수x) 데이터의 지속성을 유지하기 위해 최상위 레벨에 볼륨을 정의하고, 서비스 레벨에서 볼륨명과 서비스 내부의 디렉토리를 바인드한다.
볼륨.
- 기존 볼륨 활용가능(네트워크와 동일). 지정하지 않는다면 디렉토리 이름을 이용하여 신규 생성한다.
- volume 사용
- nfs: 디렉토리 마운트
- iscsi: 스토리지에서 volume을 생성하고 이를 컨테이너의 /dev/sda* 와 같은 형태로 연결
- tmpfs: 디스크가 아니라 RAM에 저장(영구 보관 불가)
volumes: - testvolume1:/var/www/html # 0822_testvolume1 과 컨테이너의 /var/www/html이 연결 volumes: testvolume1: # 0822_testvolume1 이 생성된다. external: true # 기존에 만들어 둔 testvolume1 을 사용한다.
networks: 컨테이너들을 연결할 네트워크를 정의한다(필수아님 -> 작성하지 않으면 모든 컨테이너는 docker0에 연결된다)
- external: 기존 네트워크에 연결하기 위한 중요한 옵션
networks: test1net: driver: bridge <-- private1은 브릿지 타입으로 생성된다 external: true # 새로 test1_test1net 이 만들어지지 않고, 기존 test1net 에 연결된다.
extends: yml파일을 추가적으로 만들거나 하나의 yml내에서 추가 컨테이너 내에 기본 내용을 작성하고 이를 다른파일이나 서비스에서 상속하여 사용하는 방법
- 주로 두개의 파일을 만들어 두고 이를 상속받는 방법을 서용한다. 자주 사용x
rapa@rapa:~/0822/test2$ touch docker-compose.yml extend-compose.yml rapa@rapa:~/0822/test2$ cat docker-compose.yml ; echo ; cat extend-compose.yml version: '3.7' services: web: extends: file: extend-compose.yml service: testweb version: '3.7' services: testweb: image: httpd ports: - "80" rapa@rapa:~/0822/test2$ docker-compose -f docker-compose.yml -f extend-compose.yml up -d Creating network "test2_default" with the default driver Creating test2_web_1 ... done Creating test2_testweb_1 ... done
주의: 일반적으로 YAML 파일은 tab 을 인식하지 않으므로 반드시 space bar 를 이용해야 한다. 들여쓰기 중요
docker-compose.yml 예시
version: '3.7' services: web: image: httpd ports: - "8001:80" command: httpd -D FOREGROUND depends_on: - db links: - db:mysql db: image: mysql:5.7 environment: - MYSQL_ROOT_PASSWORD=test123 - MYSQL_DATABASE=testdb
services: myctn1: image: centos:7 enviroment: MYSQL_ROOT_PASSWROD: test123 MYSQL_DATABASE: wordpress networks: - private1 - private2 myctn2: build: enviroment: - WORDPRESS_DB_USER=root - WORDPRESS_DB_NAME=wordpress depends_on: #실행 순서 결정. myctn1이 먼저 실행됨. myctn1의 동작완료를 확인하지는 않는다. - myctn1 ports: - "8080:80" # 시간과 구분하기 위해 " "를 붙인다. - "33061:3306" # -p 33061:3306 - "8080" # -P 8080 호스트의 랜덤포트와 컨테이너의 8080을 연결 - "8081-8085" # 랜덤포트 networks: - private2
yml 파일 배포
docker-compose up -d
: 별도의 네트워크를 위한 기본네트워크가 생성되고 컨테이너도 생성된다.ex) rapa@rapa:~/0822$ docker-compose up -d Creating network "0822_default" with the default driver Creating 0822_db_1 ... done Creating 0822_web_1 ... done
docker-compose ps
: docker compose로 만든 컨테이너만 볼 수 있다. docker container run으로 생성한 것은 ps로 확인 불가능하다.
네트워크를 지정하지 않으면 별도의 네트워크가 생성된다. 하지만, 기존에 생성되어 있는 네트워크를 재사용하고 싶다면??
docker network create test1net(네트워크이름)
docker container run -it --name centos01 --net test1net centos:7 # test를 위하여 임의의 컨테이너를 생성하고 기 생성된 test1net 에 연결
rapa@rapa:~/0822/test1$ docker container inspect centos01 --format "{{.HostConfig.NetworkMode}}"
test1net
version: '3.7'
services:
web:
build: .
image: myweb:1.0