소통하는 개발자 Sean
article thumbnail

👻 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
  1. docker-compose.yml 파일을 기반으로 Docker Compose가 서비스를 정의하고 구성합니다. 위의 예제에서는 db 서비스와 app 서비스가 정의되어 있습니다.
  2. db 서비스와 app 서비스가 각각 MySQL과 WordPress를 실행하는 컨테이너를 생성합니다. db 서비스는 MySQL 컨테이너를, app 서비스는 WordPress 컨테이너를 실행합니다.
  3. networks 키 아래에 'wordpress_net' 네트워크를 정의하고, 각 서비스의 networks 설정을 통해 해당 네트워크에 서비스를 연결합니다. **driver: bridge**는 가장 일반적인 네트워크 드라이버로, 서비스가 동일한 네트워크 내에서 서로 통신할 수 있게 해줍니다.
  4. docker-compose -f docker-compose.yml up -d 명령어의 d 옵션은 컨테이너를 백그라운드 모드로 실행하라는 의미입니다. 즉, 컨테이너가 백그라운드에서 실행되며 콘솔을 차지하지 않습니다.
  5. 컨테이너가 실행된 후, 각 서비스의 설정에 따라 컨테이너 간의 의존성이 관리됩니다. 위의 예제에서는 app 서비스가 db 서비스에 의존하므로 db 컨테이너가 먼저 실행되고 그 다음에 app 컨테이너가 실행됩니다.
  6. 컨테이너가 실행되면 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 (2)

Docker(4) - 한번에 Container 여러개를 다뤄보자, 'Docker-compose'

 

profile

소통하는 개발자 Sean

@Sean-creative

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!