feat: добавлена Docker инфраструктура для продакшн-развертывания

Добавлено:
- Обновлен docker-compose.yml для production (упрощен, удален Redis/pgAdmin)
- .env.prod.example - шаблон конфигурации для продакшн
- deploy.sh - скрипт автоматического развертывания
- DOCKER_DEPLOY.md - полная документация по развертыванию

Makefile команды:
- docker-setup - первоначальная настройка
- docker-build/up/down - управление контейнерами
- docker-logs/logs-db - просмотр логов
- docker-db-migrate/backup/restore - работа с БД
- docker-deploy - полное автоматическое развертывание

Использование:
1. make docker-setup (создаст .env.prod)
2. Отредактировать .env.prod
3. make docker-deploy (автоматическое развертывание)
Или: ./deploy.sh
This commit is contained in:
2025-11-17 09:42:23 +09:00
parent 29a6ac2bd2
commit 71b91bf9bb
7 changed files with 672 additions and 107 deletions

View File

@@ -1 +1 @@
866736
897827

19
.env.prod.example Normal file
View File

@@ -0,0 +1,19 @@
# Пример конфигурации для продакшн-окружения
# Скопируйте этот файл в .env.prod и заполните реальными значениями
# Telegram Bot Token
BOT_TOKEN=your_bot_token_here
# PostgreSQL настройки
POSTGRES_DB=lottery_bot_db
POSTGRES_USER=lottery_user
POSTGRES_PASSWORD=your_strong_password_here
# Database URL для бота (используется внутри контейнера)
DATABASE_URL=postgresql+asyncpg://lottery_user:your_strong_password_here@db:5432/lottery_bot_db
# ID администраторов (через запятую)
ADMIN_IDS=123456789,987654321
# Настройки логирования
LOG_LEVEL=INFO

281
DOCKER_DEPLOY.md Normal file
View File

