Разработка

Как правильно экспортировать зависимости Python в Docker

Введение

Экспортировать зависимости python в докер — задача, кажущаяся тривиальной, но часто приводящая к раздуванию образов и медленным сборкам. Классический подход с копированием requirements.txt игнорирует возможности кэширования слоёв. Разберём проверенные методы оптимизации процесса.

Проблемы классического подхода

Типичный Dockerfile содержит уязвимую структуру:

COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .

Любое изменение исходного кода сбрасывает кэш команды RUN pip install. Образы также накапливают лишние утилиты сборки, что критично для финальных стадий развёртывания.

Оптимизация через BuildKit

Используйте двухэтапный процесс. Активация BuildKit через DOCKER_BUILDKIT=1 открывает доступ к продвинутому кэшированию.

FROM python:3.11-slim AS builder
RUN pip install --no-cache-dir --prefix=/install uv
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --target=/install

FROM python:3.11-slim
COPY --from=builder /install /usr/local
COPY . /app
WORKDIR /app
CMD ["python", "main.py"]

Инструмент uv ускоряет установку в десятки раз благодаря параллельной загрузке. Флаг —frozen жёстко фиксирует версии, исключая дрейф зависимостей.

Сравнение методов

Метод Время сборки Размер Кэш
pip + requirements.txt Высокое Среднее Низкое
uv + pyproject.toml Низкое Минимальное Высокое
Мультистейдж Оптимальное Минимальное Максимальное

Практические рекомендации

Разделяйте установку пакетов и копирование кода. Используйте slim-образы для снижения поверхности атаки. Настройте BuildKit в CI/CD. Избегайте установки build-essential без крайней необходимости.

Вопрос-ответ (FAQ)

Зачем использовать двухэтапную сборку?

Она отделяет среду сборки от выполнения. В финальный образ попадают только бинарники, что снижает размер и исключает лишние утилиты.

Как кэшировать зависимости при изменении кода?

Размещайте RUN pip install или uv sync до COPY . .. Кэш переиспользуется, если файлы версий не изменены.

Можно ли использовать requirements.txt с uv?

Да, но не рекомендуется. uv требует pyproject.toml и uv.lock для детерминированных сборок. requirements.txt не фиксирует транзитивные зависимости точно.

Читать далее

Диагностика проблем с производительностью PostgreSQL

Введение

Производительность postgresql напрямую влияет на стабильность бизнес-процессов. Когда запросы замедляются, требуется системная диагностика. Чтобы диагностировать производительность postgresql без догадок, двигайтесь от ресурсов ОС к SQL-планам.

Начните с проверки CPU, памяти и диска. Высокий iowait или нехватка RAM заставят БД ждать. Используйте top, iostat для оценки нагрузки на уровне системы.

Инструменты и метрики

Представления pg_stat_activity и pg_stat_statements отслеживают сессии и топ-запросы. Для точного анализа всегда применяйте EXPLAIN (ANALYZE, BUFFERS). Это раскроет реальные затраты CPU, I/O и сканируемые строки.

Инструмент Назначение Ключевые метрики
pg_stat_activity Мониторинг сессий state, wait_event, query_start
pg_stat_statements Агрегация запросов mean_exec_time, calls, shared_blks_hit
EXPLAIN ANALYZE План выполнения actual_time, rows, loops
pg_stat_bgwriter Фоновая запись writes, checkpoints_timed

В облачных платформах доступны готовые функции Performance Diagnostics для визуализации трендов. Современные методики также используют верификацию через нейросетевые модели и утилиты вроде pgpro_pwr для ускорения поиска узких мест.

Практический пример

Запрос для поиска самых ресурсоемких команд:

SELECT query, calls, mean_exec_time, rows
FROM pg_stat_statements
WHERE dbid = (SELECT oid FROM pg_database WHERE datname = current_database())
ORDER BY mean_exec_time DESC
LIMIT 10;

Проанализируйте результат через EXPLAIN ANALYZE. Ищите Sequential Scan вместо Index Scan или проблемы с блокировками. Меняйте конфигурацию (shared_buffers, work_mem) только после анализа, а не наугад.

Регулярная диагностика предотвращает деградацию. Собирайте метрики, настраивайте алертинг и применяйте индексы точечно. Это обеспечит стабильную работу postgresql под нагрузкой.

Вопрос-ответ (FAQ)

Что делать, если pg_stat_statements не показывает данные?

Убедитесь, что расширение установлено: CREATE EXTENSION pg_stat_statements;. Проверьте параметр track_statements в конфигурации.

Как найти медленные запросы в реальном времени?

Используйте pg_stat_activity с фильтром по wait_event_type или state = ‘active’. Для логирования slow queries настройте log_min_duration_statement.

Стоит ли использовать внешние мониторинговые дашборды?

Да, инструменты вроде pgwatch2 или облачные панели (Performance Diagnostics) дают наглядную картину трендов и упрощают рутинную диагностику.

Читать далее

Настройка безопасности Nginx как обратного прокси сервера

Настройка безопасности обратного прокси Nginx

Введение

Обратный прокси на базе Nginx стал стандартом для маршрутизации трафика и защиты бэкендов. Базовая конфигурация не защищает от современных угроз. Чтобы правильно настроить безопасность nginx, внедрите многоуровневый подход: шифрование, фильтрацию и контроль доступа.

