flask-basic
Flask под Gunicorn. Используется в уроке 6.9.
Что демонстрирует
- Gunicorn как production-сервер для WSGI —
flask runдля этого не предназначен; - число worker'ов задаётся переменной
WEB_CONCURRENCY, а неos.cpu_count(); - логи Gunicorn направлены в stdout и stderr (
accesslog = "-"); graceful_timeoutменьше grace perioddocker stop;max_requestsс разбросом — защита от накопления утечек памяти;- healthcheck без установки
curl, средствами стандартной библиотеки.
Запуск
docker build -t flask-basic .
docker run -d --name flask -p 8000:8000 flask-basic
curl -s localhost:8000/ | python3 -m json.tool
Или через Compose:
docker compose up -d
docker compose ps # STATUS должен стать healthy
Проверки
Health endpoint:
curl -s localhost:8000/healthz
docker inspect flask --format '{{.State.Health.Status}}'
Несколько worker-процессов — разные PID в ответах:
for i in $(seq 6); do curl -s localhost:8000/ | python3 -c "import json,sys; print(json.load(sys.stdin)['pid'])"; done
Логи доступа идут в stdout, ошибки в stderr:
curl -s localhost:8000/boom > /dev/null
docker logs flask 2>/dev/null | tail -3 # только stdout
docker logs flask 2>&1 1>/dev/null | tail -5 # только stderr
Корректное завершение — Gunicorn обрабатывает SIGTERM:
time docker stop flask
docker inspect flask --format 'exit code: {{.State.ExitCode}}'
Ожидается менее секунды и код 0.
Запуск не от root:
docker exec flask id -u
Изменение числа worker'ов
docker run -d --name flask4 -p 8001:8000 -e WEB_CONCURRENCY=4 flask-basic
docker exec flask4 sh -c 'ps -o pid,args | grep -c "[g]unicorn"'
Уборка
docker rm -f flask flask4 2>/dev/null
docker compose down
docker rmi flask-basic