- 출처: https://docs.docker.com/compose/gettingstarted/
- 목적
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 |
댓글