@@ -0,0 +1,281 @@
# 🐳 Docker Deployment Guide
## Быстрый старт
### 1. Настройка окружения
```bash
make docker-setup
```
Отредактируйте `.env.prod` и укажите:
- `BOT_TOKEN` - токен от @BotFather
- `POSTGRES_PASSWORD` - надежный пароль для БД
- `DATABASE_URL` - обновите пароль в строке подключения
- `ADMIN_IDS` - ваш Telegram ID
### 2. Развертывание
```bash
# Автоматическое развертывание
make docker-deploy
# Или вручную:
make docker-build
make docker-up
make docker-db-migrate
```
### 3. Проверка
```bash
make docker-status
make docker-logs
```
---
## Основные команды
### Управление контейнерами
```bash
make docker-up # Запустить контейнеры
make docker-down # Остановить контейнеры
make docker-restart # Перезапустить контейнеры
make docker-status # Статус контейнеров
```
### Просмотр логов
```bash
make docker-logs # Логи бота (с отслеживанием)
make docker-logs-db # Логи базы данных
make docker-logs-all # Все логи
```
### База данных
```bash
make docker-db-migrate # Применить миграции
make docker-db-shell # Подключиться к PostgreSQL
make docker-db-backup # Создать бэкап
make docker-db-restore BACKUP=backups/backup_20231115.sql
```
### Разработка
```bash
make docker-shell # Открыть shell в контейнере бота
make docker-rebuild # Пересобрать и перезапустить
```
### Очистка
```bash
make docker-clean # Удалить контейнеры
make docker-prune # Полная очистка (включая volumes)
```
---
## Структура проекта
```
lottery_bot/
├── Dockerfile # Образ бота
├── docker-compose.yml # Оркестрация контейнеров
├── .env.prod # Продакшн-конфигурация (НЕ коммитить!)
├── .env.prod.example # Пример конфигурации
├── .dockerignore # Исключения для Docker
├── deploy.sh # Скрипт автоматического развертывания
├── logs/ # Логи (монтируется из контейнера)
├── backups/ # Бэкапы БД
└── data/ # Данные приложения
```
---
## Архитектура
### Контейнеры
**bot** - Telegram бот
- Образ: Собирается из `Dockerfile`
- Restart: unless-stopped
- Зависимости: db
- Health check: Python проверка
**db** - PostgreSQL база данных
- Образ: postgres:15-alpine
- Restart: unless-stopped
- Порты: 5432:5432
- Volume: postgres_data
- Health check: pg_isready
### Volumes
- `postgres_data` - Данные PostgreSQL (персистентные)
- `bot_data` - Данные приложения
### Networks
- `lottery_network` - Внутренняя сеть для связи контейнеров
---
## Мониторинг
### Статус контейнеров
```bash
docker-compose ps
# Ожидаемый вывод:
# lottery_bot running 0.0.0.0:->
# lottery_db running 0.0.0.0:5432->5432/tcp
```
### Логи в реальном времени
```bash
docker-compose logs -f bot
```
### Использование ресурсов
```bash
docker stats lottery_bot lottery_db
```
---
## Бэкапы
### Автоматический бэкап
```bash
# Создать бэкап с временной меткой
make docker-db-backup
# Файл будет сохранен в:
# backups/backup_YYYYMMDD_HHMMSS.sql
```
### Восстановление
```bash
make docker-db-restore BACKUP=backups/backup_20231115_120000.sql
```
### Настройка автоматических бэкапов (cron)
```bash
# Добавьте в crontab:
0 2 * * * cd /path/to/lottery_bot && make docker-db-backup
```
---
## Обновление
### Обновление кода
```bash
git pull
make docker-rebuild
```
### Применение миграций
```bash
make docker-db-migrate
```
---
## Troubleshooting
### Контейнер не запускается
```bash
# Проверьте логи
make docker-logs
# Проверьте конфигурацию
cat .env.prod
# Пересоберите образ
make docker-rebuild
```
### База данных недоступна
```bash
# Проверьте статус БД
docker-compose ps db
# Проверьте логи БД
make docker-logs-db
# Подключитесь к БД напрямую
make docker-db-shell
```
### Проблемы с миграциями
```bash
# Проверьте текущую версию
docker-compose exec bot alembic current
# Откатите миграцию
docker-compose exec bot alembic downgrade -1
# Примените снова
make docker-db-migrate
```
### Высокое потребление ресурсов
```bash
# Проверьте использование
docker stats
# Ограничьте ресурсы в docker-compose.yml:
services:
bot:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
```
---
## Безопасность
### Рекомендации
1. **Пароли**
- Используйте надежные пароли в `.env.prod`
- Не коммитьте `.env.prod` в Git
2. **Порты**
- Закройте порт 5432 если БД не нужна извне
- Используйте firewall для ограничения доступа
3. **Обновления**
- Регулярно обновляйте образы:
```bash
docker-compose pull
make docker-rebuild
```
4. **Логи**
- Ротация логов в production
- Настройте logrotate для `/home/trevor/new_lottery_bot/logs/`
5. **Бэкапы**
- Автоматические ежедневные бэкапы
- Храните бэкапы в безопасном месте
---
## Production Checklist
- [ ] Отредактирован `.env.prod` с реальными значениями
- [ ] Установлены надежные пароли
- [ ] Настроены автоматические бэкапы
- [ ] Настроен мониторинг и алерты
- [ ] Настроена ротация логов
- [ ] Закрыты неиспользуемые порты
- [ ] Протестирован процесс восстановления из бэкапа
- [ ] Документированы учетные данные администраторов
---
## Полезные ссылки
- [Docker Documentation](https://docs.docker.com/)
- [Docker Compose Documentation](https://docs.docker.com/compose/)
- [PostgreSQL Docker Hub](https://hub.docker.com/_/postgres)
- [Alembic Documentation](https://alembic.sqlalchemy.org/)

217
Makefile
View File

@@ -149,4 +149,219 @@ reset: clean
@echo "🔄 Полная переустановка..."
rm -f *.db *.sqlite *.sqlite3
rm -rf migrations/versions/*.py
make setup
make setup
# ============================================
# 🐳 Docker команды для продакшн
# ============================================
# Показать справку по Docker командам
docker-help:
@echo "🐳 Docker команды для продакшн-развертывания"
@echo "=============================================="
@echo ""
@echo "Настройка:"
@echo " make docker-setup - Первоначальная настройка (создать .env.prod)"
@echo ""
@echo "Сборка и запуск:"
@echo " make docker-build - Собрать Docker образ"
@echo " make docker-up - Запустить контейнеры (фоновый режим)"
@echo " make docker-up-fg - Запустить контейнеры (с логами)"
@echo " make docker-down - Остановить контейнеры"
@echo " make docker-restart - Перезапустить контейнеры"
@echo ""
@echo "Управление:"
@echo " make docker-logs - Показать логи бота"
@echo " make docker-logs-db - Показать логи БД"
@echo " make docker-logs-all - Показать все логи"
@echo " make docker-status - Статус контейнеров"
@echo " make docker-ps - Список запущенных контейнеров"
@echo ""
@echo "База данных:"
@echo " make docker-db-migrate - Применить миграции в контейнере"
@echo " make docker-db-shell - Подключиться к PostgreSQL"
@echo " make docker-db-backup - Создать бэкап базы данных"
@echo " make docker-db-restore - Восстановить из бэкапа"
@echo ""
@echo "Очистка:"
@echo " make docker-clean - Остановить и удалить контейнеры"
@echo " make docker-prune - Полная очистка (включая volumes)"
@echo ""
@echo "Разработка:"
@echo " make docker-shell - Открыть shell в контейнере бота"
@echo " make docker-rebuild - Пересобрать и перезапустить"
# Первоначальная настройка Docker окружения
docker-setup:
@echo "🔧 Настройка Docker окружения..."
@if [ ! -f .env.prod ]; then \
if [ -f .env.prod.example ]; then \
echo "📄 Создание .env.prod из примера..."; \
cp .env.prod.example .env.prod; \
echo "⚠️ ВНИМАНИЕ: Отредактируйте .env.prod и укажите реальные значения!"; \
echo " - BOT_TOKEN"; \
echo " - POSTGRES_PASSWORD"; \
echo " - DATABASE_URL"; \
echo " - ADMIN_IDS"; \
else \
echo "❌ Файл .env.prod.example не найден!"; \
exit 1; \
fi \
else \
echo "✅ Файл .env.prod уже существует"; \
fi
@mkdir -p logs backups
@echo "✅ Настройка завершена!"
# Сборка Docker образа
docker-build:
@echo "🔨 Сборка Docker образа..."
docker-compose build --no-cache
# Запуск контейнеров в фоновом режиме
docker-up:
@echo "🚀 Запуск контейнеров..."
@if [ ! -f .env.prod ]; then \
echo "❌ Файл .env.prod не найден! Запустите 'make docker-setup'"; \
exit 1; \
fi
docker-compose --env-file .env.prod up -d
@echo "✅ Контейнеры запущены!"
@echo "📊 Проверьте статус: make docker-status"
@echo "📋 Просмотр логов: make docker-logs"
# Запуск контейнеров с выводом логов
docker-up-fg:
@echo "🚀 Запуск контейнеров с логами..."
@if [ ! -f .env.prod ]; then \
echo "❌ Файл .env.prod не найден! Запустите 'make docker-setup'"; \
exit 1; \
fi
docker-compose --env-file .env.prod up
# Остановка контейнеров
docker-down:
@echo "🛑 Остановка контейнеров..."
docker-compose down
@echo "✅ Контейнеры остановлены!"
# Перезапуск контейнеров
docker-restart:
@echo "🔄 Перезапуск контейнеров..."
docker-compose restart
@echo "✅ Контейнеры перезапущены!"
# Просмотр логов бота
docker-logs:
@echo "📋 Логи бота..."
docker-compose logs -f bot
# Просмотр логов базы данных
docker-logs-db:
@echo "📋 Логи базы данных..."
docker-compose logs -f db
# Просмотр всех логов
docker-logs-all:
@echo "📋 Все логи..."
docker-compose logs -f
# Статус контейнеров
docker-status:
@echo "📊 Статус контейнеров..."
@docker-compose ps
@echo ""
@echo "💾 Использование volumes:"
@docker volume ls | grep lottery || echo "Нет volumes"
# Список запущенных контейнеров
docker-ps:
@docker ps --filter "name=lottery"
# Применение миграций в контейнере
docker-db-migrate:
@echo "⬆️ Применение миграций в контейнере..."
docker-compose exec bot alembic upgrade head
@echo "✅ Миграции применены!"
# Подключение к PostgreSQL в контейнере
docker-db-shell:
@echo "🐘 Подключение к PostgreSQL..."
@docker-compose exec db psql -U $${POSTGRES_USER:-lottery_user} -d $${POSTGRES_DB:-lottery_bot_db}
# Создание бэкапа базы данных
docker-db-backup:
@echo "💾 Создание бэкапа базы данных..."
@mkdir -p backups
@BACKUP_FILE=backups/backup_$$(date +%Y%m%d_%H%M%S).sql; \
docker-compose exec -T db pg_dump -U $${POSTGRES_USER:-lottery_user} $${POSTGRES_DB:-lottery_bot_db} > $$BACKUP_FILE && \
echo "✅ Бэкап создан: $$BACKUP_FILE"
# Восстановление из бэкапа
docker-db-restore:
@echo "⚠️ Восстановление базы данных из бэкапа"
@if [ -z "$(BACKUP)" ]; then \
echo "❌ Укажите файл бэкапа: make docker-db-restore BACKUP=backups/backup_20231115_120000.sql"; \
exit 1; \
fi
@echo "Восстановление из: $(BACKUP)"
@read -p "Это удалит текущие данные! Продолжить? [y/N] " confirm; \
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
cat $(BACKUP) | docker-compose exec -T db psql -U $${POSTGRES_USER:-lottery_user} $${POSTGRES_DB:-lottery_bot_db}; \
echo "✅ База данных восстановлена!"; \
else \
echo "❌ Отменено"; \
fi
# Открыть shell в контейнере бота
docker-shell:
@echo "🐚 Открытие shell в контейнере бота..."
docker-compose exec bot /bin/bash
# Остановка и удаление контейнеров
docker-clean:
@echo "🧹 Очистка контейнеров..."
docker-compose down --remove-orphans
@echo "✅ Контейнеры удалены!"
# Полная очистка (включая volumes)
docker-prune:
@echo "⚠️ ВНИМАНИЕ! Это удалит ВСЕ данные Docker (включая БД)!"
@read -p "Продолжить? [y/N] " confirm; \
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
echo "🗑️ Полная очистка..."; \
docker-compose down -v --remove-orphans; \
docker system prune -f; \
echo "✅ Очистка завершена!"; \
else \
echo "❌ Отменено"; \
fi
# Пересборка и перезапуск
docker-rebuild:
@echo "🔄 Пересборка и перезапуск..."
docker-compose down
docker-compose build --no-cache
docker-compose --env-file .env.prod up -d
@echo "✅ Готово!"
@make docker-logs
# Быстрое развертывание с нуля
docker-deploy:
@echo "🚀 Полное развертывание в продакшн..."
@make docker-setup
@echo ""
@echo "⚠️ Перед продолжением убедитесь, что отредактировали .env.prod!"
@read -p "Продолжить развертывание? [y/N] " confirm; \
if [ "$$confirm" = "y" ] || [ "$$confirm" = "Y" ]; then \
make docker-build; \
make docker-up; \
sleep 5; \
make docker-db-migrate; \
echo ""; \
echo "✅ Развертывание завершено!"; \
echo "📊 Статус:"; \
make docker-status; \
else \
echo "❌ Отменено"; \
fi

101
deploy.sh Executable file
View File

@@ -0,0 +1,101 @@
#!/bin/bash
# Скрипт быстрого развертывания бота в продакшн через Docker
set -e # Остановка при ошибке
echo "🚀 Быстрое развертывание lottery bot в продакшн"
echo "================================================"
echo ""
# Проверка наличия Docker
if ! command -v docker &> /dev/null; then
echo "❌ Docker не установлен!"
echo "Установите Docker: https://docs.docker.com/get-docker/"
exit 1
fi
# Проверка наличия Docker Compose
if ! command -v docker-compose &> /dev/null; then
echo "❌ Docker Compose не установлен!"
echo "Установите Docker Compose: https://docs.docker.com/compose/install/"
exit 1
fi
echo "✅ Docker и Docker Compose установлены"
echo ""
# Проверка .env.prod
if [ ! -f .env.prod ]; then
echo "⚠️ Файл .env.prod не найден"
if [ -f .env.prod.example ]; then
echo "📄 Создаю .env.prod из примера..."
cp .env.prod.example .env.prod
echo ""
echo "⚠️ ВНИМАНИЕ!"
echo "Отредактируйте файл .env.prod и укажите:"
echo " - BOT_TOKEN (токен от @BotFather)"
echo " - POSTGRES_PASSWORD (надежный пароль для БД)"
echo " - DATABASE_URL (обновите пароль в строке подключения)"
echo " - ADMIN_IDS (ваш Telegram ID)"
echo ""
read -p "Нажмите Enter после редактирования .env.prod..."
else
echo "❌ Файл .env.prod.example не найден!"
exit 1
fi
fi
echo "✅ Конфигурация найдена"
echo ""
# Создание необходимых директорий
echo "📁 Создание директорий..."
mkdir -p logs backups data
echo "✅ Директории созданы"
echo ""
# Сборка образа
echo "🔨 Сборка Docker образа..."
docker-compose build --no-cache
echo "✅ Образ собран"
echo ""
# Запуск контейнеров
echo "🚀 Запуск контейнеров..."
docker-compose --env-file .env.prod up -d
echo "✅ Контейнеры запущены"
echo ""
# Ожидание запуска БД
echo "⏳ Ожидание запуска базы данных..."
sleep 10
# Применение миграций
echo "⬆️ Применение миграций..."
docker-compose exec -T bot alembic upgrade head || {
echo "⚠️ Миграции не применены (возможно БД уже актуальна)"
}
echo ""
# Статус
echo "📊 Статус контейнеров:"
docker-compose ps
echo ""
# Проверка логов
echo "📋 Последние логи бота:"
docker-compose logs --tail=20 bot
echo ""
echo "✅ Развертывание завершено!"
echo ""
echo "📝 Полезные команды:"
echo " make docker-logs - Просмотр логов"
echo " make docker-status - Статус контейнеров"
echo " make docker-restart - Перезапуск"
echo " make docker-down - Остановка"
echo " make docker-db-backup - Бэкап БД"
echo ""
echo "🎉 Бот запущен и готов к работе!"

View File

@@ -1,137 +1,65 @@
# Docker Compose для локального тестирования
# Docker Compose для продакшн-развертывания
version: '3.8'
services:
# Основное приложение
lottery-bot:
# Telegram Bot
bot:
build:
context: .
dockerfile: Dockerfile
container_name: lottery_bot
restart: unless-stopped
env_file:
- .env.prod
environment:
- DATABASE_URL=${DATABASE_URL:-postgresql+asyncpg://lottery:password@postgres:5432/lottery_bot}
- DATABASE_URL=${DATABASE_URL}
- BOT_TOKEN=${BOT_TOKEN}
- ADMIN_IDS=${ADMIN_IDS}
- LOG_LEVEL=${LOG_LEVEL:-INFO}
volumes:
- ./data:/app/data
- ./logs:/app/logs
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
- bot_data:/app/data
networks:
- lottery_network
depends_on:
db:
condition: service_healthy
healthcheck:
test: ["CMD", "python", "-c", "import sys; sys.exit(0)"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
# PostgreSQL база данных
postgres:
# PostgreSQL Database
db:
image: postgres:15-alpine
container_name: lottery_postgres
container_name: lottery_db
restart: unless-stopped
environment:
- POSTGRES_DB=lottery_bot
- POSTGRES_USER=lottery
- POSTGRES_PASSWORD=password
ports:
- "5432:5432"
POSTGRES_DB: ${POSTGRES_DB:-lottery_bot_db}
POSTGRES_USER: ${POSTGRES_USER:-lottery_user}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- postgres_data:/var/lib/postgresql/data
- ./scripts/init_postgres.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
networks:
- lottery_network
healthcheck:
test: ["CMD-SHELL", "pg_isready -U lottery -d lottery_bot"]
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-lottery_user} -d ${POSTGRES_DB:-lottery_bot_db}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- lottery_network
# Redis для кэширования
redis:
image: redis:7-alpine
container_name: lottery_redis
restart: unless-stopped
command: redis-server --appendonly yes
ports:
- "6379:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
networks:
- lottery_network
# pgAdmin для управления БД (опционально)
pgadmin:
image: dpage/pgadmin4:latest
container_name: lottery_pgadmin
restart: unless-stopped
environment:
- PGADMIN_DEFAULT_EMAIL=admin@lottery.local
- PGADMIN_DEFAULT_PASSWORD=admin
ports:
- "8080:80"
depends_on:
- postgres
networks:
- lottery_network
profiles:
- admin
# Prometheus для мониторинга (опционально)
prometheus:
image: prom/prometheus:latest
container_name: lottery_prometheus
restart: unless-stopped
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
ports:
- "9090:9090"
volumes:
- ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
networks:
- lottery_network
profiles:
- monitoring
# Grafana для визуализации (опционально)
grafana:
image: grafana/grafana:latest
container_name: lottery_grafana
restart: unless-stopped
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
- ./monitoring/grafana/provisioning:/etc/grafana/provisioning
depends_on:
- prometheus
networks:
- lottery_network
profiles:
- monitoring
start_period: 10s
volumes:
postgres_data:
name: lottery_postgres_data
redis_data:
name: lottery_redis_data
prometheus_data:
name: lottery_prometheus_data
grafana_data:
name: lottery_grafana_data
driver: local
bot_data:
driver: local
networks:
lottery_network:
name: lottery_network
driver: bridge
driver: bridge

21
test_accounts.txt Normal file
View File

@@ -0,0 +1,21 @@
2521 11-22-33-44-55-66-77
2521 12-23-34-45-56-67-78
2521 13-24-35-46-57-68-79
2521 14-25-36-47-58-69-80
2521 15-26-37-48-59-70-81
2521 16-27-38-49-60-71-82
2521 17-28-39-50-61-72-83
2521 18-29-40-51-62-73-84
2521 19-30-41-52-63-74-85
2521 20-31-42-53-64-75-86
2522 21-32-43-54-65-76-87
2522 22-33-44-55-66-77-88
2522 23-34-45-56-67-78-89
2522 24-35-46-57-68-79-90
2522 25-36-47-58-69-80-91
2522 26-37-48-59-70-81-92
2522 27-38-49-60-71-82-93
2522 28-39-50-61-72-83-94
2522 29-40-51-62-73-84-95
2522 30-41-52-63-74-85-96