← Назад к вопросам

Как проходила работа с инфраструктурой?

1.0 Junior🔥 121 комментариев
#DevOps и инфраструктура#Soft Skills

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Работа с инфраструктурой

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

1. Локальная разработка (Local Development)

Docker Compose

Использую Docker Compose для изоляции сервисов на локальной машине:

version: '3.8'
services:
  app:
    build: .
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgresql://user:pass@db:5432/mydb
    depends_on:
      - db
  
  db:
    image: postgres:15
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data
  
  redis:
    image: redis:7
    ports:
      - "6379:6379"

volumes:
  postgres_data:
# Запуск локально
docker compose up -d

# Просмотр логов
docker compose logs -f app

# Остановка
docker compose down

2. CI/CD Pipeline

GitHub Actions

Автоматизация тестирования и деплоя:

name: Tests & Deploy

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    
    services:
      postgres:
        image: postgres:15
        env:
          POSTGRES_PASSWORD: test
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
    
    steps:
      - uses: actions/checkout@v3
      
      - uses: actions/setup-python@v4
        with:
          python-version: '3.11'
      
      - name: Install dependencies
        run: |
          pip install -r requirements.txt
          pip install pytest pytest-cov
      
      - name: Run tests
        run: pytest --cov=app tests/
        env:
          DATABASE_URL: postgresql://postgres:test@localhost/test
      
      - name: Upload coverage
        uses: codecov/codecov-action@v3
  
  deploy:
    needs: test
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    
    steps:
      - uses: actions/checkout@v3
      
      - name: Deploy to production
        env:
          DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}
        run: |
          mkdir -p ~/.ssh
          echo "$DEPLOY_KEY" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          git push dokku main

3. Production Deployment

Dokku на VPS

Использую Dokku как PaaS для простого деплоя:

# На сервере (178.253.42.36:24822)
sudo dokku apps:create myapp

# Добавляем переменные окружения
dokku config:set myapp DATABASE_URL=postgresql://...
dokku config:set myapp SECRET_KEY=...
dokku config:set myapp DEBUG=false

# Деплой через git
git remote add dokku dokku@178.253.42.36:myapp
git push dokku main

# Просмотр логов
dokku logs myapp -t

# Масштабирование
dokku ps:scale myapp web=2

Dockerfile

FROM python:3.11-slim

WORKDIR /app

RUN apt-get update && apt-get install -y postgresql-client

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

RUN python -m pip install gunicorn

CMD ["gunicorn", "app.main:app", "--bind", "0.0.0.0:5000", "--workers", "4"]

4. Базы данных

PostgreSQL с миграциями

Использую Goose (raw SQL) для миграций:

# Создание миграции
goose create add_users_table sql

# Применение миграций
goose postgres "$DATABASE_URL" up

# Откат на одну версию
goose postgres "$DATABASE_URL" down

Файл миграции 0001_add_users_table.sql:

-- +goose Up
CREATE TABLE users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email VARCHAR(255) UNIQUE NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

CREATE INDEX idx_users_email ON users(email);

-- +goose Down
DROP TABLE users;

Redis для кэширования

import redis
from typing import Any

redis_client = redis.Redis(
    host='localhost',
    port=6379,
    decode_responses=True
)

# Кэширование результатов
def get_user_cached(user_id: int) -> dict:
    cache_key = f"user:{user_id}"
    
    # Проверяем кэш
    cached = redis_client.get(cache_key)
    if cached:
        return json.loads(cached)
    
    # Получаем из БД
    user = db.get_user(user_id)
    
    # Сохраняем в кэш на 1 час
    redis_client.setex(cache_key, 3600, json.dumps(user))
    
    return user

5. Мониторинг и логирование

Структурированное логирование

import logging
import json
from datetime import datetime

class JSONFormatter(logging.Formatter):
    def format(self, record):
        log_data = {
            'timestamp': datetime.utcnow().isoformat(),
            'level': record.levelname,
            'message': record.getMessage(),
            'logger': record.name,
        }
        if record.exc_info:
            log_data['exception'] = self.formatException(record.exc_info)
        return json.dumps(log_data)

logger = logging.getLogger(__name__)
handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
logger.addHandler(handler)
logger.setLevel(logging.INFO)

# Использование
logger.info('User registered', extra={'user_id': 123})
logger.error('Database error', exc_info=True)

6. Секреты и переменные окружения

.env файл

DATABASE_URL=postgresql://user:pass@localhost/mydb
REDIS_URL=redis://localhost:6379
SECRET_KEY=your-secret-key-here
DEBUG=false
ALLOWED_HOSTS=example.com,www.example.com

Загрузка в Python

from pydantic_settings import BaseSettings
from typing import Optional

class Settings(BaseSettings):
    database_url: str
    redis_url: str
    secret_key: str
    debug: bool = False
    allowed_hosts: str = "localhost"
    
    class Config:
        env_file = ".env"
        case_sensitive = False

settings = Settings()

7. Health checks и readiness

from fastapi import APIRouter
from sqlalchemy import text

router = APIRouter()

@router.get("/health")
async def health_check():
    return {"status": "healthy"}

@router.get("/ready")
async def readiness_check():
    try:
        # Проверяем БД
        async with db.begin() as conn:
            await conn.execute(text("SELECT 1"))
        
        # Проверяем Redis
        redis_client.ping()
        
        return {"status": "ready"}
    except Exception as e:
        return {"status": "not_ready", "error": str(e)}, 503

8. Масштабирование

Horizontal scaling

# На Dokku
dokku ps:scale myapp web=3  # 3 рабочих процесса

# Load balancing через nginx (встроено в Dokku)
# Автоматически распределяет запросы

Вертикальное масштабирование

# Оптимизация кода
# Кэширование
# Индексы в БД
# Connection pooling

from sqlalchemy.pool import QueuePool

engine = create_engine(
    DATABASE_URL,
    poolclass=QueuePool,
    pool_size=20,
    max_overflow=40,
)

Типовой workflow

  1. Локальная разработка → Docker Compose
  2. Push в GitHub → CI/CD запускает тесты
  3. Merge в main → Автоматический деплой на Dokku
  4. Production → Dokku управляет приложением

Это обеспечивает быстрый деплой, надёжность, и масштабируемость.