Гид по технологиям

Flask + PostgreSQL: микросервис с Docker

6 min read DevOps Обновлено 14 Dec 2025
Flask + PostgreSQL: микросервис с Docker
Flask + PostgreSQL: микросервис с Docker

Открытый ноутбук с редактором кода на экране

Микросервис — это небольшое приложение, выполняющее отдельную бизнес‑функцию. В отличие от монолита, микросервисы позволяют независимо развёртывать, масштабировать и сопровождать компоненты системы. В этом руководстве вы реализуете простой пользовательский микросервис на Flask, подключённый к PostgreSQL, и запустите его в Docker.

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

Архитектура микросервиса

Микросервисная архитектура разбивает большую систему на изолированные сервисы. Каждый сервис отвечает за «свою» бизнес‑функцию и может иметь собственную базу данных и окружение. Связь между сервисами обычно идёт по HTTP/REST, gRPC или через брокеры сообщений (RabbitMQ, Kafka).

Серые металлические поручни

Преимущества:

  • независимое развёртывание;
  • изоляция отказов;
  • возможность выбирать технологии для каждого сервиса.

Ограничения:

  • сложнее наблюдаемость и отладка;
  • межсервисная коммуникация добавляет задержки;
  • требования к управлению данными и транзакциям усложняются.

Настройка PostgreSQL (быстрый старт)

Если PostgreSQL у вас не установлен, выберите вариант: локальная установка, облачный сервис или удалённая база данных. В этом примере мы используем Render (бесплатный тариф) для быстрого развёртывания тестовой базы.

  1. Перейдите на сайт Render, зарегистрируйтесь и откройте панель инструментов (dashboard).

Домашняя страница Render

  1. На панели выберите сервис PostgreSQL.

Список веб-сервисов на панели Render

  1. На странице параметров базы заполните поля. Выберите бесплатный тариф и нажмите Create database.

Страница настроек новой базы PostgreSQL на Render

Скопируйте внешний URL базы данных из страницы настроек. Он понадобится для подключения через SQLAlchemy.

Примечание: для продакшен‑баз используйте защищённые учётные данные, TLS и белые списки IP, где возможно.

Создание микросервиса на Flask

Ниже — шаги для создания проекта, установки зависимостей и написания простого API для управления пользователями.

Создайте структуру проекта

В терминале выполните:

mkdir flask-microservice
cd flask-microservice

Установите virtualenv и создайте виртуальное окружение:

pip install virtualenv
virtualenv venv
# Windows:
.\venv\Scripts\activate
# Unix/macOS:
source venv/bin/activate

Установите зависимости

Создайте файл requirements.txt в корне проекта и добавьте:

flask
psycopg2-binary
sqlalchemy

Установите пакеты:

pip install -r requirements.txt

Реализация сервера Flask

Создайте файл service.py в корне проекта и добавьте код ниже. Комментарии оставлены для пояснений.

from flask import Flask, request, jsonify
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
import psycopg2

app = Flask(__name__)

# Замените URL на ваш внешний URL из Render или другой БД
engine = create_engine("postgresql+psycopg2://flask_service_fe0v_user:4785MhjfkdjfhjfjyUx67O2Nuzjchb2MQIP@dpg-chffjfjdkgfk54d6mb7860-a.oregon-postgres.render.com/flask_service_fe0v")

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50))

Base.metadata.create_all(engine)
print("Table 'users' created successfully.")
Session = sessionmaker(engine)

@app.route("/api/user", methods=["POST"])
def create_user():
    data = request.get_json()
    name = data["name"]
    try:
        session = Session()
        new_user = User(name=name)
        session.add(new_user)
        session.commit()
        return {"id": new_user.id, "name": new_user.name, "message": f"User {name} created."}, 201
    except Exception as e:
        print(f"The error '{e}' occurred.")
        return {"error": "An error occurred while creating the user."}, 500

@app.route("/api/user", methods=["GET"])
def get_all_users():
    try:
        session = Session()
        users = session.query(User).all()
        if users:
            result = []
            for user in users:
                result.append({"id": user.id, "name": user.name})
            return jsonify(result)
        else:
            return jsonify({"error": f"Users not found."}), 404
    except Exception as e:
        print(f"The error '{e}' occurred.")
        return {"error": "An error occurred while getting all users."}, 500

if __name__ == "__main__":
    app.run(debug=True, host="0.0.0.0")

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

Тестирование локально

Запустите сервис в разработческом режиме:

flask --app service run

Откройте Postman или curl для проверки endpoint’ов. Пример POST‑запроса для добавления пользователя:

POST-запрос HTTP API в Postman

Ответ должен содержать id созданного пользователя или сообщение об ошибке.

Контейнеризация с Docker

Docker позволяет упаковать приложение и его зависимости в контейнер. Ниже — простой Dockerfile для нашего сервиса.

Создайте Dockerfile в корне проекта:

FROM python:3.9-alpine
WORKDIR /app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "./service.py"]

Постройте образ и запустите контейнер:

docker build -t flask-microservice .
docker run -p 5000:5000 flask-microservice

Контейнер откроет порт 5000. Доступ к сервису будет по http://localhost:5000.

Примечание: для продакшена используйте более устойчивую базу образов, multi‑stage сборку, non‑root пользователя и переменные окружения для секретов.

Практики безопасности и рекомендации

Важно выполнить следующие шаги перед развертыванием в продакшен:

  • Храните секреты (пароли, строки подключения) в менеджере секретов или переменных окружения, а не в коде.
  • Включите TLS/HTTPS для всех входящих соединений.
  • Ограничьте доступ к базе данных через белые списки IP и сеть сервисов.
  • Настройте журналы доступа и централизованную систему логирования.
  • Добавьте мониторинг (метрики и алерты) и трассировку запросов (OpenTelemetry).
  • Регулярно обновляйте зависимости и базовый образ Docker.

