Docker Compose 실습 (일단 해보면서 감 잡아보기) + 이론
👻 Docker Compose 실습 (일단 해보면서 감 잡아보기)
- 이론은 밑에 적어두었습니다. 실습 먼저!
- 도커 컨테이너 여러개 관리하기
👉 도커 네트워크 리스트 조회
- docker network ls
- bridge : 도커 엔진에 의해 자동으로 생성된 가상 네트워크, 컨테이너끼리 연결되는 기본
- host : 호스트 컴퓨터의 네트워크 인터페이스를 그대로 사용하는 네트워크
- none : 네트워크를 사용하지 않는 컨테이너
👉 도커 네트워크 생성
- docker network create [이름]
🧭 Docker Compose를 사용하지 않고 CLI로 관리한다면?
👉 mysql db container 생성
docker run \\
-d --name "db" \\
-v "$(pwd)/db_data:/var/lib/mysql" \\
-e "MYSQL_ROOT_PASSWORD=root_pass" \\
-e "MYSQL_DATABASE=wordpress" \\
-e "MYSQL_USER=docker_pro" \\
-e "MYSQL_PASSWORD=docker_pro_pass" \\
--network wordpress_net \\ #"wordpress_net"이라는 Docker 네트워크에 컨테이너를 연결
mysql:latest
- cmd에는 아래와 같이 한줄로 복붙해서 넣으시면 됩니다.
- docker run -d --name "db" -v "$(pwd)/db_data:/var/lib/mysql" -e "MYSQL_ROOT_PASSWORD=root_pass" -e "MYSQL_DATABASE=wordpress" -e "MYSQL_USER=docker_pro" -e "MYSQL_PASSWORD=docker_pro_pass" --network wordpress_net mysql:latest
- -v "$(pwd)/db_data:/var/lib/mysql": 호스트 시스템의 현재 디렉토리에 있는 "db_data" 디렉토리를 컨테이너 내부의 "/var/lib/mysql" 경로와 볼륨 마운트합니다. 이를 통해 데이터베이스 파일을 호스트 시스템과 공유하게 됩니다.
👉 wordpress container 생성
docker run \\
-d --name app \\
-v "$(pwd)/app_data:/var/www/html" \\
-e "WORDPRESS_DB_HOST=db" \\
-e "WORDPRESS_DB_NAME=wordpress" \\
-e "WORDPRESS_DB_USER=docker_pro" \\
-e "WORDPRESS_DB_PASSWORD=docker_pro_pass" \\
-e "WORDPRESS_DEBUG=1" \\
-p 8000:80 \\
--network wordpress_net \\
wordpress:latest
- docker run -d --name app -v "$(pwd)/app_data:/var/www/html" -e "WORDPRESS_DB_HOST=db" -e "WORDPRESS_DB_NAME=wordpress" -e "WORDPRESS_DB_USER=docker_pro" -e "WORDPRESS_DB_PASSWORD=docker_pro_pass" -e "WORDPRESS_DEBUG=1" -p 8000:80 --network wordpress_net wordpress:latest
Dockerfile을 사용하여 이미지를 빌드하는 대신 docker run 명령어를 사용하여 컨테이너를 바로 실행하는 방식을 사용하고 있습니다. 이 접근 방식은 간단한 테스트나 특정 상황에서 유용할 수 있지만, 실제 프로덕션 환경에서는 Dockerfile을 사용하여 이미지를 정의하고 빌드하는 것이 일반적으로 권장됩니다.
- 결과는 잘 뜹니다.
🧭 Docker Compose를 사용하여 컨테이너 관리
위에서도 CLI로 안하고 도커파일을 사용했어도 OK지만, 그래도 두개의 도커파일로 각각의 이미지를 만들고 컨테이너화 했어야 한다.
하지만 compose를 사용하면 하나의 파일에서 여러개의 컨테이너를 관리할 수 있다.
👉 docker-compose.yml
version: "3.0"
services:
db:
image: mysql:latest
volumes:
- ./db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: root_pass
MYSQL_DATABASE: wordpress
MYSQL_USER: docker_pro
MYSQL_PASSWORD: docker_pro_pass
networks:
- wordpress_net
app:
depends_on:
- db
image: wordpress:latest
volumes:
- ./app_data:/var/www/html
ports:
- "8000:80"
restart: always
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: docker_pro
WORDPRESS_DB_PASSWORD: docker_pro_pass
networks:
- wordpress_net
networks:
wordpress_net:
external: true
👉 docker-compose 명령어
# docker-compose.yml 파일을 기반으로 Docker Compose를 사용하여 컨테이너를 실행하라는 명령
# docker-compose up -d 과 같은 의미
docker-compose -f docker-compose.yml up -d
- docker-compose.yml 파일을 기반으로 Docker Compose가 서비스를 정의하고 구성합니다. 위의 예제에서는 db 서비스와 app 서비스가 정의되어 있습니다.
- db 서비스와 app 서비스가 각각 MySQL과 WordPress를 실행하는 컨테이너를 생성합니다. db 서비스는 MySQL 컨테이너를, app 서비스는 WordPress 컨테이너를 실행합니다.
- networks 키 아래에 'wordpress_net' 네트워크를 정의하고, 각 서비스의 networks 설정을 통해 해당 네트워크에 서비스를 연결합니다. **driver: bridge**는 가장 일반적인 네트워크 드라이버로, 서비스가 동일한 네트워크 내에서 서로 통신할 수 있게 해줍니다.
- docker-compose -f docker-compose.yml up -d 명령어의 d 옵션은 컨테이너를 백그라운드 모드로 실행하라는 의미입니다. 즉, 컨테이너가 백그라운드에서 실행되며 콘솔을 차지하지 않습니다.
- 컨테이너가 실행된 후, 각 서비스의 설정에 따라 컨테이너 간의 의존성이 관리됩니다. 위의 예제에서는 app 서비스가 db 서비스에 의존하므로 db 컨테이너가 먼저 실행되고 그 다음에 app 컨테이너가 실행됩니다.
- 컨테이너가 실행되면 docker-compose.yml 파일에서 정의한 설정에 따라 컨테이너 간에 네트워크 연결, 환경 변수 설정, 볼륨 마운트 등이 자동으로 구성됩니다.
👉 주의할 점
**external: true**를 생략하면, Docker Compose는 docker-compose.yml 파일에 **wordpress_net**라는 네트워크가 정의되어 있음에도 불구하고 디렉토리이름+네트워크이름 으로 네트워크를 새로 생성합니다.
기존에 있는 wordpress_net을 사용하기를 바랬지만, 실제로는 docker_wordpress_net 이라는 네트워크를 새로 만들어버립니다.
external: true 옵션을 주어서 Docker Compose에게 해당 네트워크가 이미 존재하며, 외부에서 생성된 네트워크임을 알려주어야 합니다.
**external: true**를 생략 했을 때
Network docker_default Created 를 볼 수 있습니다. (이것도 설정오류로 원래는 docker_wordpress_net Created가 맞습니다.)
**external: true**을 넣었을 때
Network Created가 안되고 2 step으로 진행되었습니다.
👉 network inspect 명령어
docker network inspect wordpress_net
- 내가 원하는 network를 잘 사용하고 있는지 꼭 확인해주세요.
관련 이미지가 이미 다운로드되어 있어서, 컨테이너가 빠르게 실행된것으로 보입니다.
다운받은 뒤로 로컬에 캐시되어 빠르게 컨테이너를 실행할 수 있는데, Docker는 이미지 캐싱 및 재사용을 통해 빠른 배포 빛 실행을 지원합니다.
- compose도 잘 나옵니다.
👉 도커를 이용한 웹 서비스 아키텍처
웹 서버, PHP, MySQL 서버의 관계와 포트 번호, 데이터 볼륨, 그리고 네트워크 설정
docker-compose를 실행하고, 브라우저에서 localhost:8080에 접속하면 다음과 같은 일이 순차적으로 발생합니다.
- 호스트의 8080번 포트와 연결된 app 컨테이너의 웹 서버가 리스닝을 하고 있다가 연결을 받는다.
- 웹 서버는 php에게 request를 넘긴다.
- php는 /var/www/html의 디렉토리에 있는 php application을 읽어서 그대로 실행한다.
- v로 마운트했으므로 호스트의 파일 시스템인 app_data에 있는 정보를 읽어온다.
- php는 app_data에 MySQL db에 접속해서 db를 꺼내오라는 정보를 가지고 같은 네트워크의 3306번 포트에 있는 MySQL 서버에 접속한다.
- 이 3306번 포트의 MySQL 서버는 /var/lib/mysql이라는 디렉토리에 있는 db를 꺼내와야 한다.
- v로 마운트했으므로 호스트의 파일 시스템인 db_data에 있는 정보를 읽어온다.
- MySQL 서버는 php에 이 정보를 전달한다.
- php는 이 정보를 가지고 웹 서버에 response를 전달한다.
- 그리고 마지막으로 웹 서버가 response를 가지고 렌더링을 해서 우리에게 정보를 보여준다.
- 이 일련의 과정들을 설명할 수 있어야 합니다.
👻 Docker Compose 이론
- 아하 이런 느낌이군, 좀 더 알고싶다면?
- Docker Compose 알아보기!
🐙 Docker Compose ?
- 도커 컨테이너를 일괄적으로 정의하고 제어하는 도구로 설정 파일을 도커 CLI로 번역해줍니다.
- (여러개의 컨테이너를 빌드하고 실행하고 관리한다면 귀찮을것..)
🐙 도커 컴포즈 파일 구성
- version 설명
- 보통 3.0 이상의 버전 사용
- services 설명
- 실행하려는 컨테이너들을 정의
- 이름, 이미지, 포트, 환경 변수, 볼륨 등 포함
- 해당 정보로 컨테이너를 생성하고 관리
- services 옵션
- image : 컨테이너를 생성할 때 쓰일 이미지를 지정
- build : 정의된 도커파일에서 이미지를 빌드해 서비스의 컨테이너를 생성하도록 설정
- environment : 환경 변수 설정, --env, -e 옵션과 동일
- command : 컨테이너가 실행될 때 수행할 명령어 (docker run 명령어의 마지막 커맨드와 동일)
- depends_on : 컨테이너 간의 의존성 주입, 명시된 컨테이너가 먼저 생성되고 실행됨.
- ports : 개방할 포트 지정, docker run 명령어의 -p 옵션과 동일
- expose : 링크로 연계된 컨테이너에게만 공개할 포트 설정
- volumes : 컨테이너에 볼륨 마운트
- restart : 컨테이너가 종료될 때 재시작 정책
- no : 재시작 x
- always : 외부 영향으로 종료 되었을 때 항상 재시작 (수동으로 끄기 전까지)
- on-failure : 오류가 생겨 종료되었을 때만 재시작
- network : 이 컨테이너들이 공유할 network 를 정의한다. (지정해주지 않아도 [이름_default]으로 하나 만들어준다.)
- volume
- config
- secret
🐙 도커 명령어
- docker network rm 네트워크_이름
- 도커에서 해당 네트워크를 삭제
- docker rm -f mycontainer
- mycontainer라는 이름의 실행 중인 컨테이너를 중지 + 삭제를 한번에!
- docker-compose down
- docker-compose.yml 파일에 정의된 모든 서비스를 중지하고, 관련 컨테이너와 네트워크를 제거합니다. 또한, v 옵션을 추가하면 관련된 볼륨도 함께 제거할 수 있습니다.
🐙 도커 컴포즈 명령어
- docker-compose -f local-infra.yml up -d
- up : 도커 컴포즈 파일로 컨테이너 생성
- f : 도커 컴포즈 파일 지정
- d : 백그라운드에서 실행
- docker-compose -f docker-compose.yml up --build
- f 이 파일로 도커 컴포즈를 실행하고 이미지를 빌드
- docker-compose vs docker compose ?
- docker-compose 명령어가 docker compose로 흡수되었음. 이전에는 Docker에서는 docker-compose 명령어가 별도로 설치되어야 했지만, Docker 20.10 버전 이후로는 docker-compose 명령어가 Docker CLI에 통합됨
- docker compose는 최신 도커 버전에서 권장되는 형식. 고로 흡수가 되었어도 옛날 버전에서는 docker-compose 가 안전할 듯
ref :
Docker(4) - 한번에 Container 여러개를 다뤄보자, 'Docker-compose'