터칭 데이터
Docker-Compose로 다수의 Container 프로그램 실행하기 (실습 개요) 본문
앞서 매뉴얼하게 실행해본 voting application를 docker-compose를 통해 실행해보자
1. Docker 명령 정리와 2장 퀴즈
2. Docker Volume이란?
3. 다수의 Container로 구성된 소프트웨어 실행
4. Docker-Compose로 다수 Container로 실행해보기
5. Airflow Docker docker-compose.yml 리뷰
지난 시간 voting application을 메뉴얼하게 구성하는 실습으로 1~3번을 진행했습니다.
이번에는 같은 프로그램을 docker-compose 방식으로 실습하며 4번 과정을 진행하겠습니다.
바로 이전 게시물에서 Docker-compose 개념을 익혔으니 이제 실습을 해보려 합니다. 그전에 실습의 개요를 설명드리겠습니다.
Voting application을 docker-compose 실행 실습 개요
앞서 5개의 Container를 일일히 실행했을 때의 문제점
Postgres를 실행하는 부분이 제대로 동작하지 않았음
docker run -d --name=db -e POSTGRES_PASSWORD=password --network mynetwork postgres
메뉴얼 실습을 끝내고 Dogs나 Cats에 투표를 해도 결과창에서는 계속 50:50으로 조회되었습니다.
그 이유는 Worker가 redis에 기록된 투표 결과를 postgres에 적어줘야 하는데
worker/Program.cs (cs는 C#의 확장자) 파일을 살펴보면
var pgsql = OpenDbConnection("Server=db;Username=postgres;Password=postgres;");
var redisConn = OpenRedisConnection("redis");
아래 명령어로 postgres 이미지 db를 빌드할 때 호스트 이름은 db로 제대로 주었지만
docker run -d --name=db -e POSTGRES_PASSWORD=password --network mynetwork postgres
패스워드를 password로 주었기 때문에 posgres와 일치하지도 않고 Username도 주지 않았기 때문입니다.
당연히 OpenDBConnection이 제대로 작동하지 않았을테고 결과가 제대로 반영되지 않았을 겁니다.
이를 해결하려면 Container를 실행할 때 아래 2개의 환경변수를 넘겨주어야 함
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "postgres" (passwor라는 패스워드 대신)
이걸 docker-compose 환경 설정 파일을 통해 넘기면서 해결해볼 예정
docker-compose.yml로 포팅: 뼈대
지난 시간 메뉴얼하게 voting application을 실습할 때 아래 5개의 명령어를 사용했었습니다.
docker run -d --name=redis --network mynetwork redis
docker run -d --name=db -e POSTGRES_PASSWORD=password --network mynetwork postgres
앞서 컨테이너를 하나씩 실행할 때 이 부분은 제대로 동작하지 않았습니다.
docker run -d --name=vote -p 5001:80 --network mynetwork vote
docker run -d --name=result -p 5002:80 --network mynetwork result
docker run -d --name=worker --network mynetwork worker
위의 명령어들을 docker-compose.yml와 docker-compose up을 사용하여
위의 이미지와 같이 보완할 겁니다.
일단 networks와 volumes를 처음에는 쓰지 않을겁니다. volumes를 쓰지 않으니 Data persistency는 보장되지 않고 networks는 docker-compose에서 기본으로 주어지는 default 네트워크를 쓰게될겁니다.
이렇게 처음 실습한 후 조금씩 난이도를 높여가며 yaml파일의 섹션들을 더 자세히 살펴보고 기능 구현을 해보겠습니다.
docker-compose.yml로 포팅: services 키 보기
yml 파일의 services 섹션을 살펴보겠습니다.
수정할 yml 파일의 services 섹션
redis:
image: redis:alpine
db:
image: postgres:15-alpine
vote:
image: vote
ports:
- 5001:80
result:
image: result
ports:
- 5002:80
worker:
image: worker
수정이 된 docker-compose.mac.yml 의 services 섹션
redis:
image: redis:alpine
db:
image: postgres:15-alpine
vote:
build: ./vote
ports:
- 5001:80
result:
build: ./result
ports:
- 5002:80
worker:
build: ./worker
image는 로컬에 이미 빌드된 Docker Image가 존재하지 않으면 Docker Hub에서 이미 빌드된 이미지를 pull로 다운 받고 빌드하겠다는 뜻입니다.
우리가 지난 voting application에서 살펴보았을 때 vote, result, worker 디렉토리의 아래에 Dockerfile이 존재했던 것을 기억하실겁니다. 그리고 Dockerfile로 이미지를 생성(빌드)했었죠? 그래서 image:를 build:로 고쳐 ./vote(result or worker) 아래의 Dockerfile을 읽도록 수정합니다.
Image와 build의 차이점을 상기시키기 위해 별도의 장으로 구성해 설명드렸습니다. 꼭 기억해주세요.
좌측이 수정전, 우측이 수정된 docker-compose.mac.yml입니다.
최종 docker-compose.mac.yml의 내용
https://github.com/learndataeng/example-voting-app/blob/main/docker-compose.mac.yml
# v2 and v3 are now combined!
# docker-compose v1.27+ required
# % docker-compose version
# Docker Compose version v2.15.1
services:
vote:
build: ./vote
# use python rather than gunicorn for local dev
command: python app.py
ports:
- "5001:80"
result:
build: ./result
# use nodemon rather than node for local dev
entrypoint: nodemon server.js
ports:
- "5002:80"
worker:
build: ./worker
redis:
image: redis:alpine
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: "postgres"
POSTGRES_PASSWORD: "postgres"
build와 ports는 똑같은데 command가 있네요? 뒤에서 설명 드리겠지만
vote 디렉토리에 존재하는 Dockerfile에 적힌
(생략..)
FROM base AS dev
RUN pip install watchdog
ENV FLASK_ENV=development
CMD ["python", "app.py"]
(생략..)
CMD의 내용을 docker-compose를 이용해 오버라이드(override)할 때 사용합니다.
즉 Dockerfile 내부에 있는 'CMD' 명령보다 docker-compose.yml 파일에 있는 'command:' 명령이 더 우선시 됩니다.
result에 적힌 entrypoint도 똑같은 맥락으로 override로 이해하시면 됩니다.
db에서 image:만 지정하지 않고 postgres_user와 postgres_password를 세팅했습니다.
그래야 위의 흐름도대로 Worker가 아래의 파일에서 코드대로 db와 연결되어
worker/Program.cs (cs는 C#의 확장자)
var pgsql = OpenDbConnection("Server=db;Username=postgres;Password=postgres;");
var redisConn = OpenRedisConnection("redis");
PostgreSQL와 잘 연결 및 작동되기 때문입니다.
데모(실습)
git clone https://github.com/learndataeng/example-voting-app.git
주의) https://github.com/dockersamples/example-voting-app 와는 다른 repo입니다.
위는 example-voting-app의 원본이고 우리가 데모를 진행할 repo는 원본을 fork한 멘토님의 repo입니다.
cd example-voting-app
먼저 청소 한번 하기
docker container rm -f $(docker container ls -aq)
docker image rm -f $(docker image ls -q)
확인해보기
docker ps -a
docker images
그리고나서 앞의 docker-compose.mac.yml의 내용을 바탕으로 실행해보기
'Docker & K8S' 카테고리의 다른 글
10주차 - 4 [Docker & K8S] (0) | 2023.12.21 |
---|---|
Docker-Compose로 다수의 Container 프로그램 실행하기 (실습) (0) | 2023.12.21 |
다수의 Container 프로그램 실행하기, Docker-Compose 개념 (0) | 2023.12.21 |
Docker & K8S - dockerignore와 맥 port 5000 에러 (0) | 2023.12.21 |
10주차 - 3 [Docker & K8S] (0) | 2023.12.20 |