Минимизация поверхности атак

Скройте служебную информацию. Отключите версию сервера и лишние заголовки. Это усложнит подбор уязвимостей.

server_tokens off;
server_name_in_redirect off;
proxy_hide_header X-Powered-By;
add_header X-Content-Type-Options nosniff always;

Настройка TLS

Используйте только TLS 1.2 и 1.3. Отключите слабые шифры, включите HSTS и OCSP-stapling.

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
add_header Strict-Transport-Security "max-age=63072000" always;

Ограничение скорости

Без rate limiting сервер быстро исчерпает ресурсы. Используйте limit_req для защиты от брутфорса.

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req zone=api burst=20 nodelay;

Сравнение методов фильтрации

Метод Назначение Производительность
limit_req Защита от сканеров Высокая
geo / map Блокировка по IP Средняя
ModSecurity WAF и анализ Низкая

Интеграция с CDN

Связка Nginx с Cloudflare снимет L3/L4 атаки. Передавайте реальный IP через X-Forwarded-For для логирования и геоблокировки.

Вопрос-ответ (FAQ)

Как проверить конфигурацию?

Запустите nginx -t. При успехе примените nginx -s reload без разрыва соединений.

Влияет ли WAF на скорость?

Да, анализ payload добавляет задержку. Размещайте модуль в отдельном контейнере или используйте ускорители.

Что делать при утечке заголовков?

Добавьте proxy_hide_header для каждого заголовка. Используйте proxy_pass_request_headers off и явно укажите нужные через proxy_set_header.

Читать далее

Сравнение Docker и Docker Compose для Python приложений

Введение

Развертывание Python-проектов требует стабильной и воспроизводимой среды исполнения. Многие инженеры путают базовый инструмент контейнеризации и оркестратор для локальной разработки. Чтобы корректно сравнить Docker и Docker Compose в контексте Python-стека, необходимо понимать их архитектурные различия, точки пересечения и реальные сценарии использования.

Архитектура и назначение

Docker — это платформа для создания, доставки и запуска изолированных контейнеров. Для Python он гарантирует, что зависимости (pip-пакеты, версии интерпретатора, системные библиотеки вроде libpq-dev) будут идентичны на машине разработчика, CI/CD и продакшене. Вы описываете образ через Dockerfile, собираете его и запускаете как единый процесс, полностью заменяя локальные виртуальные окружения.

Современное Python-приложение редко живет в одиночку. Типичный стек включает базу данных (PostgreSQL), кэш (Redis), брокер сообщений (RabbitMQ) или асинхронные воркеры Celery. Здесь на сцену выходит docker compose. Это декларативный инструмент, который описывает многоконтейнерную архитектуру в одном YAML-файле. Он автоматически настраивает внутренние сети, монтирует томы и управляет порядком запуска сервисов.

Ключевые отличия

Прямое сравнение Docker и Docker Compose показывает, что это не конкуренты, а взаимодополняющие компоненты экосистемы. Docker отвечает за упаковку, билдинг и изоляцию бинарных артефактов. Compose выступает в роли планировщика и координатора, который читает манифест и запускает кластер контейнеров как единое целое. При сравнении подходов становится очевидно: для изоляции конкретного скрипта или API-эндпоинта достаточно Dockerfile, а для полноценного веб-приложения с БД и очередями обязателен Compose.

Критерий Docker (CLI/Dockerfile) Docker Compose
Основная задача Сборка и запуск одиночных образов Управление многоконтейнерными стеками
Формат описания Dockerfile docker-compose.yml
Сеть и томы Настройка вручную через флаги Автоматическое создание по спецификации
Управление циклом docker build/run/stop docker compose up/down
Применение в Python Локальные скрипты, фоновые задачи Веб-фреймворки (Django/FastAPI) с БД

Практическая реализация

В типичном Python-проекте эти инструменты работают в связке. Сначала описывается Dockerfile для сборки образа приложения:

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0"]

Затем создается docker-compose.yml для запуска веб-сервиса и базы данных:

services:
  web:
    build: .
    ports: ["8000:8000"]
    volumes: ["./src:/app/src"]
    depends_on: [db]
  db:
    image: postgres:15
    environment:
      POSTGRES_DB: myapp
      POSTGRES_PASSWORD: secret

Итоги

Выбор инструмента зависит от сложности архитектуры. Используйте Dockerfile для изоляции конкретного процесса. Применяйте docker compose, когда нужно поднять полный стек разработки за одну команду. В профессиональной Python-разработке эти технологии неразрывны: Compose запускает контейнеры, собранные Dockerfile, обеспечивая бесшовный переход от локального тестирования к продакшену.

Вопрос-ответ (FAQ)

Можно ли использовать Compose без Dockerfile?

Да, в docker-compose.yml можно указать готовый образ из Docker Hub, но для кастомного Python-приложения сборка через Dockerfile является отраслевым стандартом.

Как перенести приложение с локальной машины на сервер?

Команда docker compose up создаст все сервисы локально. Для продакшена обычно используют тот же YAML-файл, развернутый через Docker Swarm или Kubernetes.

Влияет ли Compose на производительность Python-кода?

Нет, Compose не исполняет код, а только управляет жизненным циклом контейнеров. Производительность зависит от ресурсов хоста, оптимизации самого Python-приложения и настроек ядра Linux.

Читать далее