Когда микросервисы — не лучшее решение

Контрпримеры и ограничения:

  • Небольшой проект с одной командой. Монофония проще и быстрее доставки.
  • Сильно связанны́е данные и сложные транзакции, где распределённые транзакции дороже.
  • Команда не готова к DevOps и наблюдаемости — риски операций.

Альтернативы:

  • Модульный монолит: код остаётся внутри одного процесса, но разделён на модули с чёткими границами.
  • Сервисная шина (SOA) в крупных корпоративных системах.

Принятие решения: эвристики и модели

Ментальные модели для выбора архитектуры:

  • «Пара людей» — монолит; «несколько независимых команд» — микросервисы.
  • Если фича меняется часто и сильно влияет на масштабирование — выделяйте в сервис.
  • Если операции над данными требуют атомарности — предпочтите единое хранилище.

Матрица зрелости (уровни):

  • Уровень 0 — монолит без автоматизации;
  • Уровень 1 — модульный монолит, базовые тесты;
  • Уровень 2 — разделение на сервисы, CI/CD, логирование;
  • Уровень 3 — автоматическое масштабирование, распределённая трассировка, SLO/SLI.

Чеклисты по ролям

Backend‑разработчик:

  • Настроить миграции схемы (Alembic или аналог).
  • Не хранить секреты в репозитории.
  • Покрыть критичные endpoint’ы тестами.

DevOps/Инфраструктура:

  • Настроить CI/CD для билдов и деплоя.
  • Настроить мониторинг и алерты.
  • Управление секретами и ротация ключей.

QA/Тестирование:

  • Написать интеграционные тесты с тестовой БД.
  • Проверить сценарии отказа и восстановления.

Security:

  • Провести сканирование зависимостей и статический анализ кода.
  • Настроить политический контроль доступа (RBAC).

Критерии приёмки

  • Сервис успешно создаёт и возвращает пользователей через API.
  • Миграции запускаются без ошибок на тестовой базе.
  • Сервис работает в контейнере и отвечает на запросы.
  • Логи содержат достаточную информацию для отладки (без секретов).

Тестовые случаи и сценарии приёмки

  1. Успешное создание пользователя: POST /api/user c валидным именем — ожидается 201 и тело с id.
  2. Получение списка: GET /api/user — ожидается 200 и список пользователей.
  3. Негативный сценарий: GET на пустой БД — ожидается 404 с корректным сообщением.
  4. Неправильная строка подключения — сервис запускается и логирует ошибку подключения.

Отладка распространённых ошибок

  • Ошибка при create_engine: проверьте формат строки подключения и установленные драйверы.
  • Ошибка импорта psycopg2: убедитесь, что psycopg2-binary установлен и соответствует Python‑версии.
  • Docker не стартует: проверьте логи контейнера через docker logs .

Миграция и переход от монолита

Мини‑методология перехода:

  1. Идентифицируйте границы: выделяйте небольшие, слабо связанные функции.
  2. Экстрагируйте данные и API для выбранной области.
  3. Настройте независимый CI/CD и окружение.
  4. Постепенно перенаправляйте трафик и отключайте старые функции.

Совет: сначала выделяйте read‑heavy или высоконагруженные компоненты — эффект масштабирования виден быстрее.

Безопасность: конкретные шаги

  • Используйте механизмы аутентификации и авторизации (OAuth2, JWT) для API.
  • Ограничьте доступ к endpoint’ам по ролям.
  • Включите TLS и проверку сертификатов при подключении к БД (require_ssl).
  • Примените принципы минимально необходимых прав для учетных записей базы данных.

Краткий глоссарий (1 строка на термин)

  • Микросервис — автономный компонент, решающий одну бизнес‑задачу.
  • Монолит — приложение, упакованное и разворачиваемое как одно целое.
  • SQLAlchemy — ORM для работы с SQL базами в Python.
  • Psycopg2 — популярный PostgreSQL адаптер для Python.

Часто задаваемые вопросы

Нужно ли разделять базу данных для каждого микросервиса?

Не обязательно, но изоляция данных снижает связность. Выбор зависит от требований консистентности.

Как хранить секреты для Docker-контейнеров?

Используйте менеджеры секретов облачного провайдера или HashiCorp Vault, либо Docker Secrets / Kubernetes Secrets.

Подходит ли Flask для микросервисов в продакшене?

Да, но в проде обычно используют WSGI/ASGI серверы (gunicorn/uvicorn), переменные окружения и пул подключений.

Вывод

Микросервис на Flask и PostgreSQL — простой и понятный старт для изучения распределённых архитектур. Этот пример показывает базовую реализацию, тестирование и развёртывание в Docker. Прежде чем переходить к микросервисам, оцените сложность проекта, командные навыки и требования к операционной поддержке.

Краткая сводка:

  • Разделяйте систему на сервисы по бизнес‑границам.
  • Автоматизируйте тесты, сборку и деплой.
  • Инвестируйте в безопасность, мониторинг и логирование.

Источники кода проекта доступны в репозитории на GitHub (ссылка в оригинале проекта).

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как использовать WhatsApp в браузере
Мессенджеры

Как использовать WhatsApp в браузере

Как заблокировать приложения в Windows 11
Безопасность

Как заблокировать приложения в Windows 11

Отключить планшетный режим в Google Chrome
браузер

Отключить планшетный режим в Google Chrome

Как безопасно выключить Raspberry Pi
Raspberry Pi

Как безопасно выключить Raspberry Pi

Сбросить прогресс просмотра на Netflix
Руководство

Сбросить прогресс просмотра на Netflix

Найти разрывы разделов в Word
Microsoft Word

Найти разрывы разделов в Word