- Home »

Развёртывание Flask-приложения с Gunicorn на App Platform
Разворачивание Flask-приложений в продакшене до сих пор остается одним из тех моментов, где новички часто спотыкаются. Особенно когда речь идет о выборе между встроенным сервером разработки и полноценным WSGI-сервером вроде Gunicorn. Эта статья поможет вам разобраться с тем, как правильно деплоить Flask-приложения на App Platform, используя Gunicorn в качестве application server’а. Мы пройдемся по всем этапам: от настройки окружения до мониторинга и масштабирования. Это не просто еще одна инструкция, а практическое руководство с реальными примерами и подводными камнями, которые вы точно встретите в процессе.
Что такое App Platform и зачем Gunicorn?
App Platform — это Platform-as-a-Service (PaaS) решение от DigitalOcean, которое позволяет разворачивать приложения без головной боли с конфигурацией серверов. Но если вы предпочитаете больше контроля над инфраструктурой, VPS-сервер даст вам полную свободу действий.
Gunicorn (Green Unicorn) — это Python WSGI HTTP Server для UNIX-систем. Это pre-fork worker модель, которая позволяет обрабатывать несколько запросов одновременно. В отличие от встроенного Flask-сервера, Gunicorn готов к продакшену и может выдержать реальную нагрузку.
Как это работает: архитектура и принципы
Схема работы выглядит примерно так:
- Nginx (опционально) — reverse proxy и статические файлы
- Gunicorn — WSGI-сервер с несколькими worker-процессами
- Flask-приложение — ваш код
- App Platform — управляет всем этим зоопарком
Gunicorn создает master-процесс, который управляет worker-процессами. Каждый worker может обработать один запрос в момент времени. Если один worker падает, master перезапускает его.
Подготовка Flask-приложения
Для начала нужно подготовить само приложение. Создайте простую структуру проекта:
myapp/
├── app.py
├── requirements.txt
├── .app_platform_spec.yaml
└── Procfile
Базовое Flask-приложение в app.py
:
from flask import Flask, jsonify
import os
app = Flask(__name__)
@app.route('/')
def hello():
return jsonify({
'message': 'Hello from Flask + Gunicorn!',
'env': os.environ.get('FLASK_ENV', 'production')
})
@app.route('/health')
def health_check():
return jsonify({'status': 'healthy'})
if __name__ == '__main__':
app.run(debug=True)
Файл requirements.txt
:
Flask==2.3.3
gunicorn==21.2.0
python-dotenv==1.0.0
Настройка Gunicorn
Создайте файл gunicorn_config.py
для конфигурации:
import multiprocessing
import os
# Базовые настройки
bind = f"0.0.0.0:{os.environ.get('PORT', '8080')}"
workers = multiprocessing.cpu_count() * 2 + 1
worker_class = "sync"
worker_connections = 1000
max_requests = 1000
max_requests_jitter = 50
# Таймауты
timeout = 30
keepalive = 2
graceful_timeout = 30
# Логирование
loglevel = "info"
accesslog = "-"
errorlog = "-"
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)s'
# Безопасность
limit_request_line = 4094
limit_request_fields = 100
limit_request_field_size = 8190
# Для отладки
reload = os.environ.get('FLASK_ENV') == 'development'
Конфигурация для App Platform
Создайте файл .app_platform_spec.yaml
:
name: flask-gunicorn-app
services:
- name: web
source_dir: /
github:
repo: your-username/your-repo
branch: main
run_command: gunicorn --config gunicorn_config.py app:app
environment_slug: python
instance_count: 2
instance_size_slug: basic-xxs
http_port: 8080
health_check:
http_path: /health
initial_delay_seconds: 10
period_seconds: 10
timeout_seconds: 5
failure_threshold: 3
success_threshold: 2
env:
- key: FLASK_ENV
value: production
- key: PYTHONUNBUFFERED
value: "1"
Альтернативный способ: Procfile
Если предпочитаете Heroku-style деплой, создайте Procfile
:
web: gunicorn --config gunicorn_config.py app:app
Пошаговое развертывание
Шаг 1: Подготовка репозитория
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/your-username/your-repo.git
git push -u origin main
Шаг 2: Создание приложения на App Platform
Через веб-интерфейс DigitalOcean или с помощью CLI:
doctl apps create --spec .app_platform_spec.yaml
Шаг 3: Мониторинг развертывания
doctl apps list
doctl apps get YOUR_APP_ID
doctl apps logs YOUR_APP_ID --follow
Сравнение различных конфигураций
Параметр | Development | Production (Basic) | Production (High Load) |
---|---|---|---|
Workers | 1 | 2-4 | CPU * 2 + 1 |
Worker Class | sync | sync | gevent/eventlet |
Timeout | 30s | 30s | 60s |
Max Requests | 0 | 1000 | 5000 |
Instance Size | basic-xxs | basic-xs | professional-xs+ |
Продвинутая конфигурация Gunicorn
Для высоконагруженных приложений рекомендую следующую конфигурацию:
# gunicorn_config_advanced.py
import multiprocessing
import os
# Асинхронные воркеры для высокой нагрузки
worker_class = "gevent"
worker_connections = 1000
workers = multiprocessing.cpu_count() * 2 + 1
# Настройки для работы с базой данных
max_requests = 1000
max_requests_jitter = 100
preload_app = True
# Кастомные хуки
def when_ready(server):
server.log.info("Server is ready. Spawning workers")
def worker_int(worker):
worker.log.info("worker received INT or QUIT signal")
def pre_fork(server, worker):
server.log.info("Worker spawned (pid: %s)", worker.pid)
def post_fork(server, worker):
server.log.info("Worker spawned (pid: %s)", worker.pid)
# Здесь можно инициализировать connection pool
Мониторинг и отладка
Для мониторинга приложения добавьте эндпоинты:
@app.route('/metrics')
def metrics():
return jsonify({
'workers': os.environ.get('WEB_CONCURRENCY', 1),
'memory_usage': get_memory_usage(),
'uptime': get_uptime()
})
def get_memory_usage():
import psutil
process = psutil.Process(os.getpid())
return process.memory_info().rss / 1024 / 1024 # MB
def get_uptime():
import time
return time.time() - start_time
Работа с переменными окружения
Создайте файл .env
для локальной разработки:
FLASK_ENV=development
DATABASE_URL=postgresql://user:pass@localhost/mydb
REDIS_URL=redis://localhost:6379
SECRET_KEY=your-secret-key-here
И загружайте их в приложении:
from dotenv import load_dotenv
load_dotenv()
app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY')
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL')
Альтернативные решения
Если App Platform не подходит, рассмотрите альтернативы:
- Docker + Kubernetes — для максимального контроля
- Heroku — классический PaaS
- AWS Elastic Beanstalk — если уже используете AWS
- Google Cloud Run — serverless контейнеры
- VPS с ручной настройкой — аренда VPS для полного контроля
Производительность и масштабирование
Для высокопроизводительных приложений можно использовать:
# Конфигурация для gevent
worker_class = "gevent"
worker_connections = 1000
workers = multiprocessing.cpu_count() * 2 + 1
# Или для uvicorn (если используете FastAPI совместно)
worker_class = "uvicorn.workers.UvicornWorker"
Для критически важных приложений рассмотрите выделенный сервер с полным контролем над железом.
Распространенные ошибки и их решения
Ошибка 1: Worker timeout
# Увеличьте timeout в конфигурации
timeout = 60
graceful_timeout = 30
Ошибка 2: Память заканчивается
# Добавьте ограничения
max_requests = 1000
max_requests_jitter = 50
Ошибка 3: Health check не проходит
# Убедитесь, что endpoint доступен
@app.route('/health')
def health():
return {'status': 'ok'}, 200
Автоматизация и CI/CD
Создайте GitHub Action для автоматического деплоя:
# .github/workflows/deploy.yml
name: Deploy to App Platform
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy to App Platform
uses: digitalocean/app_action@v1.1.5
with:
app_name: flask-gunicorn-app
token: ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
Полезные команды для отладки
# Проверка статуса приложения
doctl apps get YOUR_APP_ID
# Просмотр логов
doctl apps logs YOUR_APP_ID --type=run --follow
# Масштабирование
doctl apps update YOUR_APP_ID --spec updated_spec.yaml
# Локальная отладка
gunicorn --reload --bind 0.0.0.0:8000 app:app
# Проверка конфигурации
gunicorn --check-config gunicorn_config.py app:app
Заключение и рекомендации
Разворачивание Flask-приложений с Gunicorn на App Platform — это отличный баланс между простотой и производительностью. Основные выводы:
- Для небольших проектов — App Platform с базовой конфигурацией Gunicorn
- Для средних проектов — добавьте кастомную конфигурацию и мониторинг
- Для высоконагруженных приложений — используйте async воркеры и подумайте о выделенном сервере
- Всегда настраивайте health checks — это основа стабильности
- Мониторьте метрики — memory usage, response time, error rate
App Platform избавляет от многих проблем DevOps, но понимание того, как работает Gunicorn под капотом, поможет вам оптимизировать производительность и быстро решать проблемы. Если же нужен полный контроль над окружением, VPS-сервер даст вам все необходимые инструменты для кастомной настройки.
В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.
Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.