Docker Compose (번역)

2023. 5. 6. 19:25리눅스 실제 사용 팁/Docker

작성일 : 2020. 11. 29.

 

[역자 주] 개인적으로 현재까지는 docker compose 를 써본 적이 없다. 도커 컨테이너 여러 개를 유기적으로 실행해서 서로 통신할 수 있게 하는 거란다. 관련된 검색결과를 따라가봤더니 postgres DB와 파이썬 기반 웹서비스 프레임워크를 실행하는 예제가 있었다. 따라하다가 파이썬 자체 오류가 나서 중간에 때려치웠다.

 

도커 자체 문서를 따라가면서 익혀 봐야겠다.

아래의 글은

Get started with Docker Compose

에서 가져온 글이다. 원문을 번역해서 내 머리에 쏘옥 넣기 위한 것이다.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

(읽고 이해하는데 대략 11 분쯤 걸릴 것으로 예상)

 

본 글에서는 Docker Compose 에서 실행되는 파이썬 웹 애플리케이션을 구축(걍 '빌드'로 번역할까)해볼 것이다. Flask (플라스크) 프레임워크를 활용하며 Redis 에서 hit counter 를 maintain 하게 된다. 샘플로 파이썬을 사용하기에, 당장에 파이썬에 익숙하지 않더라도 여기서 다루는 컨셉 정도는 이해할 수 있어야 한다.

준비물

시스템에 도커 엔진도커 컴포즈가 설치되어 있어야 한다. 파이썬과 레디스(Redis DB) 는 샘플 도커 이미지에서 제공할 것이므로 설치하지 않아도 된다.

1단계: 설정하기

애플리케이션 종속성(상호 의존성 라이브러리?)을 정의한다.

 

1. 프로젝트 디렉토리를 생성하라 (역자 주: 아래 예제에서는 'composetest' 라는 이름을 쓰기로 함)

$ mkdir composetest
$ cd composetest

 

2. app.py 파일을 만든 후, 아래의 코드를 붙여 넣는다.

(역자 주: 파이썬은 스페이스의 영향을 많이 받는 언어다. 일정한 간격 또는 탭을 쓰되, 둘을 섞어서 쓰지 않기 바란다)

import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)
@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

위 코드에서 host='redis' 부분; 여기서 redis 는 애플리케이션 네트워크에서 레디스 컨테이너를 가리키는 호스트네임이다. 사용하는 포트는 레디스 기본설정인 6379 를 그대로 쓰겠다.

 

Handling transient errors

Note the way the get_hit_count function is written. This basic retry loop lets us attempt our request multiple times if the redis service is not available. This is useful at startup while the application comes online, but also makes our application more resilient if the Redis service needs to be restarted anytime during the app’s lifetime. In a cluster, this also helps handling momentary connection drops between nodes.

 

3. requirements.txt 파일을 만들고 아래의 코드를 붙여 넣는다.

flask
redis

2단계: Dockerfile 만들기

이번 장에서는 도커 이미지를 빌드할 때 활용되는 Dockerfile 을 만들 것이다.

(역자 주: 도커 명세를 좌르륵 기술해놓은 파일)

 

우리가 만들 도커 이미지에는 파이썬 자체는 물론, 파이썬 애플리케이션에서 필요로 하는 의존성 꾸러미도 포함된다.

프로젝트 디렉토리에서 'Dockerfile' (역자 주: 이게 파일명이다) 을 만들고 아래 내용을 붙여 넣는다.

FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]

위 도커 명세는 이렇다:

  • (역자 주: 공식저장소에 비치된) 'python 3.7' 이미지를 본을 떠서 새 이미지를 빌드한다.
  • 작업 디렉토리를 '/code' 로 바꾼다.
  • flask 커맨드에서 사용하는 환경변수를 설정한다. (역자 주: 'FLASK_APP', 'FLASK_RUN_HOST' <-- 이것들인가 보다)
  • gcc 와 그것에 종속된 꾸러미를 설치한다.
  • requirements.txt 파일을 복사하고 파이썬 종속 꾸러미들을 설치한다. (역자 주: requirements.txt 에 기록된 필수 꾸러미)
  • 이미지에 (도커) 컨테이너가 5000 을 서비스 포트번호로써 열어 놓고 있음을 알린다. (컨테이너로 실행 시 항시 대기 중)
  • Copy the current directory . in the project to the workdir . in the image.
  • 컨테이너로 실행 시 기본적으로 호출될 커맨드를 설정한다. (역자 주: 'flask run' 으로 Flask 를 실행하나 보다.)

