본문 바로가기
Framework and Tool/Docker

Docker compose - Tutorials

by ocwokocw 2023. 10. 12.

- 출처: https://docs.docker.com/compose/gettingstarted/

 

Try Docker Compose

Check out this tutorial on how to use Docker Compose from defining application dependencies to experimenting with commands.

docs.docker.com

 

- 목적

Docker Compose의 핵심 개념을 알아보기 위해 간단한 Python web app을 구성해본다. Docker Engine과 Docker Compose가 standalone binaries로 설치되어 있거나 Docker Desktop이 설치되어 있어야 한다.


 

- Step 1: app 의존성 정의

1. project를 위한 directory 생성

docker-compose % mkdir composetest
docker-compose % 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)

3. requirements.txt 파일 생성후 아래 코드 복사

flask
redis

- Step 2: Dockerfile 생성

Dockerfile은 Docker image를 build하기 위해 사용된다. 이미지에는 Python 자체를 포함해서 app에 필요한 의존성들을 포함하고 있다. project directory에 Dockerfile 을 생성하고 아래 코드를 복사한다.

# syntax=docker/dockerfile:1
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"]

Dockerfile의 의미를 살펴보면 아래와 같다.

  • 이미지로 python 3.7 version을 사용했다.
  • /code 를 working directory로 설정
  • flask에 사용될 환경 변수 정의
  • gcc 및 기타 설치
  • requirements.txt 를 복사하고 Python 의존성 설치
  • container에게 5000 port를 수신하라고 기술
  • 현재 local의 project directory 를 image 내의 work directory로 복사
  • container의 default command를 "flask run"으로 설정

- Step 3: Compose file에 service 정의

project directory에 compose.yaml 파일을 아래 내용으로 생성한다.

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

이 compose file은 web과 redis 2개의 service로 구성되어 있다.

web service는 현재 directory내의 Dockerfile로 부터 build된 이미지를 사용한다. 그 후 host machine의 8000 port가 container의 5000 port와 연동시킨다. 

redis service는 Docker Hub registry로 부터 공개된 Redis image를 받아오도록 선언하였다.


- Step 4: Compose로 build and run

docker compose up 명령어를 실행해보자.

composetest % docker compose up
...
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
[+] Running 3/3
 ⠿ Network composetest_default    Created                                                                                                        0.0s
 ⠿ Container composetest-web-1    Created                                                                                                        0.1s
 ⠿ Container composetest-redis-1  Created                                                                                                        0.1s
Attaching to composetest-redis-1, composetest-web-1
composetest-redis-1  | 1:C 14 Oct 2023 11:23:54.291 * oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
composetest-redis-1  | 1:C 14 Oct 2023 11:23:54.291 * Redis version=7.2.1, bits=64, commit=00000000, modified=0, pid=1, just started
composetest-redis-1  | 1:C 14 Oct 2023 11:23:54.291 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
composetest-redis-1  | 1:M 14 Oct 2023 11:23:54.291 * monotonic clock: POSIX clock_gettime
composetest-redis-1  | 1:M 14 Oct 2023 11:23:54.291 * Running mode=standalone, port=6379.
composetest-redis-1  | 1:M 14 Oct 2023 11:23:54.292 * Server initialized
composetest-redis-1  | 1:M 14 Oct 2023 11:23:54.292 * Ready to accept connections tcp
composetest-web-1    |  * Serving Flask app 'app.py'
composetest-web-1    |  * Debug mode: off
composetest-web-1    | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
composetest-web-1    |  * Running on all addresses (0.0.0.0)
composetest-web-1    |  * Running on http://127.0.0.1:5000
composetest-web-1    |  * Running on http://172.20.0.3:5000
composetest-web-1    | Press CTRL+C to quit

http://localhost:8000 로 접속해서 새로고침을 해보면 "Hello World! I have been seen 5 times." 문구의 숫자가 변경되는것을 볼 수 있다.


- Step 5: bind mount

web service에 bind mount를 추가하기 위해 compose.yaml을 수정해보자. 

services:
  web:
    build: .
    ports:
      - "8000:5000"
    volumes:
      - .:/code
    environment:
      FLASK_DEBUG: "true"
  redis:
    image: "redis:alpine"

volumes 은 host의 project directory를 container 내의 /code로 mount 하는데, 이렇게하면 image를 다시 build할 필요 없이 code를 수정할 수 있다. environment에서 설정한 FLASK_DEBUG 환경 변수를 설정하면 flask rund을 개발 mode로 실행하여 코드 변경시 reload 한다.


- Step 6: Re-build 

다시 build하기 위해 docker compose up 명령어를 다시 실행한다. 


- Step 7: Update the application

application code가 container로 mount 되었으므로 코드 수정이 곧바로 반영된다. app.py 코드중 인삿말 문구를 수정하고 저장해보자.

return 'Hello from Docker! I have been seen {} times.\n'.format(count)

browser에서 새로고침을 해보면 수정된 문구가 곧바로 반영되는것을 알 수 있다. 

'Framework and Tool > Docker' 카테고리의 다른 글

Docker compose - Overview and Feature  (0) 2023.10.12
Swarm - routing mesh  (1) 2023.10.08
Swarm - drain node  (0) 2023.10.02
Swarm - Rolling update  (0) 2023.10.02
Swarm mode tutorial  (0) 2023.10.02

댓글