Добавлено логирование информации о запуске приложения в Docker-контейнере в функции настройки логирования. Теперь выводится информация о временной зоне и пользователе контейнера, что улучшает отслеживание работы приложения в различных средах.

This commit is contained in:
Vlad 2025-06-04 08:02:53 +03:00
parent 98ba1cb3c1
commit c0a8cf1334
9 changed files with 840 additions and 0 deletions

91
.dockerignore Normal file
View File

@ -0,0 +1,91 @@
# Версионный контроль
.git/
.gitignore
.gitattributes
.gitmodules
# Окружение Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
venv/
env/
ENV/
.env
.venv
# IDE и редакторы
.vscode/
.idea/
*.swp
*.swo
*.sublime-*
*.code-workspace
# Операционная система
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
Desktop.ini
# Логи и временные файлы
logs/
*.log
*.tmp
*.temp
temp/
tmp/
# Тестирование
.pytest_cache/
.coverage
.tox/
.cache
coverage.xml
htmlcov/
.nyc_output
# Документация
docs/
*.md
*.rst
*.txt
!requirements.txt
# Docker файлы
Dockerfile.*
docker-compose*.yml
!docker-compose.yml
# Конфигурация
env.example
.env.*
!.env.example
# Базы данных (если есть локальные)
*.db
*.sqlite3
data/
# Бекапы и архивы
*.bak
*.backup
*.zip
*.tar.gz
*.rar
# Локальные изображения для разработки
images/*
!images/.gitkeep
# Специфичные для проекта
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

62
Dockerfile Normal file
View File

@ -0,0 +1,62 @@
# Используем официальный Python образ
FROM python:3.12-slim
# Устанавливаем системные зависимости
RUN apt-get update && apt-get install -y \
gcc \
libaio1 \
libaio-dev \
unzip \
wget \
&& rm -rf /var/lib/apt/lists/*
# Устанавливаем Oracle Instant Client
RUN mkdir -p /opt/oracle && \
cd /opt/oracle && \
wget https://download.oracle.com/otn_software/linux/instantclient/1921000/instantclient-basic-linux.x64-19.21.0.0.0dbru.zip && \
unzip instantclient-basic-linux.x64-19.21.0.0.0dbru.zip && \
rm instantclient-basic-linux.x64-19.21.0.0.0dbru.zip && \
echo /opt/oracle/instantclient_19_21 > /etc/ld.so.conf.d/oracle-instantclient.conf && \
ldconfig
# Устанавливаем переменные окружения для Oracle
ENV ORACLE_HOME=/opt/oracle/instantclient_19_21
ENV LD_LIBRARY_PATH=/opt/oracle/instantclient_19_21:$LD_LIBRARY_PATH
ENV PATH=/opt/oracle/instantclient_19_21:$PATH
# Создаем пользователя для безопасности
RUN useradd --create-home --shell /bin/bash salvagebot
USER salvagebot
WORKDIR /home/salvagebot/app
# Копируем файл зависимостей
COPY --chown=salvagebot:salvagebot requirements.txt .
# Устанавливаем Python зависимости
RUN pip install --user --no-cache-dir -r requirements.txt
# Копируем entrypoint скрипт
COPY --chown=salvagebot:salvagebot docker-entrypoint.sh /usr/local/bin/
USER root
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
USER salvagebot
# Копируем код приложения
COPY --chown=salvagebot:salvagebot . .
# Создаем необходимые директории
RUN mkdir -p logs images data
# Устанавливаем переменные окружения Python
ENV PYTHONPATH=/home/salvagebot/app
ENV PYTHONUNBUFFERED=1
# Проверяем здоровье контейнера
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD python -c "import sys; sys.exit(0)"
# Используем entrypoint для инициализации
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
# Команда запуска
CMD ["python", "main.py"]

148
Makefile Normal file
View File

@ -0,0 +1,148 @@
# Makefile для SalvageDB Telegram Bot
.PHONY: help build up down restart logs shell clean test health
# Переменные
COMPOSE_FILE = docker-compose.yml
SERVICE_NAME = salvagedb-bot
CONTAINER_NAME = salvagedb-telegram-bot
# Помощь
help: ## Показать доступные команды
@echo "SalvageDB Telegram Bot - Docker Commands"
@echo "========================================"
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}'
# Основные команды
build: ## Собрать Docker образ
@echo "🔨 Building Docker image..."
docker-compose build --no-cache
up: ## Запустить контейнер
@echo "🚀 Starting container..."
docker-compose up -d
down: ## Остановить контейнер
@echo "🛑 Stopping container..."
docker-compose down
restart: ## Перезапустить контейнер
@echo "🔄 Restarting container..."
docker-compose restart
# Логи и мониторинг
logs: ## Показать логи в реальном времени
@echo "📋 Following logs..."
docker-compose logs -f $(SERVICE_NAME)
logs-tail: ## Показать последние 100 строк логов
@echo "📋 Last 100 log lines..."
docker-compose logs --tail=100 $(SERVICE_NAME)
health: ## Проверить здоровье контейнера
@echo "🏥 Checking container health..."
docker inspect --format='{{.State.Health.Status}}' $(CONTAINER_NAME) || echo "Health check not available"
status: ## Показать статус контейнера
@echo "📊 Container status:"
docker-compose ps
stats: ## Показать статистику ресурсов
@echo "📈 Resource usage:"
docker stats $(CONTAINER_NAME) --no-stream
# Разработка
shell: ## Подключиться к контейнеру
@echo "🐚 Opening shell in container..."
docker-compose exec $(SERVICE_NAME) bash
shell-root: ## Подключиться как root
@echo "🔑 Opening root shell in container..."
docker-compose exec --user root $(SERVICE_NAME) bash
# Тестирование
test-env: ## Проверить переменные окружения
@echo "🔍 Checking environment variables..."
docker-compose exec $(SERVICE_NAME) python -c "import os; [print(f'{k}={v[:20]}{"..." if len(v) > 20 else ""}') for k, v in sorted(os.environ.items()) if any(x in k.upper() for x in ['BOT', 'DB', 'PRICE', 'ADMIN', 'DEBUG'])]"
test-db: ## Тестировать подключение к БД
@echo "🗄️ Testing database connection..."
docker-compose exec $(SERVICE_NAME) python -c "import oracledb, os; conn = oracledb.connect(user=os.getenv('DB_USER'), password=os.getenv('DB_PASSWORD'), dsn=os.getenv('DB_DSN')); print('✅ Database connection successful!'); conn.close()"
test-bot: ## Проверить импорты бота
@echo "🤖 Testing bot imports..."
docker-compose exec $(SERVICE_NAME) python -c "import aiogram, oracledb, asyncio, logging; print('✅ All imports successful!')"
test-all: test-env test-db test-bot ## Запустить все тесты
# Обслуживание
clean: ## Удалить контейнеры и volumes
@echo "🧹 Cleaning up..."
docker-compose down -v
docker system prune -f
clean-images: ## Удалить неиспользуемые образы
@echo "🗑️ Removing unused images..."
docker image prune -f
clean-all: clean clean-images ## Полная очистка
# Бэкап и восстановление
backup-logs: ## Создать архив логов
@echo "💾 Creating logs backup..."
tar -czf logs_backup_$(shell date +%Y%m%d_%H%M%S).tar.gz logs/
backup-env: ## Создать бэкап переменных окружения
@echo "🔐 Creating environment backup..."
cp .env .env.backup.$(shell date +%Y%m%d_%H%M%S)
# Деплой
deploy: build up ## Полный деплой (сборка + запуск)
@echo "🚀 Deployment complete!"
@make health
redeploy: down build up ## Переделой (остановка + сборка + запуск)
@echo "🔄 Redeployment complete!"
@make health
# Мониторинг
monitor: ## Мониторинг в реальном времени
@echo "📊 Starting monitoring (Ctrl+C to stop)..."
@while true; do \
clear; \
echo "=== SalvageDB Bot Monitoring ==="; \
echo "Time: $$(date)"; \
echo ""; \
echo "Container Status:"; \
docker-compose ps; \
echo ""; \
echo "Resource Usage:"; \
docker stats $(CONTAINER_NAME) --no-stream 2>/dev/null || echo "Container not running"; \
echo ""; \
echo "Last 5 log lines:"; \
docker-compose logs --tail=5 $(SERVICE_NAME) 2>/dev/null || echo "No logs available"; \
sleep 5; \
done
# Обновление
update: ## Обновить код и перезапустить
@echo "📥 Updating application..."
git pull
@make redeploy
# Конфигурация
setup: ## Первоначальная настройка
@echo "⚙️ Initial setup..."
@if [ ! -f .env ]; then \
echo "📝 Creating .env file from template..."; \
cp env.example .env; \
echo "✅ Please edit .env file with your configuration"; \
else \
echo "✅ .env file already exists"; \
fi
@echo "📁 Creating directories..."
mkdir -p logs images data
chmod 755 logs images data
@echo "✅ Setup complete! Edit .env file and run 'make deploy'"
# По умолчанию
.DEFAULT_GOAL := help

236
README_DOCKER.md Normal file
View File

@ -0,0 +1,236 @@
# SalvageDB Telegram Bot - Docker Deployment
Полная инструкция по развертыванию SalvageDB Telegram Bot в Docker контейнере.
## 📋 Требования
- Docker Engine 20.10+
- Docker Compose 2.0+
- Минимум 512 MB RAM
- Доступ к Oracle Database
## 🚀 Быстрый старт
### 1. Подготовка переменных окружения
Скопируйте файл с примером и настройте переменные:
```bash
cp env.example .env
nano .env
```
Обязательно настройте следующие переменные:
- `BOT_TOKEN` - токен от @BotFather
- `DB_USER`, `DB_PASSWORD`, `DB_DSN` - настройки Oracle DB
- `ADMIN_USER_ID` - ваш Telegram ID для админ-функций
### 2. Создание необходимых директорий
```bash
# Создаем директории для данных
mkdir -p logs images data
# Устанавливаем права доступа
chmod 755 logs images data
```
### 3. Запуск контейнера
```bash
# Сборка и запуск
docker-compose up --build -d
# Проверка статуса
docker-compose ps
# Просмотр логов
docker-compose logs -f salvagedb-bot
```
## 📁 Структура проекта
```
salvagedb_bot/
├── Dockerfile # Конфигурация Docker образа
├── docker-compose.yml # Orchestration конфигурация
├── docker-entrypoint.sh # Скрипт инициализации
├── .dockerignore # Исключения для Docker
├── env.example # Пример переменных окружения
├── requirements.txt # Python зависимости
├── main.py # Основной код бота
├── db.py # Модуль работы с БД
├── middlewares/ # Middleware компоненты
├── logs/ # Логи приложения (volume)
├── images/ # Изображения автомобилей (volume)
└── data/ # Дополнительные данные (volume)
```
## 🔧 Конфигурация
### Переменные окружения
| Переменная | Описание | Значение по умолчанию |
|-----------|----------|----------------------|
| `BOT_TOKEN` | Токен Telegram бота | **Обязательно** |
| `BOT_NAME` | Имя бота | `SalvageDB Bot` |
| `ADMIN_USER_ID` | ID администратора | **Обязательно** |
| `DECODE_PRICE` | Цена декодирования VIN | `1` |
| `CHECK_PRICE` | Цена проверки повреждений | `10` |
| `IMG_PRICE` | Цена доступа к фото | `100` |
| `DB_USER` | Пользователь Oracle DB | **Обязательно** |
| `DB_PASSWORD` | Пароль Oracle DB | **Обязательно** |
| `DB_DSN` | DSN строка Oracle DB | **Обязательно** |
| `DEBUG` | Режим отладки | `0` |
| `TIMEZONE` | Часовой пояс | `UTC` |
### Volumes
- `./logs:/home/salvagebot/app/logs` - Логи приложения
- `./images:/home/salvagebot/app/images:ro` - Изображения (read-only)
- `./data:/home/salvagebot/app/data` - Дополнительные данные
## 🛠️ Управление контейнером
### Основные команды
```bash
# Запуск
docker-compose up -d
# Остановка
docker-compose down
# Перезапуск
docker-compose restart
# Пересборка и запуск
docker-compose up --build -d
# Просмотр логов в реальном времени
docker-compose logs -f salvagedb-bot
# Подключение к контейнеру
docker-compose exec salvagedb-bot bash
# Просмотр статуса
docker-compose ps
```
### Мониторинг
```bash
# Проверка здоровья контейнера
docker-compose exec salvagedb-bot python -c "print('Bot is healthy!')"
# Статистика ресурсов
docker stats salvagedb-telegram-bot
# Информация о контейнере
docker inspect salvagedb-telegram-bot
```
## 📊 Логирование
### Структура логов
Логи сохраняются в директории `./logs/`:
- `salvagedb_bot.log` - текущий лог файл
- `salvagedb_bot.log.YYYY-MM-DD` - архивные логи
### Конфигурация логирования
- **Ротация:** ежедневно в полночь
- **Хранение:** 30 дней
- **Формат:** `YYYY-MM-DD HH:MM:SS - module - LEVEL - message`
- **Уровни:** INFO, WARNING, ERROR
## 🔒 Безопасность
### Рекомендации
1. **Переменные окружения:**
- Никогда не коммитьте `.env` файл
- Используйте сильные пароли для БД
- Ограничьте доступ к токену бота
2. **Сетевая безопасность:**
- Контейнер работает в изолированной сети
- Нет открытых портов (только исходящие соединения)
3. **Файловая система:**
- Приложение работает под непривилегированным пользователем
- Read-only монтирование для изображений
## 🐛 Устранение неполадок
### Проблемы с Oracle
```bash
# Проверка Oracle client в контейнере
docker-compose exec salvagedb-bot python -c "import oracledb; print(oracledb.version)"
# Тест подключения к БД
docker-compose exec salvagedb-bot python -c "
import oracledb
import os
conn = oracledb.connect(user=os.getenv('DB_USER'), password=os.getenv('DB_PASSWORD'), dsn=os.getenv('DB_DSN'))
print('Connection successful!')
conn.close()
"
```
### Проблемы с ботом
```bash
# Проверка токена бота
docker-compose exec salvagedb-bot python -c "
import os
print('Bot token length:', len(os.getenv('BOT_TOKEN', '')))
"
# Проверка aiogram
docker-compose exec salvagebot-bot python -c "import aiogram; print('aiogram version:', aiogram.__version__)"
```
### Логи отладки
```bash
# Включить DEBUG режим
echo "DEBUG=1" >> .env
docker-compose restart
# Просмотр подробных логов
docker-compose logs -f --tail=100 salvagedb-bot
```
## 🔄 Обновление
```bash
# Остановить контейнер
docker-compose down
# Обновить код
git pull
# Пересобрать и запустить
docker-compose up --build -d
# Проверить статус
docker-compose logs -f salvagedb-bot
```
## 📞 Поддержка
При возникновении проблем:
1. Проверьте логи: `docker-compose logs salvagedb-bot`
2. Убедитесь в правильности переменных окружения
3. Проверьте подключение к Oracle DB
4. Проверьте валидность токена бота
## 🏷️ Теги версий
- `latest` - последняя стабильная версия
- `dev` - версия для разработки
- `v1.x.x` - конкретные релизы

115
docker-compose.yml Normal file
View File

@ -0,0 +1,115 @@
version: '3.8'
services:
salvagedb-bot:
build:
context: .
dockerfile: Dockerfile
container_name: salvagedb-telegram-bot
restart: unless-stopped
# Переменные окружения
environment:
# Telegram Bot настройки
- BOT_TOKEN=${BOT_TOKEN}
- BOT_NAME=${BOT_NAME:-SalvageDB Bot}
- ADMIN_USER_ID=${ADMIN_USER_ID}
# Цены на услуги (в Telegram Stars)
- DECODE_PRICE=${DECODE_PRICE:-1}
- CHECK_PRICE=${CHECK_PRICE:-10}
- IMG_PRICE=${IMG_PRICE:-100}
# База данных Oracle
- db_user=${DB_USER}
- db_password=${DB_PASSWORD}
- db_dsn=${DB_DSN}
# Настройки приложения
- DEBUG=${DEBUG:-0}
- PYTHONUNBUFFERED=1
- TZ=${TIMEZONE:-UTC}
# Монтируем volumes для логов и изображений
volumes:
- ./logs:/home/salvagebot/app/logs
- ./images:/home/salvagebot/app/images:ro # read-only для изображений
- ./data:/home/salvagebot/app/data # дополнительные данные если нужны
# Настройки сети
networks:
- salvagedb-network
# Ограничения ресурсов
deploy:
resources:
limits:
memory: 512M
cpus: '0.5'
reservations:
memory: 256M
cpus: '0.25'
# Политика перезапуска
restart: unless-stopped
# Зависимости (если есть другие сервисы)
depends_on: []
# Логирование
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# Проверка здоровья
healthcheck:
test: ["CMD", "python", "-c", "import sys; sys.exit(0)"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# Дополнительные сервисы (если понадобятся)
# nginx:
# image: nginx:alpine
# container_name: salvagedb-nginx
# restart: unless-stopped
# ports:
# - "80:80"
# - "443:443"
# volumes:
# - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
# - ./nginx/ssl:/etc/nginx/ssl:ro
# networks:
# - salvagedb-network
# depends_on:
# - salvagedb-bot
# redis:
# image: redis:7-alpine
# container_name: salvagedb-redis
# restart: unless-stopped
# volumes:
# - redis_data:/data
# networks:
# - salvagedb-network
# command: redis-server --appendonly yes
# Определяем сети
networks:
salvagedb-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
# Определяем volumes
volumes:
# redis_data:
# driver: local
logs_data:
driver: local
images_data:
driver: local

98
docker-entrypoint.sh Normal file
View File

@ -0,0 +1,98 @@
#!/bin/bash
# Скрипт инициализации для Docker контейнера SalvageDB Bot
set -e
echo "====================================================="
echo "SalvageDB Telegram Bot - Docker Container Startup"
echo "====================================================="
# Проверяем обязательные переменные окружения
check_env_var() {
if [ -z "${!1}" ]; then
echo "❌ ERROR: Environment variable $1 is not set!"
echo "Please check your .env file or docker-compose.yml"
exit 1
else
echo "$1 is configured"
fi
}
echo "🔍 Checking required environment variables..."
check_env_var BOT_TOKEN
check_env_var DB_USER
check_env_var DB_PASSWORD
check_env_var DB_DSN
check_env_var ADMIN_USER_ID
echo ""
echo "📋 Configuration Summary:"
echo " • Bot Name: ${BOT_NAME:-'SalvageDB Bot'}"
echo " • Debug Mode: ${DEBUG:-'0'}"
echo " • Timezone: ${TZ:-'UTC'}"
echo " • Decode Price: ${DECODE_PRICE:-'1'}"
echo " • Check Price: ${CHECK_PRICE:-'10'}"
echo " • Image Price: ${IMG_PRICE:-'100'}"
echo " • Database DSN: ${DB_DSN}"
echo " • Admin User ID: ${ADMIN_USER_ID}"
echo ""
echo "📁 Creating directories..."
mkdir -p /home/salvagebot/app/logs
mkdir -p /home/salvagebot/app/images
mkdir -p /home/salvagebot/app/data
echo "✅ Directory structure created"
echo ""
echo "🐍 Testing Python environment..."
python -c "
import sys
print(f'Python version: {sys.version}')
print(f'Python path: {sys.executable}')
"
echo ""
echo "📦 Testing critical imports..."
python -c "
try:
import aiogram
print('✅ aiogram imported successfully')
import oracledb
print('✅ oracledb imported successfully')
import asyncio
print('✅ asyncio imported successfully')
import logging
print('✅ logging imported successfully')
print('🎉 All critical dependencies are available')
except ImportError as e:
print(f'❌ Import error: {e}')
exit(1)
"
echo ""
echo "🔗 Testing Oracle connectivity..."
python -c "
import oracledb
import os
try:
# Тестируем создание пула соединений (без подключения к БД)
print('Testing Oracle client library...')
print(f'Oracle client version: {oracledb.version}')
print('✅ Oracle client is ready')
except Exception as e:
print(f'❌ Oracle client error: {e}')
exit(1)
"
echo ""
echo "🚀 Starting SalvageDB Telegram Bot..."
echo "====================================================="
# Запускаем основное приложение
exec "$@"

61
env.example Normal file
View File

@ -0,0 +1,61 @@
# ==================================================
# SALVAGEDB TELEGRAM BOT - ПЕРЕМЕННЫЕ ОКРУЖЕНИЯ
# ==================================================
# --------------------------------------------------
# TELEGRAM BOT НАСТРОЙКИ
# --------------------------------------------------
# Токен бота от @BotFather
BOT_TOKEN=your_bot_token_here
# Имя бота (опционально)
BOT_NAME=SalvageDB Bot
# ID администратора для возврата платежей и статистики
ADMIN_USER_ID=123456789
# --------------------------------------------------
# ЦЕНЫ НА УСЛУГИ (в Telegram Stars)
# --------------------------------------------------
# Цена за детальную информацию о VIN
DECODE_PRICE=1
# Цена за детальную проверку повреждений
CHECK_PRICE=10
# Цена за доступ к фотографиям
IMG_PRICE=100
# --------------------------------------------------
# БАЗА ДАННЫХ ORACLE
# --------------------------------------------------
# Пользователь базы данных
DB_USER=your_db_user
# Пароль базы данных
DB_PASSWORD=your_db_password
# DSN строка подключения к Oracle
# Формат: host:port/service_name
DB_DSN=localhost:1521/XEPDB1
# --------------------------------------------------
# НАСТРОЙКИ ПРИЛОЖЕНИЯ
# --------------------------------------------------
# Режим отладки (0 = выключен, 1 = включен)
DEBUG=0
# Часовой пояс
TIMEZONE=UTC
# --------------------------------------------------
# ДОПОЛНИТЕЛЬНЫЕ НАСТРОЙКИ (опционально)
# --------------------------------------------------
# Максимальный размер лог файла
LOG_MAX_SIZE=10M
# Количество архивных лог файлов
LOG_MAX_FILES=3
# Интервал очистки временных файлов (в часах)
CLEANUP_INTERVAL=24

View File

@ -75,6 +75,15 @@ def setup_logging():
logging.info(f"Log level: {logging.getLevelName(log_level)}") logging.info(f"Log level: {logging.getLevelName(log_level)}")
logging.info(f"Logs directory: {os.path.abspath(logs_dir)}") logging.info(f"Logs directory: {os.path.abspath(logs_dir)}")
logging.info(f"Log rotation: daily, keeping 30 days") logging.info(f"Log rotation: daily, keeping 30 days")
# Проверяем запуск в Docker
if os.path.exists('/.dockerenv'):
logging.info("Running inside Docker container")
logging.info(f"Container timezone: {getenv('TZ', 'UTC')}")
logging.info(f"Container user: {getenv('USER', 'unknown')}")
else:
logging.info("Running on host system")
logging.info("=== LOGGING SETUP COMPLETE ===") logging.info("=== LOGGING SETUP COMPLETE ===")

20
requirements.txt Normal file
View File

@ -0,0 +1,20 @@
# Telegram Bot Framework
aiogram==3.13.1
# Oracle Database
oracledb==2.5.0
# Async HTTP client (зависимость aiogram)
aiohttp==3.10.11
# Дополнительные зависимости для работы с данными
typing-extensions==4.12.2
# Для работы с датами и временем
python-dateutil==2.9.0
# Для логирования (встроенно в Python, но для совместимости)
# logging - встроенно
# Для работы с переменными окружения
python-dotenv==1.0.1