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

Как запускали четыре приложения на продакшн?

1.2 Junior🔥 101 комментариев
#DevOps и инфраструктура#Архитектура и паттерны

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

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

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

Как запускали четыре приложения на продакшн?

Запуск и управление несколькими приложениями на production требует комплексного подхода с использованием контейнеризации, оркестрации и мониторинга. Рассмотрю основные стратегии.

1. Docker Compose (для небольших deployment)

Это хороший вариант, когда приложения работают на одной машине:

# docker-compose.yml
version: 3.8
services:
  api_service:
    build: ./api
    ports:
      - "8001:8000"
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/api_db
    depends_on:
      - db
    restart: always
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3

  worker_service:
    build: ./worker
    environment:
      - REDIS_URL=redis://redis:6379
    depends_on:
      - redis
      - api_service
    restart: always

  scheduler_service:
    build: ./scheduler
    environment:
      - DATABASE_URL=postgresql://user:pass@db:5432/scheduler_db
    depends_on:
      - db
    restart: always

  bot_service:
    build: ./bot
    environment:
      - BOT_TOKEN=${BOT_TOKEN}
      - API_URL=http://api_service:8000
    depends_on:
      - api_service
    restart: always

  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_PASSWORD=securepass
    volumes:
      - db_data:/var/lib/postgresql/data
    restart: always

  redis:
    image: redis:7-alpine
    restart: always

volumes:
  db_data:

2. Kubernetes (для масштабируемого решения)

Для production обычно используют Kubernetes с несколькими replica sets:

# api-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-service
spec:
  replicas: 3  # Три инстанса
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api
        image: registry.example.com/api:latest
        ports:
        - containerPort: 8000
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: connection-string
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 8000
          initialDelaySeconds: 30
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: api-service
spec:
  selector:
    app: api
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8000
  type: LoadBalancer

3. Systemd (для управления сервисами на VPS)

Для отдельных приложений на сервере:

# /etc/systemd/system/api-service.service
[Unit]
Description=API Service
After=network.target

[Service]
Type=notify
User=appuser
WorkingDirectory=/opt/api
Environment="DATABASE_URL=postgresql://user:pass@localhost/api_db"
ExecStart=/usr/bin/python -m gunicorn app:app --workers 4 --bind 0.0.0.0:8001
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
# Команды управления
sudo systemctl start api-service
sudo systemctl enable api-service  # Стартовать при перезагрузке
sudo systemctl status api-service
sudo journalctl -u api-service -f  # Логи

4. Supervisor (для управления несколькими process)

# /etc/supervisor/conf.d/apps.conf
[program:api]
command=/usr/bin/python -m gunicorn app:app --workers 4
directory=/opt/api
user=appuser
autostart=true
autorestart=true
stderr_logfile=/var/log/api.err.log
stdout_logfile=/var/log/api.out.log

[program:worker]
command=/usr/bin/python -m celery worker -A tasks
directory=/opt/worker
user=appuser
autostart=true
autorestart=true
stderr_logfile=/var/log/worker.err.log

[group:apps]
programs=api,worker

5. Nginx как reverse proxy

Для балансировки нагрузки между приложениями:

# /etc/nginx/nginx.conf
http {
    upstream api_backend {
        server 127.0.0.1:8001;
        server 127.0.0.1:8002;  # replica
        server 127.0.0.1:8003;  # replica
    }

    upstream worker_backend {
        server 127.0.0.1:9001;
    }

    server {
        listen 80;
        server_name api.example.com;

        location / {
            proxy_pass http://api_backend;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

        location /health {
            access_log off;
            proxy_pass http://api_backend;
        }
    }

    server {
        listen 80;
        server_name worker.example.com;
        location / {
            proxy_pass http://worker_backend;
        }
    }
}

6. Скрипт для запуска на production

#!/bin/bash
# deploy.sh
set -e

echo "Stopping services..."
sudo systemctl stop api worker scheduler bot

echo "Pulling latest code..."
cd /opt/app
git pull origin main

echo "Installing dependencies..."
pip install -r requirements.txt

echo "Running migrations..."
python -m alembic upgrade head

echo "Starting services..."
sudo systemctl start api worker scheduler bot

echo "Waiting for health checks..."
sleep 5
curl -f http://localhost:8001/health || (echo "API failed" && exit 1)

echo "Deployment complete!"

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

# Централизованное логирование со структурированными логами
import logging
import json
from pythonjsonlogger import jsonlogger

logger = logging.getLogger(__name__)

# JSON логирование для всех приложений
logHandler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter()
logHandler.setFormatter(formatter)
logger.addHandler(logHandler)

# Использование
logger.info(
    "API request processed",
    extra={
        "service": "api",
        "duration_ms": 145,
        "status_code": 200,
        "user_id": 12345
    }
)

8. Здоровье приложений (Health Checks)

# Общий endpoint для всех приложений
from fastapi import FastAPI
import asyncio

app = FastAPI()

@app.get("/health")
async def health_check():
    return {
        "status": "healthy",
        "service": "api",
        "timestamp": datetime.utcnow().isoformat(),
        "checks": {
            "database": await check_db_connection(),
            "redis": await check_redis_connection(),
            "memory": psutil.virtual_memory().percent < 80
        }
    }

9. Graceful shutdown

import signal
import sys

shutdown_event = asyncio.Event()

def signal_handler(signum, frame):
    """Обработка сигнала graceful shutdown"""
    logger.info(f"Received signal {signum}, shutting down...")
    shutdown_event.set()

signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGINT, signal_handler)

# В приложении
await shutdown_event.wait()
logger.info("Closing all connections...")
# Закрыть БД, кэш, etc

Чек-лист запуска 4 приложений

  • Изоляция — каждое приложение на своем порту
  • Health checks — проверка каждого сервиса
  • Логирование — централизованное и структурированное
  • Балансировка нагрузки — Nginx или Kubernetes
  • Graceful shutdown — корректное завершение
  • Мониторинг — Prometheus/Grafana или подобное
  • Backup и restore — процесс восстановления
  • Версионирование — контроль версий приложений

В моем случае мы использовали Docker Compose для разработки и Kubernetes для production.

Как запускали четыре приложения на продакшн? | PrepBro