(역자 주 : 도커에서 이미지 빌드 시, 주로 기존에 이미 만들어져 있는 이미지를 기본 이미지로 삼아서 살을 덧붙이는 편이다.

이 때, 기본 이미지를 메모리로 읽어 들여서(이게 컨테이너) 위의 명세대로 작업을 하고 새 이미지로 저장하는 방식이다.)

 

Dockerfile 작성방법에 대해 더 깊이 알고 싶다면 Docker user guideDockerfile reference 를 참고하기 바란다.

3단계: 컴포즈 파일에 서비스 목록 정의하기

프로젝트 디렉토리에 docker-compose.yml 을 생성하고 다음을 붙여 넣는다.

version: "3.8"
services:
  web:
    build: .
    ports:
      - "5000:5000"
  redis:
    image: "redis:alpine"

services 필드 아래에 web 과 redis 를 서비스로 정의한다.

Web service

위의 'web' 은 현재 디렉토리에 존재하는 Dockerfile 로부터 빌드한 이미지를 사용한다. (build)

그런 다음에는 컨테이너를 실행하는 호스트 컴퓨터와 컨테이너의 5000번 포트를 서로 연결한다. (ports)

본 예제에서는 Flask 웹서버의 기본 포트인 5000 을 그대로 활용함.

Redis service

위의 'redis' 서비스는 Docker hub registry(도커 허브 레지스트리)에서 끌어 온 Redis 공식 이미지를 활용한다.

 

4단계: 컴포즈(compose) 로 앱을 빌드해서 실행하기

1. 프로젝트 디렉토리에서 'docker-compose up'  명령으로 애플리케이션을 실행한다.

$ docker-compose up
Creating network "composetest_default" with the default driver
Creating composetest_web_1 ...
Creating composetest_redis_1 ...
Creating composetest_web_1
Creating composetest_redis_1 ... done
Attaching to composetest_web_1, composetest_redis_1
web_1    |  * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
redis_1  | 1:C 17 Aug 22:11:10.480 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis_1  | 1:C 17 Aug 22:11:10.480 # Redis version=4.0.1, bits=64, commit=00000000, modified=0, pid=1, just started
redis_1  | 1:C 17 Aug 22:11:10.480 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
web_1    |  * Restarting with stat
redis_1  | 1:M 17 Aug 22:11:10.483 * Running mode=standalone, port=6379.
redis_1  | 1:M 17 Aug 22:11:10.483 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
web_1    |  * Debugger is active!
redis_1  | 1:M 17 Aug 22:11:10.483 # Server initialized
redis_1  | 1:M 17 Aug 22:11:10.483 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
web_1    |  * Debugger PIN: 330-787-903
redis_1  | 1:M 17 Aug 22:11:10.483 * Ready to accept connections

docker-compose 명령은 Redis 이미지를 내려 받아서 앞서 언급한 코드 블럭으로 도커 이미지를 생성한 다음, 정의한 서비스들을 실행한다. 코드는 이미지 빌드 시에 정적으로 복사된다.

 

2. 웹브라우저에서 http://localhost:5000/ 로 접속하면 애플리케이션이 실행되는지 확인해볼 수 있다.

'http://localhost:5000' 를 인식하지 못하면 'http://127.0.0.1:5000' 으로 시도해보기 바란다.

(역자 주: 5000 포트로 접속 시 본 예제에서 준비한 'Hello World' 가 잘 나오는지 보기 위함이다)

 

그래도 호스트를 인식하지 못한다면, 윈도우즈나 맥에 한해서, docker-machine ip MACHINE_VM 를 써서 IP 주소를 알 수 있다고

 

If you’re using Docker natively on Linux, Docker Desktop for Mac, or Docker Desktop for Windows, then the web app should now be listening on port 5000 on your Docker daemon host. Point your web browser to http://localhost:5000 to find the Hello World message. If this doesn’t resolve, you can also try http://127.0.0.1:5000.

If you’re using Docker Machine on a Mac or Windows, use docker-machine ip MACHINE_VM to get the IP address of your Docker host. Then, open http://MACHINE_VM_IP:5000 in a browser.

You should see a message in your browser saying:

'리눅스 실제 사용 팁 > Docker' 카테고리의 다른 글

Docker : Oracle Database  (0) 2023.08.08
Dockerfile  (0) 2023.08.01
Docker 외부 파일을 가져오기 (Import)  (0) 2023.05.06
Docker 이미지를 파일로 내보내기 (Export)  (0) 2023.05.06
Docker 빌드하기  (0) 2023.05.06