Главная/Материалы/Материал

flask-basic

Flask под Gunicorn. Используется в уроке 6.9.

Что демонстрирует

  • Gunicorn как production-сервер для WSGI — flask run для этого не предназначен;
  • число worker'ов задаётся переменной WEB_CONCURRENCY, а не os.cpu_count();
  • логи Gunicorn направлены в stdout и stderr (accesslog = "-");
  • graceful_timeout меньше grace period docker stop;
  • max_requests с разбросом — защита от накопления утечек памяти;
  • healthcheck без установки curl, средствами стандартной библиотеки.

Запуск

bash
docker build -t flask-basic .
docker run -d --name flask -p 8000:8000 flask-basic
curl -s localhost:8000/ | python3 -m json.tool

Или через Compose:

bash
docker compose up -d
docker compose ps      # STATUS должен стать healthy

Проверки

Health endpoint:

bash
curl -s localhost:8000/healthz
docker inspect flask --format '{{.State.Health.Status}}'

Несколько worker-процессов — разные PID в ответах:

bash
for i in $(seq 6); do curl -s localhost:8000/ | python3 -c "import json,sys; print(json.load(sys.stdin)['pid'])"; done

Логи доступа идут в stdout, ошибки в stderr:

bash
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:

bash
time docker stop flask
docker inspect flask --format 'exit code: {{.State.ExitCode}}'

Ожидается менее секунды и код 0.

Запуск не от root:

bash
docker exec flask id -u

Изменение числа worker'ов

bash
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"'

Уборка

bash
docker rm -f flask flask4 2>/dev/null
docker compose down
docker rmi flask-basic
Markdown на GitHub ↗