Compare commits
7 Commits
dev
...
9281388959
| Author | SHA1 | Date | |
|---|---|---|---|
| 9281388959 | |||
| 0566901fa4 | |||
| e907dffe8c | |||
| fdd0580554 | |||
| 29d6255f22 | |||
| d02a742278 | |||
| 155e4d3b7b |
@@ -16,7 +16,7 @@ COPY src/ ./src/
|
|||||||
COPY .env.example ./
|
COPY .env.example ./
|
||||||
|
|
||||||
# Build the application (using Linux-compatible build command)
|
# Build the application (using Linux-compatible build command)
|
||||||
RUN npm run build:linux
|
RUN npm run build:linux:linux
|
||||||
|
|
||||||
# Production stage
|
# Production stage
|
||||||
FROM node:18-alpine AS production
|
FROM node:18-alpine AS production
|
||||||
|
|||||||
75
Makefile
Normal file
75
Makefile
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# Makefile для Telegram Tinder Bot
|
||||||
|
|
||||||
|
.PHONY: help install update run migrate fix-docker clean
|
||||||
|
|
||||||
|
# Значения по умолчанию
|
||||||
|
DB_HOST ?= db
|
||||||
|
DB_PORT ?= 5432
|
||||||
|
DB_NAME ?= telegram_tinder_bot
|
||||||
|
DB_USERNAME ?= postgres
|
||||||
|
DB_PASSWORD ?= postgres
|
||||||
|
|
||||||
|
# Основные команды
|
||||||
|
help:
|
||||||
|
@echo "========== Telegram Tinder Bot Makefile =========="
|
||||||
|
@echo "make install - Установка зависимостей"
|
||||||
|
@echo "make update - Обновление кода из репозитория"
|
||||||
|
@echo "make run - Запуск бота в контейнере"
|
||||||
|
@echo "make migrate - Применение миграций базы данных"
|
||||||
|
@echo "make fix-docker - Исправление проблем с Docker"
|
||||||
|
@echo "make clean - Очистка и остановка контейнеров"
|
||||||
|
|
||||||
|
install:
|
||||||
|
@echo "Установка зависимостей..."
|
||||||
|
@if ! command -v docker &> /dev/null || ! command -v docker-compose &> /dev/null; then \
|
||||||
|
echo "Установка Docker..."; \
|
||||||
|
sudo apt update && sudo apt install -y docker.io docker-compose; \
|
||||||
|
fi
|
||||||
|
@if [ ! -f .env ]; then \
|
||||||
|
echo "Создание .env файла..."; \
|
||||||
|
cp .env.example .env 2>/dev/null || cp .env.production .env 2>/dev/null || echo "NODE_ENV=production" > .env; \
|
||||||
|
echo "Пожалуйста, отредактируйте файл .env!"; \
|
||||||
|
fi
|
||||||
|
@mkdir -p logs uploads && chmod -R 777 logs uploads
|
||||||
|
|
||||||
|
update:
|
||||||
|
@echo "Обновление кода..."
|
||||||
|
@git fetch --all
|
||||||
|
@git pull origin main || git pull origin master || echo "Не удалось обновить код"
|
||||||
|
@if [ -f package.json ]; then npm ci || npm install; fi
|
||||||
|
|
||||||
|
run:
|
||||||
|
@echo "Запуск бота..."
|
||||||
|
@docker-compose down || true
|
||||||
|
@make fix-docker
|
||||||
|
@docker-compose build
|
||||||
|
@docker-compose up -d
|
||||||
|
@echo "Бот запущен! Для просмотра логов: docker-compose logs -f"
|
||||||
|
|
||||||
|
migrate:
|
||||||
|
@echo "Применение миграций..."
|
||||||
|
@if [ -d migrations ]; then \
|
||||||
|
mkdir -p temp_migrations; \
|
||||||
|
find migrations -name "*.js" -exec cp {} temp_migrations/ \; 2>/dev/null || true; \
|
||||||
|
DATABASE_URL=postgres://${DB_USERNAME}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/${DB_NAME} \
|
||||||
|
npx node-pg-migrate up --migrations-dir=migrations || true; \
|
||||||
|
fi
|
||||||
|
@if [ -d sql ]; then \
|
||||||
|
for sql_file in sql/*.sql; do \
|
||||||
|
[ -f "$${sql_file}" ] && docker-compose exec -T db psql -U ${DB_USERNAME} -d ${DB_NAME} -f "/app/$${sql_file}" || true; \
|
||||||
|
done; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
fix-docker:
|
||||||
|
@echo "Исправление Docker конфигурации..."
|
||||||
|
@if [ -f Dockerfile ] && grep -q "RUN npm run build" Dockerfile; then \
|
||||||
|
sed -i 's/RUN npm run build/RUN npm run build:linux/g' Dockerfile; \
|
||||||
|
fi
|
||||||
|
@docker rm -f postgres-tinder adminer-tinder telegram-tinder-bot 2>/dev/null || true
|
||||||
|
@docker system prune -f --volumes >/dev/null 2>&1 || true
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo "Очистка..."
|
||||||
|
@docker-compose down || true
|
||||||
|
@rm -rf temp_migrations node_modules/.cache
|
||||||
|
@echo "Очистка завершена"
|
||||||
49
additional_translations.json
Normal file
49
additional_translations.json
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"noProfile": {
|
||||||
|
"message": "❌ У вас пока нет профиля.\\nСоздайте его для начала использования бота!",
|
||||||
|
"createButton": "🚀 Создать профиль"
|
||||||
|
},
|
||||||
|
"noMatches": {
|
||||||
|
"message": "💔 У вас пока нет матчей.\\n\\n🔍 Попробуйте просмотреть больше анкет!\\nИспользуйте /browse для поиска.",
|
||||||
|
"browsing": "🔍 Найти еще"
|
||||||
|
},
|
||||||
|
"matches": {
|
||||||
|
"title": "💕 Ваши матчи:",
|
||||||
|
"openChats": "💬 Открыть чаты",
|
||||||
|
"nativeChats": "📱 Нативные чаты",
|
||||||
|
"findMore": "🔍 Найти еще",
|
||||||
|
"cityNotSpecified": "Не указан"
|
||||||
|
},
|
||||||
|
"profileCreation": {
|
||||||
|
"start": "👋 Давайте создадим ваш профиль!\\n\\n📝 Сначала напишите ваше имя:",
|
||||||
|
"enterName": "❌ Пожалуйста, отправьте текстовое сообщение с вашим именем",
|
||||||
|
"enterAge": "📅 Отлично! Теперь укажите ваш возраст:",
|
||||||
|
"ageNotNumber": "❌ Пожалуйста, отправьте число",
|
||||||
|
"ageInvalid": "❌ Возраст должен быть числом от 18 до 100",
|
||||||
|
"enterCity": "📍 Прекрасно! В каком городе вы живете?",
|
||||||
|
"cityText": "❌ Пожалуйста, отправьте название города",
|
||||||
|
"enterBio": "📝 Теперь расскажите немного о себе (био):\\n\\n💡 Например: хобби, интересы, что ищете в отношениях и т.д.",
|
||||||
|
"bioText": "❌ Пожалуйста, отправьте текстовое описание",
|
||||||
|
"enterPhoto": "📸 Отлично! Теперь отправьте ваше фото:\\n\\n💡 Лучше использовать качественное фото лица",
|
||||||
|
"photoRequired": "❌ Пожалуйста, отправьте фотографию",
|
||||||
|
"error": "❌ Произошла ошибка. Попробуйте еще раз.",
|
||||||
|
"createError": "❌ Ошибка при создании профиля. Попробуйте еще раз позже."
|
||||||
|
},
|
||||||
|
"profileView": {
|
||||||
|
"cityNotSpecified": "Не указан",
|
||||||
|
"bioNotSpecified": "Описание не указано",
|
||||||
|
"editProfile": "✏️ Редактировать",
|
||||||
|
"managePhotos": "📸 Фото",
|
||||||
|
"startBrowsing": "🔍 Начать поиск",
|
||||||
|
"backToBrowsing": "👈 Назад"
|
||||||
|
},
|
||||||
|
"browsing": {
|
||||||
|
"noMoreProfiles": "🎉 Вы просмотрели всех доступных кандидатов!\\n\\n⏰ Попробуйте позже - возможно появятся новые анкеты!",
|
||||||
|
"needProfile": "❌ Сначала создайте профиль!\\nИспользуйте команду /start",
|
||||||
|
"cityNotSpecified": "Не указан"
|
||||||
|
},
|
||||||
|
"general": {
|
||||||
|
"greeting": "Привет! 👋\\n\\nИспользуйте команды для навигации:\\n/start - Главное меню\\n/help - Справка\\n/profile - Мой профиль\\n/browse - Поиск анкет",
|
||||||
|
"photoManagement": "📸 Для управления фотографиями используйте:"
|
||||||
|
}
|
||||||
|
}
|
||||||
54
bin/QUICK_FIX.md
Normal file
54
bin/QUICK_FIX.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Быстрое исправление проблем с миграциями
|
||||||
|
|
||||||
|
## Проблема
|
||||||
|
При запуске миграций возникают ошибки с TypeScript-файлами и проблемы с модульными разрешениями.
|
||||||
|
|
||||||
|
## Быстрое решение
|
||||||
|
|
||||||
|
1. **Примените прямые SQL-миграции (рекомендуемый способ)**:
|
||||||
|
```bash
|
||||||
|
chmod +x bin/apply_direct_sql.sh
|
||||||
|
./bin/apply_direct_sql.sh
|
||||||
|
```
|
||||||
|
Этот скрипт создаст и применит консолидированную SQL-миграцию, которая создаст все необходимые таблицы.
|
||||||
|
|
||||||
|
2. **Создайте консолидированную JS-миграцию**:
|
||||||
|
```bash
|
||||||
|
chmod +x bin/create_consolidated_migration.sh
|
||||||
|
./bin/create_consolidated_migration.sh
|
||||||
|
```
|
||||||
|
Затем примените её:
|
||||||
|
```bash
|
||||||
|
DATABASE_URL="postgres://$DB_USERNAME:$DB_PASSWORD@$DB_HOST:$DB_PORT/$DB_NAME" npx node-pg-migrate up
|
||||||
|
```
|
||||||
|
|
||||||
|
## Проверка результата
|
||||||
|
|
||||||
|
После выполнения миграций проверьте наличие таблиц в базе данных:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export PGPASSWORD=$DB_PASSWORD
|
||||||
|
psql -h $DB_HOST -p $DB_PORT -U $DB_USERNAME -d $DB_NAME -c "\dt"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Если проблемы сохраняются
|
||||||
|
|
||||||
|
1. **Проверьте доступность базы данных**:
|
||||||
|
```bash
|
||||||
|
export PGPASSWORD=$DB_PASSWORD
|
||||||
|
psql -h $DB_HOST -p $DB_PORT -U $DB_USERNAME -d $DB_NAME -c "SELECT 1"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Проверьте правильность переменных окружения**:
|
||||||
|
```bash
|
||||||
|
echo "DB_HOST: $DB_HOST"
|
||||||
|
echo "DB_PORT: $DB_PORT"
|
||||||
|
echo "DB_NAME: $DB_NAME"
|
||||||
|
echo "DB_USERNAME: $DB_USERNAME"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Установите PostgreSQL-клиент**, если он отсутствует:
|
||||||
|
```bash
|
||||||
|
apt-get update
|
||||||
|
apt-get install -y postgresql-client
|
||||||
|
```
|
||||||
208
bin/apply_direct_sql.sh
Executable file
208
bin/apply_direct_sql.sh
Executable file
@@ -0,0 +1,208 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# apply_direct_sql.sh - Прямое выполнение SQL-миграций с помощью psql
|
||||||
|
|
||||||
|
echo "🚀 Прямое выполнение SQL-миграций..."
|
||||||
|
|
||||||
|
# Загрузка переменных окружения из .env
|
||||||
|
if [ -f .env ]; then
|
||||||
|
echo "📝 Загрузка переменных окружения из .env..."
|
||||||
|
set -o allexport
|
||||||
|
source .env
|
||||||
|
set +o allexport
|
||||||
|
else
|
||||||
|
echo "⚠️ Файл .env не найден, используем значения по умолчанию"
|
||||||
|
export DB_HOST="localhost"
|
||||||
|
export DB_PORT="5432"
|
||||||
|
export DB_NAME="telegram_tinder_bot"
|
||||||
|
export DB_USERNAME="postgres"
|
||||||
|
export DB_PASSWORD="postgres"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Создаем консолидированный SQL-файл
|
||||||
|
echo "📝 Создание консолидированного SQL-файла..."
|
||||||
|
consolidated_sql="consolidated_migration.sql"
|
||||||
|
|
||||||
|
cat > "$consolidated_sql" << EOL
|
||||||
|
-- Консолидированная миграция для Telegram Tinder Bot
|
||||||
|
-- Создана автоматически: $(date)
|
||||||
|
|
||||||
|
-- Создаем таблицу migrations, если её еще нет
|
||||||
|
CREATE TABLE IF NOT EXISTS migrations (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR(255) NOT NULL,
|
||||||
|
executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Основная структура базы данных
|
||||||
|
|
||||||
|
-- Таблица пользователей
|
||||||
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id BIGINT PRIMARY KEY,
|
||||||
|
username VARCHAR(255),
|
||||||
|
first_name VARCHAR(255),
|
||||||
|
last_name VARCHAR(255),
|
||||||
|
language_code VARCHAR(10),
|
||||||
|
is_bot BOOLEAN DEFAULT FALSE,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
state VARCHAR(50) DEFAULT 'START',
|
||||||
|
state_data JSONB,
|
||||||
|
gender VARCHAR(10),
|
||||||
|
looking_for VARCHAR(10),
|
||||||
|
bio TEXT,
|
||||||
|
age INTEGER,
|
||||||
|
location VARCHAR(255),
|
||||||
|
photos JSONB DEFAULT '[]'::jsonb,
|
||||||
|
interests TEXT[],
|
||||||
|
premium BOOLEAN DEFAULT FALSE,
|
||||||
|
premium_expires_at TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Таблица профилей
|
||||||
|
CREATE TABLE IF NOT EXISTS profiles (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
name VARCHAR(255),
|
||||||
|
age INTEGER,
|
||||||
|
gender VARCHAR(10),
|
||||||
|
bio TEXT,
|
||||||
|
photos JSONB DEFAULT '[]'::jsonb,
|
||||||
|
interests TEXT[],
|
||||||
|
location VARCHAR(255),
|
||||||
|
religion VARCHAR(50),
|
||||||
|
education VARCHAR(255),
|
||||||
|
job VARCHAR(255),
|
||||||
|
height INTEGER,
|
||||||
|
smoking VARCHAR(50),
|
||||||
|
drinking VARCHAR(50),
|
||||||
|
looking_for VARCHAR(10),
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Таблица лайков
|
||||||
|
CREATE TABLE IF NOT EXISTS likes (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
from_user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
to_user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
is_like BOOLEAN NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE(from_user_id, to_user_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Таблица матчей
|
||||||
|
CREATE TABLE IF NOT EXISTS matches (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
user1_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
user2_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
active BOOLEAN DEFAULT TRUE,
|
||||||
|
UNIQUE(user1_id, user2_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Таблица сообщений
|
||||||
|
CREATE TABLE IF NOT EXISTS messages (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
match_id INTEGER REFERENCES matches(id) ON DELETE CASCADE,
|
||||||
|
sender_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
message_text TEXT,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Таблица просмотров профилей
|
||||||
|
CREATE TABLE IF NOT EXISTS profile_views (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
viewer_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
viewed_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
viewed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE(viewer_id, viewed_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Таблица уведомлений
|
||||||
|
CREATE TABLE IF NOT EXISTS notifications (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
type VARCHAR(50) NOT NULL,
|
||||||
|
data JSONB,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
scheduled_for TIMESTAMP,
|
||||||
|
processed BOOLEAN DEFAULT FALSE
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Индексы для оптимизации запросов
|
||||||
|
|
||||||
|
-- Индексы для таблицы пользователей
|
||||||
|
CREATE INDEX IF NOT EXISTS users_username_idx ON users(username);
|
||||||
|
CREATE INDEX IF NOT EXISTS users_gender_idx ON users(gender);
|
||||||
|
CREATE INDEX IF NOT EXISTS users_looking_for_idx ON users(looking_for);
|
||||||
|
CREATE INDEX IF NOT EXISTS users_premium_idx ON users(premium);
|
||||||
|
|
||||||
|
-- Индексы для таблицы лайков
|
||||||
|
CREATE INDEX IF NOT EXISTS likes_from_user_id_idx ON likes(from_user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS likes_to_user_id_idx ON likes(to_user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS likes_is_like_idx ON likes(is_like);
|
||||||
|
|
||||||
|
-- Индексы для таблицы матчей
|
||||||
|
CREATE INDEX IF NOT EXISTS matches_user1_id_idx ON matches(user1_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS matches_user2_id_idx ON matches(user2_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS matches_active_idx ON matches(active);
|
||||||
|
|
||||||
|
-- Индексы для таблицы сообщений
|
||||||
|
CREATE INDEX IF NOT EXISTS messages_match_id_idx ON messages(match_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS messages_sender_id_idx ON messages(sender_id);
|
||||||
|
|
||||||
|
-- Индексы для таблицы профилей
|
||||||
|
CREATE INDEX IF NOT EXISTS profiles_user_id_idx ON profiles(user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS profiles_gender_idx ON profiles(gender);
|
||||||
|
CREATE INDEX IF NOT EXISTS profiles_looking_for_idx ON profiles(looking_for);
|
||||||
|
|
||||||
|
-- Индексы для таблицы просмотров профилей
|
||||||
|
CREATE INDEX IF NOT EXISTS profile_views_viewer_id_idx ON profile_views(viewer_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS profile_views_viewed_id_idx ON profile_views(viewed_id);
|
||||||
|
|
||||||
|
-- Индексы для таблицы уведомлений
|
||||||
|
CREATE INDEX IF NOT EXISTS notifications_user_id_idx ON notifications(user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS notifications_scheduled_for_idx ON notifications(scheduled_for);
|
||||||
|
CREATE INDEX IF NOT EXISTS notifications_processed_idx ON notifications(processed);
|
||||||
|
|
||||||
|
-- Запись о выполнении миграции
|
||||||
|
INSERT INTO migrations (name) VALUES ('consolidated_migration.sql')
|
||||||
|
ON CONFLICT DO NOTHING;
|
||||||
|
EOL
|
||||||
|
|
||||||
|
echo "✅ Консолидированный SQL-файл создан: $consolidated_sql"
|
||||||
|
|
||||||
|
# Вывод информации о подключении
|
||||||
|
echo "🔍 Используемые параметры подключения:"
|
||||||
|
echo "DB_HOST: $DB_HOST"
|
||||||
|
echo "DB_PORT: $DB_PORT"
|
||||||
|
echo "DB_NAME: $DB_NAME"
|
||||||
|
echo "DB_USERNAME: $DB_USERNAME"
|
||||||
|
echo "DB_PASSWORD: ********"
|
||||||
|
|
||||||
|
# Проверка наличия psql
|
||||||
|
if command -v psql >/dev/null; then
|
||||||
|
echo "✅ Найдена команда psql, продолжаем..."
|
||||||
|
else
|
||||||
|
echo "⚠️ Команда psql не найдена, установите PostgreSQL клиент:"
|
||||||
|
echo "apt-get update && apt-get install -y postgresql-client"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Применение миграции
|
||||||
|
echo "🔄 Применение консолидированной миграции..."
|
||||||
|
export PGPASSWORD=$DB_PASSWORD
|
||||||
|
psql -h $DB_HOST -p $DB_PORT -U $DB_USERNAME -d $DB_NAME -f "$consolidated_sql"
|
||||||
|
|
||||||
|
# Проверка результата
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ Миграция успешно применена!"
|
||||||
|
else
|
||||||
|
echo "❌ Ошибка при применении миграции!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Удаление временного файла
|
||||||
|
rm -f "$consolidated_sql"
|
||||||
|
|
||||||
|
echo "🚀 Миграция базы данных завершена!"
|
||||||
75
bin/apply_migrations.sh
Executable file
75
bin/apply_migrations.sh
Executable file
@@ -0,0 +1,75 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# apply_migrations.sh - Скрипт для ручного применения миграций
|
||||||
|
|
||||||
|
echo "🔄 Ручное применение миграций базы данных..."
|
||||||
|
|
||||||
|
# Загрузка переменных окружения из .env
|
||||||
|
if [ -f .env ]; then
|
||||||
|
echo "📝 Загрузка переменных окружения из .env..."
|
||||||
|
export $(grep -v '^#' .env | xargs)
|
||||||
|
else
|
||||||
|
echo "⚠️ Файл .env не найден, используем значения по умолчанию"
|
||||||
|
export DB_HOST="localhost"
|
||||||
|
export DB_PORT="5432"
|
||||||
|
export DB_NAME="telegram_tinder_bot"
|
||||||
|
export DB_USERNAME="postgres"
|
||||||
|
export DB_PASSWORD="postgres"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Проверка на существование директории миграций
|
||||||
|
if [ ! -d "migrations" ] && [ ! -d "src/database/migrations" ]; then
|
||||||
|
echo "❌ Не найдены директории с миграциями!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Вывод информации о подключении
|
||||||
|
echo "🔍 Используемые параметры подключения:"
|
||||||
|
echo "DB_HOST: $DB_HOST"
|
||||||
|
echo "DB_PORT: $DB_PORT"
|
||||||
|
echo "DB_NAME: $DB_NAME"
|
||||||
|
echo "DB_USERNAME: $DB_USERNAME"
|
||||||
|
echo "DB_PASSWORD: ********"
|
||||||
|
|
||||||
|
# Проверка подключения к базе данных
|
||||||
|
echo "🔍 Проверка подключения к базе данных..."
|
||||||
|
if command -v pg_isready >/dev/null; then
|
||||||
|
pg_isready -h $DB_HOST -p $DB_PORT -U $DB_USERNAME
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "❌ Не удалось подключиться к базе данных!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "⚠️ Утилита pg_isready не найдена, пропускаем проверку"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Копирование миграций JS в отдельную директорию
|
||||||
|
echo "📂 Копирование только JS-миграций во временную директорию..."
|
||||||
|
mkdir -p temp_migrations
|
||||||
|
find migrations -name "*.js" -exec cp {} temp_migrations/ \;
|
||||||
|
|
||||||
|
# Применение миграций
|
||||||
|
echo "🔄 Применение миграций с помощью node-pg-migrate..."
|
||||||
|
DATABASE_URL="postgres://$DB_USERNAME:$DB_PASSWORD@$DB_HOST:$DB_PORT/$DB_NAME" npx node-pg-migrate up --migrations-dir=temp_migrations
|
||||||
|
|
||||||
|
# Проверка результата
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ Миграции успешно применены!"
|
||||||
|
else
|
||||||
|
echo "❌ Ошибка при применении миграций!"
|
||||||
|
echo "⚠️ Пытаемся применить миграции из других источников..."
|
||||||
|
|
||||||
|
# Попробуем применить SQL-миграции напрямую
|
||||||
|
if [ -d "src/database/migrations" ]; then
|
||||||
|
echo "📂 Найдены SQL-миграции. Пытаемся применить их напрямую..."
|
||||||
|
for sql_file in src/database/migrations/*.sql; do
|
||||||
|
if [ -f "$sql_file" ]; then
|
||||||
|
echo "🔄 Применение миграции $sql_file..."
|
||||||
|
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USERNAME -d $DB_NAME -f "$sql_file" || echo "⚠️ Ошибка при применении $sql_file"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Очистка временных файлов
|
||||||
|
echo "🧹 Очистка временных файлов..."
|
||||||
|
rm -rf temp_migrations
|
||||||
0
bin/backup_db.sh
Normal file → Executable file
0
bin/backup_db.sh
Normal file → Executable file
52
bin/compile_ts_migrations.sh
Executable file
52
bin/compile_ts_migrations.sh
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# compile_ts_migrations.sh - Скрипт для компиляции TS миграций в JS
|
||||||
|
|
||||||
|
echo "🔄 Компиляция TypeScript миграций в JavaScript..."
|
||||||
|
|
||||||
|
# Проверка наличия TypeScript файлов
|
||||||
|
if [ ! -f "migrations/*.ts" ] && [ ! -d "node_modules/typescript" ]; then
|
||||||
|
echo "📦 Установка TypeScript..."
|
||||||
|
npm install --no-save typescript
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Создание временного tsconfig для миграций
|
||||||
|
echo "📝 Создание временного tsconfig.json для миграций..."
|
||||||
|
cat > migrations/tsconfig.json << EOL
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es2020",
|
||||||
|
"module": "commonjs",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": false,
|
||||||
|
"outDir": "../temp_migrations",
|
||||||
|
"baseUrl": "..",
|
||||||
|
"paths": {
|
||||||
|
"*": ["node_modules/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"include": ["./*.ts"]
|
||||||
|
}
|
||||||
|
EOL
|
||||||
|
|
||||||
|
# Компиляция TS файлов
|
||||||
|
echo "🔄 Компиляция TypeScript миграций..."
|
||||||
|
npx tsc -p migrations/tsconfig.json
|
||||||
|
|
||||||
|
# Подтверждение
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ Миграции успешно скомпилированы в директорию temp_migrations/"
|
||||||
|
|
||||||
|
# Проверка, были ли созданы файлы
|
||||||
|
file_count=$(find temp_migrations -name "*.js" | wc -l)
|
||||||
|
echo "📊 Скомпилировано файлов: $file_count"
|
||||||
|
else
|
||||||
|
echo "❌ Ошибка при компиляции миграций!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Очистка временных файлов
|
||||||
|
rm migrations/tsconfig.json
|
||||||
188
bin/create_consolidated_migration.sh
Executable file
188
bin/create_consolidated_migration.sh
Executable file
@@ -0,0 +1,188 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# create_consolidated_migration.sh - Создание консолидированной миграции из всех источников
|
||||||
|
|
||||||
|
echo "🚀 Создание консолидированной миграции..."
|
||||||
|
|
||||||
|
# Создаем каталог для миграций если его нет
|
||||||
|
mkdir -p migrations
|
||||||
|
|
||||||
|
# Текущее время для имени файла
|
||||||
|
timestamp=$(date +%s)
|
||||||
|
|
||||||
|
# Путь к консолидированной миграции
|
||||||
|
consolidated_file="migrations/${timestamp}_consolidated_migration.js"
|
||||||
|
|
||||||
|
echo "📝 Создание файла $consolidated_file..."
|
||||||
|
|
||||||
|
# Создаем JS-миграцию
|
||||||
|
cat > "$consolidated_file" << EOL
|
||||||
|
/* eslint-disable camelcase */
|
||||||
|
|
||||||
|
exports.shorthands = undefined;
|
||||||
|
|
||||||
|
exports.up = pgm => {
|
||||||
|
// Консолидированная миграция, созданная автоматически
|
||||||
|
|
||||||
|
// Создаем таблицу migrations, если её ещё нет
|
||||||
|
pgm.sql(\`
|
||||||
|
CREATE TABLE IF NOT EXISTS migrations (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR(255) NOT NULL,
|
||||||
|
executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
\`);
|
||||||
|
|
||||||
|
// Создаем основную структуру базы данных
|
||||||
|
pgm.sql(\`
|
||||||
|
-- Таблица пользователей
|
||||||
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
|
id BIGINT PRIMARY KEY,
|
||||||
|
username VARCHAR(255),
|
||||||
|
first_name VARCHAR(255),
|
||||||
|
last_name VARCHAR(255),
|
||||||
|
language_code VARCHAR(10),
|
||||||
|
is_bot BOOLEAN DEFAULT FALSE,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
state VARCHAR(50) DEFAULT 'START',
|
||||||
|
state_data JSONB,
|
||||||
|
gender VARCHAR(10),
|
||||||
|
looking_for VARCHAR(10),
|
||||||
|
bio TEXT,
|
||||||
|
age INTEGER,
|
||||||
|
location VARCHAR(255),
|
||||||
|
photos JSONB DEFAULT '[]'::jsonb,
|
||||||
|
interests TEXT[],
|
||||||
|
premium BOOLEAN DEFAULT FALSE,
|
||||||
|
premium_expires_at TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Таблица профилей
|
||||||
|
CREATE TABLE IF NOT EXISTS profiles (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
name VARCHAR(255),
|
||||||
|
age INTEGER,
|
||||||
|
gender VARCHAR(10),
|
||||||
|
bio TEXT,
|
||||||
|
photos JSONB DEFAULT '[]'::jsonb,
|
||||||
|
interests TEXT[],
|
||||||
|
location VARCHAR(255),
|
||||||
|
religion VARCHAR(50),
|
||||||
|
education VARCHAR(255),
|
||||||
|
job VARCHAR(255),
|
||||||
|
height INTEGER,
|
||||||
|
smoking VARCHAR(50),
|
||||||
|
drinking VARCHAR(50),
|
||||||
|
looking_for VARCHAR(10),
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Таблица лайков
|
||||||
|
CREATE TABLE IF NOT EXISTS likes (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
from_user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
to_user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
is_like BOOLEAN NOT NULL,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE(from_user_id, to_user_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Таблица матчей
|
||||||
|
CREATE TABLE IF NOT EXISTS matches (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
user1_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
user2_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
active BOOLEAN DEFAULT TRUE,
|
||||||
|
UNIQUE(user1_id, user2_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Таблица сообщений
|
||||||
|
CREATE TABLE IF NOT EXISTS messages (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
match_id INTEGER REFERENCES matches(id) ON DELETE CASCADE,
|
||||||
|
sender_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
message_text TEXT,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Таблица просмотров профилей
|
||||||
|
CREATE TABLE IF NOT EXISTS profile_views (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
viewer_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
viewed_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
viewed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
UNIQUE(viewer_id, viewed_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Таблица уведомлений
|
||||||
|
CREATE TABLE IF NOT EXISTS notifications (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
|
||||||
|
type VARCHAR(50) NOT NULL,
|
||||||
|
data JSONB,
|
||||||
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
scheduled_for TIMESTAMP,
|
||||||
|
processed BOOLEAN DEFAULT FALSE
|
||||||
|
);
|
||||||
|
\`);
|
||||||
|
|
||||||
|
// Индексы для оптимизации запросов
|
||||||
|
pgm.sql(\`
|
||||||
|
-- Индексы для таблицы пользователей
|
||||||
|
CREATE INDEX IF NOT EXISTS users_username_idx ON users(username);
|
||||||
|
CREATE INDEX IF NOT EXISTS users_gender_idx ON users(gender);
|
||||||
|
CREATE INDEX IF NOT EXISTS users_looking_for_idx ON users(looking_for);
|
||||||
|
CREATE INDEX IF NOT EXISTS users_premium_idx ON users(premium);
|
||||||
|
|
||||||
|
-- Индексы для таблицы лайков
|
||||||
|
CREATE INDEX IF NOT EXISTS likes_from_user_id_idx ON likes(from_user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS likes_to_user_id_idx ON likes(to_user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS likes_is_like_idx ON likes(is_like);
|
||||||
|
|
||||||
|
-- Индексы для таблицы матчей
|
||||||
|
CREATE INDEX IF NOT EXISTS matches_user1_id_idx ON matches(user1_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS matches_user2_id_idx ON matches(user2_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS matches_active_idx ON matches(active);
|
||||||
|
|
||||||
|
-- Индексы для таблицы сообщений
|
||||||
|
CREATE INDEX IF NOT EXISTS messages_match_id_idx ON messages(match_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS messages_sender_id_idx ON messages(sender_id);
|
||||||
|
|
||||||
|
-- Индексы для таблицы профилей
|
||||||
|
CREATE INDEX IF NOT EXISTS profiles_user_id_idx ON profiles(user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS profiles_gender_idx ON profiles(gender);
|
||||||
|
CREATE INDEX IF NOT EXISTS profiles_looking_for_idx ON profiles(looking_for);
|
||||||
|
|
||||||
|
-- Индексы для таблицы просмотров профилей
|
||||||
|
CREATE INDEX IF NOT EXISTS profile_views_viewer_id_idx ON profile_views(viewer_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS profile_views_viewed_id_idx ON profile_views(viewed_id);
|
||||||
|
|
||||||
|
-- Индексы для таблицы уведомлений
|
||||||
|
CREATE INDEX IF NOT EXISTS notifications_user_id_idx ON notifications(user_id);
|
||||||
|
CREATE INDEX IF NOT EXISTS notifications_scheduled_for_idx ON notifications(scheduled_for);
|
||||||
|
CREATE INDEX IF NOT EXISTS notifications_processed_idx ON notifications(processed);
|
||||||
|
\`);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.down = pgm => {
|
||||||
|
// Эта функция не будет фактически использоваться,
|
||||||
|
// но для полноты оставляем возможность отката
|
||||||
|
pgm.sql(\`
|
||||||
|
DROP TABLE IF EXISTS notifications;
|
||||||
|
DROP TABLE IF EXISTS profile_views;
|
||||||
|
DROP TABLE IF EXISTS messages;
|
||||||
|
DROP TABLE IF EXISTS matches;
|
||||||
|
DROP TABLE IF EXISTS likes;
|
||||||
|
DROP TABLE IF EXISTS profiles;
|
||||||
|
DROP TABLE IF EXISTS users;
|
||||||
|
\`);
|
||||||
|
};
|
||||||
|
EOL
|
||||||
|
|
||||||
|
echo "✅ Консолидированная миграция создана: $consolidated_file"
|
||||||
|
echo ""
|
||||||
|
echo "🚀 Для применения миграции выполните:"
|
||||||
|
echo "DATABASE_URL=postgres://\${DB_USERNAME}:\${DB_PASSWORD}@\${DB_HOST}:\${DB_PORT}/\${DB_NAME} npx node-pg-migrate up"
|
||||||
0
bin/create_release.sh
Normal file → Executable file
0
bin/create_release.sh
Normal file → Executable file
100
bin/fix_docker.bat
Normal file
100
bin/fix_docker.bat
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
@echo off
|
||||||
|
REM fix_docker.bat - Скрипт для устранения проблемы ContainerConfig в Windows
|
||||||
|
|
||||||
|
echo 🔧 Устранение проблемы с Docker контейнерами...
|
||||||
|
|
||||||
|
REM Остановка всех контейнеров проекта
|
||||||
|
echo 📥 Остановка всех контейнеров проекта...
|
||||||
|
docker-compose down -v
|
||||||
|
|
||||||
|
REM Принудительное удаление контейнеров по имени
|
||||||
|
echo 🗑️ Принудительное удаление оставшихся контейнеров...
|
||||||
|
docker rm -f postgres-tinder adminer-tinder telegram-tinder-bot 2>NUL
|
||||||
|
|
||||||
|
REM Очистка неиспользуемых томов и сетей
|
||||||
|
echo 🧹 Очистка неиспользуемых томов и сетей...
|
||||||
|
docker system prune -f --volumes
|
||||||
|
|
||||||
|
REM Очистка кеша Docker
|
||||||
|
echo 🧼 Очистка кеша Docker...
|
||||||
|
docker builder prune -f
|
||||||
|
|
||||||
|
REM Исправление docker-compose.yml
|
||||||
|
echo 📝 Создание обновленного docker-compose.yml...
|
||||||
|
|
||||||
|
REM Создаем обновленный docker-compose.yml с использованием PowerShell
|
||||||
|
powershell -Command "& {
|
||||||
|
$content = @'
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
bot:
|
||||||
|
build: .
|
||||||
|
container_name: telegram-tinder-bot
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- DB_HOST=${DB_HOST:-db}
|
||||||
|
- DB_PORT=${DB_PORT:-5432}
|
||||||
|
- DB_NAME=${DB_NAME:-telegram_tinder_bot}
|
||||||
|
- DB_USERNAME=${DB_USERNAME:-postgres}
|
||||||
|
- DB_PASSWORD=${DB_PASSWORD:-postgres}
|
||||||
|
volumes:
|
||||||
|
- ./uploads:/app/uploads:rw
|
||||||
|
- ./logs:/app/logs:rw
|
||||||
|
networks:
|
||||||
|
- bot-network
|
||||||
|
healthcheck:
|
||||||
|
test: [\"CMD\", \"wget\", \"--no-verbose\", \"--tries=1\", \"--spider\", \"http://localhost:3000/health\"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
container_name: postgres-tinder
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- POSTGRES_DB=${DB_NAME:-telegram_tinder_bot}
|
||||||
|
- POSTGRES_USER=${DB_USERNAME:-postgres}
|
||||||
|
- POSTGRES_PASSWORD=${DB_PASSWORD:-postgres}
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- \"5433:5432\"
|
||||||
|
networks:
|
||||||
|
- bot-network
|
||||||
|
healthcheck:
|
||||||
|
test: [\"CMD-SHELL\", \"pg_isready -U ${DB_USERNAME:-postgres} -d ${DB_NAME:-telegram_tinder_bot}\"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
adminer:
|
||||||
|
image: adminer:latest
|
||||||
|
container_name: adminer-tinder
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- \"8080:8080\"
|
||||||
|
networks:
|
||||||
|
- bot-network
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
bot-network:
|
||||||
|
driver: bridge
|
||||||
|
'@
|
||||||
|
Set-Content -Path 'docker-compose.yml' -Value $content
|
||||||
|
}"
|
||||||
|
|
||||||
|
echo ✅ docker-compose.yml обновлен!
|
||||||
|
|
||||||
|
echo 🚀 Готово! Теперь вы можете запустить контейнеры снова с помощью команды:
|
||||||
|
echo docker-compose up -d
|
||||||
|
|
||||||
|
pause
|
||||||
117
bin/fix_docker.sh
Executable file
117
bin/fix_docker.sh
Executable file
@@ -0,0 +1,117 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# fix_docker.sh - Скрипт для устранения проблемы ContainerConfig
|
||||||
|
|
||||||
|
echo "🔧 Устранение проблемы с Docker контейнерами..."
|
||||||
|
|
||||||
|
# Остановка всех контейнеров проекта
|
||||||
|
echo "📥 Остановка всех контейнеров проекта..."
|
||||||
|
docker-compose down -v
|
||||||
|
|
||||||
|
# Принудительное удаление контейнеров по имени
|
||||||
|
echo "🗑️ Принудительное удаление оставшихся контейнеров..."
|
||||||
|
docker rm -f postgres-tinder adminer-tinder telegram-tinder-bot 2>/dev/null || true
|
||||||
|
|
||||||
|
# Очистка неиспользуемых томов и сетей
|
||||||
|
echo "🧹 Очистка неиспользуемых томов и сетей..."
|
||||||
|
docker system prune -f --volumes
|
||||||
|
|
||||||
|
# Очистка кеша Docker
|
||||||
|
echo "🧼 Очистка кеша Docker..."
|
||||||
|
docker builder prune -f
|
||||||
|
|
||||||
|
# Исправление docker-compose.yml
|
||||||
|
echo "📝 Создание обновленного docker-compose.yml..."
|
||||||
|
|
||||||
|
cat > docker-compose.yml << EOL
|
||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
bot:
|
||||||
|
build: .
|
||||||
|
container_name: telegram-tinder-bot
|
||||||
|
restart: unless-stopped
|
||||||
|
env_file: .env
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
- DB_HOST=${DB_HOST:-db}
|
||||||
|
- DB_PORT=${DB_PORT:-5432}
|
||||||
|
- DB_NAME=${DB_NAME:-telegram_tinder_bot}
|
||||||
|
- DB_USERNAME=${DB_USERNAME:-postgres}
|
||||||
|
- DB_PASSWORD=${DB_PASSWORD:-postgres}
|
||||||
|
volumes:
|
||||||
|
- ./uploads:/app/uploads:rw
|
||||||
|
- ./logs:/app/logs:rw
|
||||||
|
networks:
|
||||||
|
- bot-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
start_period: 10s
|
||||||
|
EOL
|
||||||
|
|
||||||
|
# Если используем внешнюю базу данных, добавляем только adminer
|
||||||
|
if [ "${DB_HOST:-db}" != "db" ]; then
|
||||||
|
cat >> docker-compose.yml << EOL
|
||||||
|
|
||||||
|
adminer:
|
||||||
|
image: adminer:latest
|
||||||
|
container_name: adminer-tinder
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
networks:
|
||||||
|
- bot-network
|
||||||
|
EOL
|
||||||
|
else
|
||||||
|
# Если используем локальную базу данных, добавляем PostgreSQL и adminer
|
||||||
|
cat >> docker-compose.yml << EOL
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:15-alpine
|
||||||
|
container_name: postgres-tinder
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- POSTGRES_DB=\${DB_NAME:-telegram_tinder_bot}
|
||||||
|
- POSTGRES_USER=\${DB_USERNAME:-postgres}
|
||||||
|
- POSTGRES_PASSWORD=\${DB_PASSWORD:-postgres}
|
||||||
|
volumes:
|
||||||
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- "5433:5432"
|
||||||
|
networks:
|
||||||
|
- bot-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U \${DB_USERNAME:-postgres} -d \${DB_NAME:-telegram_tinder_bot}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 10s
|
||||||
|
|
||||||
|
adminer:
|
||||||
|
image: adminer:latest
|
||||||
|
container_name: adminer-tinder
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
networks:
|
||||||
|
- bot-network
|
||||||
|
EOL
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Завершаем файл docker-compose.yml
|
||||||
|
cat >> docker-compose.yml << EOL
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgres_data:
|
||||||
|
|
||||||
|
networks:
|
||||||
|
bot-network:
|
||||||
|
driver: bridge
|
||||||
|
EOL
|
||||||
|
|
||||||
|
echo "✅ docker-compose.yml обновлен!"
|
||||||
|
|
||||||
|
echo "🚀 Готово! Теперь вы можете запустить контейнеры снова с помощью команды:"
|
||||||
|
echo "docker-compose up -d"
|
||||||
15
bin/fix_line_endings.sh
Executable file
15
bin/fix_line_endings.sh
Executable file
@@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# fix_line_endings.sh - Script to fix line endings in shell scripts
|
||||||
|
|
||||||
|
echo "🔧 Fixing line endings in shell scripts..."
|
||||||
|
|
||||||
|
# Fix shell scripts
|
||||||
|
for file in $(find . -name "*.sh"); do
|
||||||
|
echo "📄 Processing $file..."
|
||||||
|
tr -d '\r' < "$file" > "$file.fixed"
|
||||||
|
mv "$file.fixed" "$file"
|
||||||
|
chmod +x "$file"
|
||||||
|
echo "✅ Fixed $file"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "🚀 All shell scripts fixed!"
|
||||||
17
bin/fix_permissions.sh
Executable file
17
bin/fix_permissions.sh
Executable file
@@ -0,0 +1,17 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# fix_permissions.sh - Устанавливает права на выполнение для всех скриптов
|
||||||
|
|
||||||
|
echo "🔧 Установка прав на выполнение для всех скриптов..."
|
||||||
|
|
||||||
|
# Находим все .sh файлы и устанавливаем права на выполнение
|
||||||
|
find . -name "*.sh" -type f -exec chmod +x {} \;
|
||||||
|
|
||||||
|
echo "✅ Права на выполнение установлены!"
|
||||||
|
|
||||||
|
# Исправление переносов строк
|
||||||
|
echo "🔧 Исправление переносов строк..."
|
||||||
|
find . -name "*.sh" -type f -exec sh -c 'tr -d "\r" < "$1" > "$1.fixed" && mv "$1.fixed" "$1"' -- {} \;
|
||||||
|
|
||||||
|
echo "✅ Переносы строк исправлены!"
|
||||||
|
|
||||||
|
echo "🚀 Готово! Все скрипты готовы к использованию."
|
||||||
0
bin/install_docker.sh
Normal file → Executable file
0
bin/install_docker.sh
Normal file → Executable file
0
bin/install_ubuntu.sh
Normal file → Executable file
0
bin/install_ubuntu.sh
Normal file → Executable file
37
bin/run_full_migration.sh
Executable file
37
bin/run_full_migration.sh
Executable file
@@ -0,0 +1,37 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run_full_migration.sh - Полный процесс миграции с компиляцией TypeScript
|
||||||
|
|
||||||
|
echo "🚀 Запуск полного процесса миграции..."
|
||||||
|
|
||||||
|
# Проверка наличия файлов TS
|
||||||
|
if find migrations -name "*.ts" -quit; then
|
||||||
|
echo "📋 Обнаружены TypeScript миграции. Компилируем их..."
|
||||||
|
|
||||||
|
# Компиляция TS файлов
|
||||||
|
./bin/compile_ts_migrations.sh
|
||||||
|
|
||||||
|
# Проверка результата
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "❌ Ошибка компиляции TS миграций!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "ℹ️ TypeScript миграции не обнаружены, пропускаем компиляцию."
|
||||||
|
mkdir -p temp_migrations
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Копирование JS миграций
|
||||||
|
echo "📂 Копирование JS-миграций..."
|
||||||
|
find migrations -name "*.js" -exec cp {} temp_migrations/ \;
|
||||||
|
|
||||||
|
# Запуск миграций
|
||||||
|
echo "🔄 Применение всех миграций..."
|
||||||
|
./bin/apply_migrations.sh
|
||||||
|
|
||||||
|
# Проверка результата
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ Процесс миграции успешно завершен!"
|
||||||
|
else
|
||||||
|
echo "❌ Ошибка в процессе миграции."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
101
bin/run_sql_migrations.sh
Executable file
101
bin/run_sql_migrations.sh
Executable file
@@ -0,0 +1,101 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# run_sql_migrations.sh - Ручное применение SQL-миграций
|
||||||
|
|
||||||
|
echo "🚀 Запуск SQL-миграций..."
|
||||||
|
|
||||||
|
# Загрузка переменных окружения из .env
|
||||||
|
if [ -f .env ]; then
|
||||||
|
echo "📝 Загрузка переменных окружения из .env..."
|
||||||
|
set -o allexport
|
||||||
|
source .env
|
||||||
|
set +o allexport
|
||||||
|
else
|
||||||
|
echo "⚠️ Файл .env не найден, используем значения по умолчанию"
|
||||||
|
export DB_HOST="localhost"
|
||||||
|
export DB_PORT="5432"
|
||||||
|
export DB_NAME="telegram_tinder_bot"
|
||||||
|
export DB_USERNAME="postgres"
|
||||||
|
export DB_PASSWORD="postgres"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Вывод информации о подключении
|
||||||
|
echo "🔍 Используемые параметры подключения:"
|
||||||
|
echo "DB_HOST: $DB_HOST"
|
||||||
|
echo "DB_PORT: $DB_PORT"
|
||||||
|
echo "DB_NAME: $DB_NAME"
|
||||||
|
echo "DB_USERNAME: $DB_USERNAME"
|
||||||
|
echo "DB_PASSWORD: ********"
|
||||||
|
|
||||||
|
# Функция для применения SQL файлов из директории
|
||||||
|
apply_sql_files() {
|
||||||
|
local directory=$1
|
||||||
|
echo "🔍 Ищем SQL-файлы в директории $directory..."
|
||||||
|
|
||||||
|
if [ -d "$directory" ]; then
|
||||||
|
# Получаем список файлов в порядке времени создания
|
||||||
|
files=$(find "$directory" -name "*.sql" | sort)
|
||||||
|
|
||||||
|
if [ -z "$files" ]; then
|
||||||
|
echo "⚠️ SQL-файлы не найдены в $directory"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for sql_file in $files; do
|
||||||
|
echo "🔄 Применение миграции $sql_file..."
|
||||||
|
|
||||||
|
# Проверяем, есть ли уже запись о миграции в таблице migrations
|
||||||
|
filename=$(basename "$sql_file")
|
||||||
|
exists=$(PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USERNAME -d $DB_NAME -t -c "SELECT EXISTS(SELECT 1 FROM migrations WHERE name='$filename')" 2>/dev/null)
|
||||||
|
|
||||||
|
# Если таблицы migrations не существует, создаем её
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "📝 Таблица migrations не найдена. Создаем..."
|
||||||
|
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USERNAME -d $DB_NAME -c "
|
||||||
|
CREATE TABLE IF NOT EXISTS migrations (
|
||||||
|
id SERIAL PRIMARY KEY,
|
||||||
|
name VARCHAR(255) NOT NULL,
|
||||||
|
executed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||||
|
)
|
||||||
|
" 2>/dev/null
|
||||||
|
exists=" f"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Если миграция уже применена, пропускаем
|
||||||
|
if [[ "$exists" == *"t"* ]]; then
|
||||||
|
echo "⏭️ Миграция $filename уже применена, пропускаем"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Применяем миграцию
|
||||||
|
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USERNAME -d $DB_NAME -f "$sql_file"
|
||||||
|
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
echo "✅ Миграция $filename успешно применена"
|
||||||
|
# Записываем в таблицу migrations
|
||||||
|
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USERNAME -d $DB_NAME -c "
|
||||||
|
INSERT INTO migrations (name) VALUES ('$filename')
|
||||||
|
" 2>/dev/null
|
||||||
|
else
|
||||||
|
echo "❌ Ошибка при применении миграции $filename"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "⚠️ Директория $directory не найдена"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Применяем SQL миграции из всех возможных папок
|
||||||
|
echo "🔄 Применение SQL-миграций из src/database/migrations..."
|
||||||
|
apply_sql_files "src/database/migrations"
|
||||||
|
|
||||||
|
echo "🔄 Применение SQL-миграций из migrations/sql..."
|
||||||
|
apply_sql_files "migrations/sql"
|
||||||
|
|
||||||
|
echo "🔄 Применение SQL-миграций из migrations (если есть)..."
|
||||||
|
apply_sql_files "migrations"
|
||||||
|
|
||||||
|
echo "✅ Процесс применения SQL-миграций завершен!"
|
||||||
0
bin/setup.sh
Normal file → Executable file
0
bin/setup.sh
Normal file → Executable file
0
bin/start_bot.sh
Normal file → Executable file
0
bin/start_bot.sh
Normal file → Executable file
0
bin/update.sh
Normal file → Executable file
0
bin/update.sh
Normal file → Executable file
230
deploy.sh
Normal file → Executable file
230
deploy.sh
Normal file → Executable file
@@ -1,63 +1,217 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# deploy.sh - Скрипт для деплоя Telegram Tinder Bot
|
# deploy.sh - Улучшенный скрипт для деплоя Telegram Tinder Bot
|
||||||
|
|
||||||
echo "🚀 Деплой Telegram Tinder Bot..."
|
set -e # Выход при ошибке
|
||||||
|
|
||||||
# Проверяем наличие Docker
|
# Определение цветов для вывода
|
||||||
if ! command -v docker &> /dev/null || ! command -v docker-compose &> /dev/null; then
|
GREEN='\033[0;32m'
|
||||||
echo "❌ Docker и Docker Compose должны быть установлены!"
|
BLUE='\033[0;34m'
|
||||||
echo "Для установки на Ubuntu выполните:"
|
YELLOW='\033[0;33m'
|
||||||
echo "sudo apt update && sudo apt install -y docker.io docker-compose"
|
RED='\033[0;31m'
|
||||||
exit 1
|
NC='\033[0m' # No Color
|
||||||
fi
|
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
echo -e "${BLUE} Telegram Tinder Bot Deploy ${NC}"
|
||||||
|
echo -e "${BLUE}========================================${NC}"
|
||||||
|
|
||||||
# Определяем рабочую директорию
|
# Определяем рабочую директорию
|
||||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||||||
cd "$SCRIPT_DIR"
|
cd "$SCRIPT_DIR"
|
||||||
|
|
||||||
|
# Функция для проверки наличия команды
|
||||||
|
check_command() {
|
||||||
|
if ! command -v "$1" &> /dev/null; then
|
||||||
|
echo -e "${RED}❌ Команда $1 не найдена!${NC}"
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
echo -e "${GREEN}✓ Команда $1 найдена${NC}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Шаг 1: Проверка и установка зависимостей
|
||||||
|
echo -e "\n${BLUE}Шаг 1: Проверка и установка зависимостей...${NC}"
|
||||||
|
|
||||||
|
# Проверяем наличие Docker и Docker Compose
|
||||||
|
if ! check_command docker || ! check_command docker-compose; then
|
||||||
|
echo -e "${YELLOW}Установка Docker и Docker Compose...${NC}"
|
||||||
|
|
||||||
|
# Проверяем, запущен ли скрипт от имени root
|
||||||
|
if [ "$(id -u)" -ne 0 ]; then
|
||||||
|
echo -e "${RED}❌ Этот скрипт должен быть запущен с правами root для установки Docker.${NC}"
|
||||||
|
echo -e "Пожалуйста, запустите: ${YELLOW}sudo $0${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Устанавливаем Docker и Docker Compose
|
||||||
|
if [ -f bin/install_docker.sh ]; then
|
||||||
|
bash bin/install_docker.sh
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}Установка Docker с помощью apt...${NC}"
|
||||||
|
apt update
|
||||||
|
apt install -y docker.io docker-compose
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Проверяем наличие Git
|
||||||
|
if ! check_command git; then
|
||||||
|
echo -e "${YELLOW}Установка Git...${NC}"
|
||||||
|
apt update && apt install -y git
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Проверяем наличие Node.js (для локальных операций)
|
||||||
|
if ! check_command node || ! check_command npm; then
|
||||||
|
echo -e "${YELLOW}Установка Node.js...${NC}"
|
||||||
|
apt update
|
||||||
|
apt install -y curl
|
||||||
|
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
||||||
|
apt install -y nodejs
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Шаг 2: Получение последних изменений из репозитория
|
||||||
|
echo -e "\n${BLUE}Шаг 2: Получение последних изменений из репозитория...${NC}"
|
||||||
|
|
||||||
|
# Сохраняем локальные изменения, если они есть
|
||||||
|
git stash save "Auto-stash before deploy: $(date)" || true
|
||||||
|
|
||||||
# Получаем последние изменения
|
# Получаем последние изменения
|
||||||
echo "📥 Получение последних изменений..."
|
git fetch --all
|
||||||
git pull origin main
|
git checkout main || git checkout master
|
||||||
|
git pull origin "$(git rev-parse --abbrev-ref HEAD)"
|
||||||
|
echo -e "${GREEN}✓ Получены последние изменения${NC}"
|
||||||
|
|
||||||
|
# Шаг 3: Проверка и создание файлов конфигурации
|
||||||
|
echo -e "\n${BLUE}Шаг 3: Проверка и настройка конфигурационных файлов...${NC}"
|
||||||
|
|
||||||
# Проверяем наличие .env файла
|
# Проверяем наличие .env файла
|
||||||
if [ ! -f .env ]; then
|
if [ ! -f .env ]; then
|
||||||
echo "📝 Создание .env файла из .env.production..."
|
echo -e "${YELLOW}⚠️ Файл .env не найден!${NC}"
|
||||||
cp .env.production .env
|
|
||||||
echo "⚠️ Пожалуйста, отредактируйте файл .env и укажите свои настройки!"
|
# Пытаемся найти шаблон .env файла
|
||||||
exit 1
|
if [ -f .env.production ]; then
|
||||||
|
echo -e "${YELLOW}Создание .env файла из .env.production...${NC}"
|
||||||
|
cp .env.production .env
|
||||||
|
elif [ -f .env.example ]; then
|
||||||
|
echo -e "${YELLOW}Создание .env файла из .env.example...${NC}"
|
||||||
|
cp .env.example .env
|
||||||
|
else
|
||||||
|
echo -e "${RED}❌ Шаблон .env файла не найден! Создаем базовый .env файл...${NC}"
|
||||||
|
cat > .env << EOL
|
||||||
|
# Базовый .env файл
|
||||||
|
NODE_ENV=production
|
||||||
|
PORT=3000
|
||||||
|
DB_HOST=db
|
||||||
|
DB_PORT=5432
|
||||||
|
DB_NAME=telegram_tinder_bot
|
||||||
|
DB_USERNAME=postgres
|
||||||
|
DB_PASSWORD=postgres
|
||||||
|
TELEGRAM_BOT_TOKEN=YOUR_BOT_TOKEN
|
||||||
|
EOL
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${YELLOW}⚠️ Пожалуйста, отредактируйте файл .env и укажите свои настройки!${NC}"
|
||||||
|
echo -e "${YELLOW}⚠️ Особенно важно указать TELEGRAM_BOT_TOKEN${NC}"
|
||||||
|
read -p "Продолжить деплой? (y/n): " continue_deploy
|
||||||
|
if [[ ! $continue_deploy =~ ^[Yy]$ ]]; then
|
||||||
|
echo -e "${RED}Деплой отменен. Пожалуйста, настройте .env файл и запустите скрипт снова.${NC}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Проверяем и исправляем проблему с командой сборки в Dockerfile
|
# Проверяем наличие docker-compose.override.yml
|
||||||
echo "🔧 Проверка конфигурации Dockerfile..."
|
if [ ! -f docker-compose.override.yml ] && [ -f docker-compose.override.yml.example ]; then
|
||||||
if grep -q "RUN npm run build" Dockerfile; then
|
echo -e "${YELLOW}Создание docker-compose.override.yml из примера...${NC}"
|
||||||
echo "⚠️ Исправление команды сборки в Dockerfile для совместимости с Linux..."
|
cp docker-compose.override.yml.example docker-compose.override.yml
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Шаг 4: Исправление проблем с Docker
|
||||||
|
echo -e "\n${BLUE}Шаг 4: Проверка и исправление проблем с Docker...${NC}"
|
||||||
|
|
||||||
|
# Исправляем проблему с командой сборки в Dockerfile
|
||||||
|
if [ -f Dockerfile ] && grep -q "RUN npm run build" Dockerfile; then
|
||||||
|
echo -e "${YELLOW}⚠️ Исправление команды сборки в Dockerfile для совместимости с Linux...${NC}"
|
||||||
sed -i 's/RUN npm run build/RUN npm run build:linux/g' Dockerfile
|
sed -i 's/RUN npm run build/RUN npm run build:linux/g' Dockerfile
|
||||||
echo "✅ Dockerfile обновлен"
|
echo -e "${GREEN}✓ Dockerfile обновлен${NC}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Запускаем Docker Compose
|
# Исправление прав доступа к файлам в Unix-системах
|
||||||
echo "🐳 Сборка и запуск контейнеров Docker..."
|
if [ -f bin/fix_permissions.sh ]; then
|
||||||
docker-compose down
|
echo -e "${YELLOW}Исправление прав доступа к файлам...${NC}"
|
||||||
|
bash bin/fix_permissions.sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Шаг 5: Запуск с Docker Compose
|
||||||
|
echo -e "\n${BLUE}Шаг 5: Сборка и запуск Docker контейнеров...${NC}"
|
||||||
|
|
||||||
|
# Остановка и удаление старых контейнеров
|
||||||
|
echo -e "${YELLOW}Остановка и удаление старых контейнеров...${NC}"
|
||||||
|
docker-compose down || true
|
||||||
|
|
||||||
|
# Проверка наличия скрипта для исправления Docker
|
||||||
|
if [ -f bin/fix_docker.sh ]; then
|
||||||
|
echo -e "${YELLOW}Запуск скрипта исправления Docker...${NC}"
|
||||||
|
bash bin/fix_docker.sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Создание необходимых директорий с правильными правами доступа
|
||||||
|
echo -e "${YELLOW}Создание необходимых директорий...${NC}"
|
||||||
|
mkdir -p logs uploads
|
||||||
|
chmod -R 777 logs uploads
|
||||||
|
|
||||||
|
# Сборка и запуск контейнеров
|
||||||
|
echo -e "${YELLOW}Сборка контейнеров...${NC}"
|
||||||
docker-compose build
|
docker-compose build
|
||||||
|
|
||||||
|
echo -e "${YELLOW}Запуск контейнеров...${NC}"
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
|
|
||||||
|
# Шаг 6: Применение миграций
|
||||||
|
echo -e "\n${BLUE}Шаг 6: Применение миграций базы данных...${NC}"
|
||||||
|
|
||||||
|
# Ждем инициализации базы данных
|
||||||
|
echo -e "${YELLOW}Ожидание инициализации базы данных...${NC}"
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Выбор способа миграции
|
||||||
|
if [ -f bin/run_full_migration.sh ]; then
|
||||||
|
echo -e "${YELLOW}Запуск полной миграции базы данных...${NC}"
|
||||||
|
docker-compose exec bot bash -c "cd /app && ./bin/run_full_migration.sh" || true
|
||||||
|
elif [ -f bin/apply_migrations.sh ]; then
|
||||||
|
echo -e "${YELLOW}Применение миграций базы данных...${NC}"
|
||||||
|
docker-compose exec bot bash -c "cd /app && ./bin/apply_migrations.sh" || true
|
||||||
|
else
|
||||||
|
echo -e "${YELLOW}Миграционные скрипты не найдены, пропускаем этап миграции${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Шаг 7: Проверка работоспособности
|
||||||
|
echo -e "\n${BLUE}Шаг 7: Проверка работоспособности...${NC}"
|
||||||
|
|
||||||
# Проверяем статус контейнеров
|
# Проверяем статус контейнеров
|
||||||
echo "🔍 Проверка статуса контейнеров..."
|
echo -e "${YELLOW}Проверка статуса контейнеров...${NC}"
|
||||||
docker-compose ps
|
docker-compose ps
|
||||||
|
|
||||||
echo "✅ Деплой успешно завершен! Бот должен быть доступен через Telegram."
|
# Ждем запуска API
|
||||||
|
echo -e "${YELLOW}Ожидание запуска API...${NC}"
|
||||||
|
sleep 5
|
||||||
|
docker-compose exec bot curl -s http://localhost:3000/health || echo "⚠️ Сервис не отвечает на проверку здоровья"
|
||||||
|
|
||||||
|
# Вывод информации о деплое
|
||||||
|
echo -e "\n${GREEN}✅ Деплой успешно завершен!${NC}"
|
||||||
|
echo -e "${GREEN}✅ Бот должен быть доступен через Telegram.${NC}"
|
||||||
echo ""
|
echo ""
|
||||||
echo "📊 Полезные команды:"
|
echo -e "${BLUE}📊 Полезные команды:${NC}"
|
||||||
echo "- Просмотр логов: docker-compose logs -f"
|
echo -e "- ${YELLOW}Просмотр логов:${NC} docker-compose logs -f bot"
|
||||||
echo "- Перезапуск сервисов: docker-compose restart"
|
echo -e "- ${YELLOW}Перезапуск сервисов:${NC} docker-compose restart"
|
||||||
echo "- Остановка всех сервисов: docker-compose down"
|
echo -e "- ${YELLOW}Остановка всех сервисов:${NC} docker-compose down"
|
||||||
echo "- Доступ к базе данных: docker-compose exec db psql -U postgres -d telegram_tinder_bot"
|
echo -e "- ${YELLOW}Доступ к базе данных:${NC} docker-compose exec db psql -U postgres -d telegram_tinder_bot"
|
||||||
echo "- Проверка состояния бота: curl http://localhost:3000/health"
|
echo -e "- ${YELLOW}Проверка состояния бота:${NC} curl http://localhost:3000/health"
|
||||||
echo ""
|
echo ""
|
||||||
echo "🌟 Для администрирования базы данных:"
|
echo -e "${BLUE}🌟 Для администрирования базы данных:${NC}"
|
||||||
echo "Adminer доступен по адресу: http://ваш_сервер:8080"
|
echo -e "Adminer доступен по адресу: http://ваш_сервер:8080"
|
||||||
echo " - Система: PostgreSQL"
|
echo -e " - ${YELLOW}Система:${NC} PostgreSQL"
|
||||||
echo " - Сервер: db"
|
echo -e " - ${YELLOW}Сервер:${NC} db"
|
||||||
echo " - Пользователь: postgres"
|
echo -e " - ${YELLOW}Пользователь:${NC} postgres"
|
||||||
echo " - Пароль: (из переменной DB_PASSWORD в .env)"
|
echo -e " - ${YELLOW}Пароль:${NC} (из переменной DB_PASSWORD в .env)"
|
||||||
echo " - База данных: telegram_tinder_bot"
|
echo -e " - ${YELLOW}База данных:${NC} telegram_tinder_bot"
|
||||||
|
echo ""
|
||||||
|
echo -e "${YELLOW}⚠️ При возникновении проблем проверьте файлы в директории bin/ для дополнительных утилит исправления.${NC}"
|
||||||
|
|||||||
@@ -1,69 +0,0 @@
|
|||||||
# Используем версию Docker Compose для локальной разработки
|
|
||||||
|
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
|
||||||
bot:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
args:
|
|
||||||
- NODE_ENV=development
|
|
||||||
environment:
|
|
||||||
- NODE_ENV=development
|
|
||||||
- DB_HOST=db
|
|
||||||
- DB_PORT=5432
|
|
||||||
- DB_NAME=telegram_tinder_bot
|
|
||||||
- DB_USERNAME=postgres
|
|
||||||
- DB_PASSWORD=dev_password
|
|
||||||
volumes:
|
|
||||||
# Монтируем исходный код для горячей перезагрузки
|
|
||||||
- ./src:/app/src
|
|
||||||
- ./dist:/app/dist
|
|
||||||
- ./.env:/app/.env
|
|
||||||
ports:
|
|
||||||
# Открываем порт для отладки
|
|
||||||
- "9229:9229"
|
|
||||||
command: npm run dev
|
|
||||||
networks:
|
|
||||||
- bot-network
|
|
||||||
depends_on:
|
|
||||||
- db
|
|
||||||
|
|
||||||
db:
|
|
||||||
# Используем последнюю версию PostgreSQL для разработки
|
|
||||||
image: postgres:16-alpine
|
|
||||||
environment:
|
|
||||||
- POSTGRES_DB=telegram_tinder_bot
|
|
||||||
- POSTGRES_USER=postgres
|
|
||||||
- POSTGRES_PASSWORD=dev_password
|
|
||||||
volumes:
|
|
||||||
# Хранение данных локально для быстрого сброса
|
|
||||||
- postgres_data_dev:/var/lib/postgresql/data
|
|
||||||
# Монтируем скрипты инициализации
|
|
||||||
- ./sql:/docker-entrypoint-initdb.d
|
|
||||||
ports:
|
|
||||||
# Открываем порт для доступа к БД напрямую
|
|
||||||
- "5433:5432"
|
|
||||||
networks:
|
|
||||||
- bot-network
|
|
||||||
|
|
||||||
adminer:
|
|
||||||
image: adminer:latest
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
networks:
|
|
||||||
- bot-network
|
|
||||||
depends_on:
|
|
||||||
- db
|
|
||||||
environment:
|
|
||||||
- ADMINER_DEFAULT_SERVER=db
|
|
||||||
- ADMINER_DEFAULT_USER=postgres
|
|
||||||
- ADMINER_DEFAULT_PASSWORD=dev_password
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres_data_dev:
|
|
||||||
|
|
||||||
networks:
|
|
||||||
bot-network:
|
|
||||||
driver: bridge
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
[36mВведите параметры подключения к внешней базе данных:[0m
|
|
||||||
Хост (например, localhost): Порт (например, 5432): Имя базы данных: Имя пользователя: Пароль: [33mМодифицируем docker-compose.yml для работы с внешней базой данных...[0m
|
|
||||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 䠩<><E4A0A9><EFBFBD>: 0.
|
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
|
||||||
bot:
|
|
||||||
build: .
|
|
||||||
container_name: telegram-tinder-bot
|
|
||||||
restart: unless-stopped
|
|
||||||
env_file: .env
|
|
||||||
environment:
|
|
||||||
- NODE_ENV=production
|
|
||||||
- DB_HOST=
|
|
||||||
- DB_PORT=
|
|
||||||
- DB_NAME=
|
|
||||||
- DB_USERNAME=
|
|
||||||
- DB_PASSWORD=
|
|
||||||
volumes:
|
|
||||||
- ./uploads:/app/uploads
|
|
||||||
- ./logs:/app/logs
|
|
||||||
networks:
|
|
||||||
- bot-network
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
start_period: 10s
|
|
||||||
|
|
||||||
adminer:
|
|
||||||
image: adminer:latest
|
|
||||||
container_name: adminer-tinder
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
networks:
|
|
||||||
- bot-network
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
||||||
|
|
||||||
networks:
|
|
||||||
bot-network:
|
|
||||||
driver: bridge
|
|
||||||
80
docs/docker_fix.md
Normal file
80
docs/docker_fix.md
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# Решение проблемы с Docker-контейнерами
|
||||||
|
|
||||||
|
## Проблема
|
||||||
|
При запуске контейнеров через Docker Compose возникает ошибка `KeyError: 'ContainerConfig'`. Эта ошибка появляется из-за несовместимости между версиями Docker, Docker Compose и структурой docker-compose.yml.
|
||||||
|
|
||||||
|
## Решение
|
||||||
|
|
||||||
|
### 1. Очистка окружения Docker
|
||||||
|
|
||||||
|
На сервере выполните следующие команды, чтобы полностью очистить окружение Docker:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Остановка и удаление контейнеров
|
||||||
|
docker-compose down -v
|
||||||
|
|
||||||
|
# Принудительное удаление контейнеров по имени
|
||||||
|
docker rm -f postgres-tinder adminer-tinder telegram-tinder-bot
|
||||||
|
|
||||||
|
# Очистка неиспользуемых томов и сетей
|
||||||
|
docker system prune -f --volumes
|
||||||
|
|
||||||
|
# Очистка кеша Docker
|
||||||
|
docker builder prune -f
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Исправление проблем с переносами строк
|
||||||
|
|
||||||
|
Файлы, созданные в Windows и перенесенные в Linux, могут содержать неправильные символы переноса строки.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Исправление переносов строк в shell-скриптах
|
||||||
|
find . -name "*.sh" -type f -exec sh -c 'tr -d "\r" < "$1" > "$1.fixed" && mv "$1.fixed" "$1" && chmod +x "$1"' -- {} \;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Обновление docker-compose.yml
|
||||||
|
|
||||||
|
Создайте новый docker-compose.yml с исправленной структурой:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запустите скрипт для исправления проблем с Docker
|
||||||
|
./bin/fix_docker.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Запуск с полностью чистым окружением
|
||||||
|
|
||||||
|
После выполнения всех исправлений запустите контейнеры заново:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
## Альтернативное решение
|
||||||
|
|
||||||
|
Если проблема сохраняется, можно попробовать запустить контейнеры по отдельности:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Сначала запустить базу данных (если она нужна)
|
||||||
|
docker-compose up -d db
|
||||||
|
|
||||||
|
# Дождаться запуска базы данных
|
||||||
|
sleep 10
|
||||||
|
|
||||||
|
# Запустить бота
|
||||||
|
docker-compose up -d bot
|
||||||
|
|
||||||
|
# Запустить adminer
|
||||||
|
docker-compose up -d adminer
|
||||||
|
```
|
||||||
|
|
||||||
|
## Проверка работы миграций
|
||||||
|
|
||||||
|
После запуска контейнеров проверьте, что миграции базы данных применяются правильно:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Просмотр логов контейнера бота
|
||||||
|
docker logs telegram-tinder-bot
|
||||||
|
|
||||||
|
# Если миграции не применяются, можно запустить их вручную внутри контейнера
|
||||||
|
docker exec -it telegram-tinder-bot sh -c "DATABASE_URL=postgres://$DB_USERNAME:$DB_PASSWORD@$DB_HOST:$DB_PORT/$DB_NAME npx node-pg-migrate up"
|
||||||
|
```
|
||||||
88
docs/migrations_fix.md
Normal file
88
docs/migrations_fix.md
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
# Решение проблемы с миграциями базы данных
|
||||||
|
|
||||||
|
## Проблемы
|
||||||
|
|
||||||
|
При попытке применить миграции были обнаружены следующие проблемы:
|
||||||
|
|
||||||
|
1. **Ошибка с TypeScript файлами**: Node.js не может напрямую выполнять файлы `.ts` без компиляции их в JavaScript.
|
||||||
|
2. **Предупреждения о ES модулях**: Файлы используют синтаксис ES модулей, но не имеют расширения `.mjs` или настроек в package.json.
|
||||||
|
3. **Неверный порядок миграций**: Миграции могут выполняться в неправильном порядке.
|
||||||
|
|
||||||
|
## Решения
|
||||||
|
|
||||||
|
### Для быстрого применения миграций
|
||||||
|
|
||||||
|
Используйте один из следующих сценариев:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Полный процесс миграции с компиляцией TypeScript
|
||||||
|
./bin/run_full_migration.sh
|
||||||
|
|
||||||
|
# Только SQL-миграции (минуя node-pg-migrate)
|
||||||
|
./bin/run_sql_migrations.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пошаговое решение
|
||||||
|
|
||||||
|
1. **Компиляция TypeScript миграций в JavaScript**:
|
||||||
|
```bash
|
||||||
|
./bin/compile_ts_migrations.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Применение JS-миграций**:
|
||||||
|
```bash
|
||||||
|
./bin/apply_migrations.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Ручное применение SQL-миграций**:
|
||||||
|
```bash
|
||||||
|
./bin/run_sql_migrations.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Описание скриптов
|
||||||
|
|
||||||
|
- **run_full_migration.sh**: Полный процесс миграции, включающий компиляцию TypeScript и применение всех миграций.
|
||||||
|
- **compile_ts_migrations.sh**: Только компиляция TypeScript миграций в JavaScript.
|
||||||
|
- **apply_migrations.sh**: Применение JS-миграций через node-pg-migrate.
|
||||||
|
- **run_sql_migrations.sh**: Прямое применение SQL-миграций через psql.
|
||||||
|
|
||||||
|
## Проверка результатов
|
||||||
|
|
||||||
|
После выполнения миграций проверьте состояние базы данных:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Подключение к базе данных
|
||||||
|
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USERNAME -d $DB_NAME
|
||||||
|
|
||||||
|
# Проверка таблиц
|
||||||
|
\dt
|
||||||
|
|
||||||
|
# Проверка примененных миграций
|
||||||
|
SELECT * FROM migrations ORDER BY executed_at;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Если проблемы сохраняются
|
||||||
|
|
||||||
|
1. **Очистить директорию миграций**:
|
||||||
|
```bash
|
||||||
|
# Создание резервной копии
|
||||||
|
mkdir -p backup_migrations
|
||||||
|
cp -r migrations/* backup_migrations/
|
||||||
|
|
||||||
|
# Оставить только JS-миграции
|
||||||
|
rm -f migrations/*.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Инициализировать миграции заново**:
|
||||||
|
```bash
|
||||||
|
npx node-pg-migrate init
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Применить специальную консолидированную миграцию**:
|
||||||
|
```bash
|
||||||
|
# Создание консолидированной миграции
|
||||||
|
cat src/database/migrations/*.sql > consolidated.sql
|
||||||
|
|
||||||
|
# Применение консолидированной миграции
|
||||||
|
PGPASSWORD=$DB_PASSWORD psql -h $DB_HOST -p $DB_PORT -U $DB_USERNAME -d $DB_NAME -f consolidated.sql
|
||||||
|
```
|
||||||
@@ -27,7 +27,56 @@ sleep 5
|
|||||||
|
|
||||||
# Run database migrations
|
# Run database migrations
|
||||||
echo "🔄 Running database migrations..."
|
echo "🔄 Running database migrations..."
|
||||||
node dist/database/migrateOnStartup.js
|
|
||||||
|
# Create migrations directory structure
|
||||||
|
mkdir -p dist/database/migrations
|
||||||
|
|
||||||
|
# Copy any available migrations
|
||||||
|
if [ -d "src/database/migrations" ]; then
|
||||||
|
echo "<22> Found SQL migrations. Copying..."
|
||||||
|
cp -R src/database/migrations/* dist/database/migrations/ 2>/dev/null || echo "No SQL migrations to copy"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Copy JS migrations if available
|
||||||
|
if [ -d "migrations" ]; then
|
||||||
|
echo "📂 Found JS migrations. Copying..."
|
||||||
|
mkdir -p migrations-temp
|
||||||
|
cp migrations/*.js migrations-temp/ 2>/dev/null || echo "No JS migrations to copy"
|
||||||
|
# Move JS migrations to dist/database/migrations
|
||||||
|
cp migrations-temp/*.js dist/database/migrations/ 2>/dev/null || echo "No JS migrations to copy to dist"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Display environment variables for debugging (without passwords)
|
||||||
|
echo "🔍 Environment variables for database connection:"
|
||||||
|
echo "DB_HOST: $DB_HOST"
|
||||||
|
echo "DB_PORT: $DB_PORT"
|
||||||
|
echo "DB_NAME: $DB_NAME"
|
||||||
|
echo "DB_USERNAME: $DB_USERNAME"
|
||||||
|
|
||||||
|
# Run migrations using node-pg-migrate
|
||||||
|
echo "🔄 Running migrations with node-pg-migrate..."
|
||||||
|
DATABASE_URL="postgres://$DB_USERNAME:$DB_PASSWORD@$DB_HOST:$DB_PORT/$DB_NAME" npx node-pg-migrate up
|
||||||
|
|
||||||
|
# Verify connection to database
|
||||||
|
echo "🔍 Verifying database connection..."
|
||||||
|
node -e "
|
||||||
|
const { Pool } = require('pg');
|
||||||
|
const pool = new Pool({
|
||||||
|
host: process.env.DB_HOST,
|
||||||
|
port: process.env.DB_PORT,
|
||||||
|
database: process.env.DB_NAME,
|
||||||
|
user: process.env.DB_USERNAME,
|
||||||
|
password: process.env.DB_PASSWORD
|
||||||
|
});
|
||||||
|
pool.query('SELECT NOW()', (err, res) => {
|
||||||
|
if (err) {
|
||||||
|
console.error('❌ Database connection failed:', err.message);
|
||||||
|
process.exit(1);
|
||||||
|
} else {
|
||||||
|
console.log('✅ Database connection successful:', res.rows[0].now);
|
||||||
|
pool.end();
|
||||||
|
}
|
||||||
|
});" || echo "❌ Failed to verify database connection"
|
||||||
|
|
||||||
# Start the bot
|
# Start the bot
|
||||||
echo "✅ Starting the bot..."
|
echo "✅ Starting the bot..."
|
||||||
|
|||||||
59
src/services/userLanguageService.ts
Normal file
59
src/services/userLanguageService.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import { query } from '../database/connection';
|
||||||
|
|
||||||
|
export class UserLanguageService {
|
||||||
|
// Получить язык пользователя
|
||||||
|
async getUserLanguage(telegramId: string): Promise<string> {
|
||||||
|
try {
|
||||||
|
const result = await query(
|
||||||
|
'SELECT language FROM users WHERE telegram_id = $1',
|
||||||
|
[telegramId]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (result.rows.length > 0) {
|
||||||
|
return result.rows[0].language || 'ru';
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'ru'; // Язык по умолчанию
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error getting user language:', error);
|
||||||
|
return 'ru';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Установить язык пользователя
|
||||||
|
async setUserLanguage(telegramId: string, language: string): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
await query(
|
||||||
|
'UPDATE users SET language = $1 WHERE telegram_id = $2',
|
||||||
|
[language, telegramId]
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error setting user language:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Получить поддерживаемые языки
|
||||||
|
getSupportedLanguages(): { [key: string]: string } {
|
||||||
|
return {
|
||||||
|
'ru': '🇷🇺 Русский',
|
||||||
|
'en': '🇺🇸 English',
|
||||||
|
'es': '🇪🇸 Español',
|
||||||
|
'fr': '🇫🇷 Français',
|
||||||
|
'de': '🇩🇪 Deutsch',
|
||||||
|
'it': '🇮🇹 Italiano',
|
||||||
|
'pt': '🇵🇹 Português',
|
||||||
|
'zh': '🇨🇳 中文',
|
||||||
|
'ja': '🇯🇵 日本語',
|
||||||
|
'ko': '🇰🇷 한국어',
|
||||||
|
'uz': '🇺🇿 O\'zbekcha',
|
||||||
|
'kk': '🇰🇿 Қазақша'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверить, поддерживается ли язык
|
||||||
|
isLanguageSupported(language: string): boolean {
|
||||||
|
return Object.keys(this.getSupportedLanguages()).includes(language);
|
||||||
|
}
|
||||||
|
}
|
||||||
241
start.bat
241
start.bat
@@ -1,241 +0,0 @@
|
|||||||
@echo off
|
|
||||||
:: start.bat - Скрипт для запуска Telegram Tinder Bot на Windows
|
|
||||||
:: Позволяет выбрать между локальной БД в контейнере или внешней БД
|
|
||||||
|
|
||||||
echo ================================================
|
|
||||||
echo Запуск Telegram Tinder Bot
|
|
||||||
echo ================================================
|
|
||||||
|
|
||||||
:: Проверка наличия Docker и Docker Compose
|
|
||||||
WHERE docker >nul 2>&1
|
|
||||||
IF %ERRORLEVEL% NEQ 0 (
|
|
||||||
echo [31mОШИБКА: Docker не установлен![0m
|
|
||||||
echo Установите Docker Desktop для Windows: https://docs.docker.com/desktop/install/windows-install/
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Проверяем наличие .env файла
|
|
||||||
IF NOT EXIST .env (
|
|
||||||
echo [33mФайл .env не найден. Создаем из шаблона...[0m
|
|
||||||
IF EXIST .env.example (
|
|
||||||
copy .env.example .env
|
|
||||||
echo [32mФайл .env создан из шаблона. Пожалуйста, отредактируйте его с вашими настройками.[0m
|
|
||||||
) ELSE (
|
|
||||||
echo [31mОШИБКА: Файл .env.example не найден. Создайте файл .env вручную.[0m
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Спрашиваем про запуск базы данных
|
|
||||||
set /p use_container_db="Запустить базу данных PostgreSQL в контейнере? (y/n): "
|
|
||||||
|
|
||||||
:: Функции для работы с docker-compose
|
|
||||||
IF /I "%use_container_db%" NEQ "y" (
|
|
||||||
:: Запрашиваем параметры подключения к внешней БД
|
|
||||||
echo [36mВведите параметры подключения к внешней базе данных:[0m
|
|
||||||
set /p db_host="Хост (например, localhost): "
|
|
||||||
set /p db_port="Порт (например, 5432): "
|
|
||||||
set /p db_name="Имя базы данных: "
|
|
||||||
set /p db_user="Имя пользователя: "
|
|
||||||
set /p db_password="Пароль: "
|
|
||||||
|
|
||||||
:: Модифицируем docker-compose.yml
|
|
||||||
echo [33mМодифицируем docker-compose.yml для работы с внешней базой данных...[0m
|
|
||||||
|
|
||||||
:: Сохраняем оригинальную версию файла
|
|
||||||
copy docker-compose.yml docker-compose.yml.bak
|
|
||||||
|
|
||||||
:: Создаем временный файл с модифицированным содержимым
|
|
||||||
(
|
|
||||||
echo version: '3.8'
|
|
||||||
echo.
|
|
||||||
echo services:
|
|
||||||
echo bot:
|
|
||||||
echo build: .
|
|
||||||
echo container_name: telegram-tinder-bot
|
|
||||||
echo restart: unless-stopped
|
|
||||||
echo env_file: .env
|
|
||||||
echo environment:
|
|
||||||
echo - NODE_ENV=production
|
|
||||||
echo - DB_HOST=%db_host%
|
|
||||||
echo - DB_PORT=%db_port%
|
|
||||||
echo - DB_NAME=%db_name%
|
|
||||||
echo - DB_USERNAME=%db_user%
|
|
||||||
echo - DB_PASSWORD=%db_password%
|
|
||||||
echo volumes:
|
|
||||||
echo - ./uploads:/app/uploads
|
|
||||||
echo - ./logs:/app/logs
|
|
||||||
echo networks:
|
|
||||||
echo - bot-network
|
|
||||||
echo healthcheck:
|
|
||||||
echo test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
|
|
||||||
echo interval: 30s
|
|
||||||
echo timeout: 5s
|
|
||||||
echo retries: 3
|
|
||||||
echo start_period: 10s
|
|
||||||
echo.
|
|
||||||
echo adminer:
|
|
||||||
echo image: adminer:latest
|
|
||||||
echo container_name: adminer-tinder
|
|
||||||
echo restart: unless-stopped
|
|
||||||
echo ports:
|
|
||||||
echo - "8080:8080"
|
|
||||||
echo networks:
|
|
||||||
echo - bot-network
|
|
||||||
echo.
|
|
||||||
echo volumes:
|
|
||||||
echo postgres_data:
|
|
||||||
echo.
|
|
||||||
echo networks:
|
|
||||||
echo bot-network:
|
|
||||||
echo driver: bridge
|
|
||||||
) > docker-compose.temp.yml
|
|
||||||
|
|
||||||
:: Заменяем оригинальный файл
|
|
||||||
move /y docker-compose.temp.yml docker-compose.yml
|
|
||||||
|
|
||||||
echo [32mdocker-compose.yml обновлен для работы с внешней базой данных[0m
|
|
||||||
|
|
||||||
:: Обновляем .env файл
|
|
||||||
echo [33mОбновляем файл .env с параметрами внешней базы данных...[0m
|
|
||||||
|
|
||||||
:: Создаем временный файл
|
|
||||||
type NUL > .env.temp
|
|
||||||
|
|
||||||
:: Читаем .env построчно и заменяем нужные строки
|
|
||||||
for /f "tokens=*" %%a in (.env) do (
|
|
||||||
set line=%%a
|
|
||||||
set line=!line:DB_HOST=*!
|
|
||||||
if "!line:~0,1!" == "*" (
|
|
||||||
echo DB_HOST=%db_host%>> .env.temp
|
|
||||||
) else (
|
|
||||||
set line=!line:DB_PORT=*!
|
|
||||||
if "!line:~0,1!" == "*" (
|
|
||||||
echo DB_PORT=%db_port%>> .env.temp
|
|
||||||
) else (
|
|
||||||
set line=!line:DB_NAME=*!
|
|
||||||
if "!line:~0,1!" == "*" (
|
|
||||||
echo DB_NAME=%db_name%>> .env.temp
|
|
||||||
) else (
|
|
||||||
set line=!line:DB_USERNAME=*!
|
|
||||||
if "!line:~0,1!" == "*" (
|
|
||||||
echo DB_USERNAME=%db_user%>> .env.temp
|
|
||||||
) else (
|
|
||||||
set line=!line:DB_PASSWORD=*!
|
|
||||||
if "!line:~0,1!" == "*" (
|
|
||||||
echo DB_PASSWORD=%db_password%>> .env.temp
|
|
||||||
) else (
|
|
||||||
echo %%a>> .env.temp
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Заменяем оригинальный файл
|
|
||||||
move /y .env.temp .env
|
|
||||||
|
|
||||||
echo [32mФайл .env обновлен с параметрами внешней базы данных[0m
|
|
||||||
|
|
||||||
:: Запускаем только контейнер с ботом
|
|
||||||
echo [36mЗапускаем Telegram Bot без контейнера базы данных...[0m
|
|
||||||
docker-compose up -d bot adminer
|
|
||||||
|
|
||||||
echo [32mБот запущен и использует внешнюю базу данных: %db_host%:%db_port%/%db_name%[0m
|
|
||||||
echo [33mAdminer доступен по адресу: http://localhost:8080/[0m
|
|
||||||
echo [33mДанные для входа в Adminer:[0m
|
|
||||||
echo [33mСистема: PostgreSQL[0m
|
|
||||||
echo [33mСервер: %db_host%[0m
|
|
||||||
echo [33mПользователь: %db_user%[0m
|
|
||||||
echo [33mПароль: (введенный вами)[0m
|
|
||||||
echo [33mБаза данных: %db_name%[0m
|
|
||||||
) ELSE (
|
|
||||||
:: Восстанавливаем оригинальный docker-compose.yml если есть бэкап
|
|
||||||
if exist docker-compose.yml.bak (
|
|
||||||
move /y docker-compose.yml.bak docker-compose.yml
|
|
||||||
echo [32mdocker-compose.yml восстановлен из резервной копии[0m
|
|
||||||
)
|
|
||||||
|
|
||||||
echo [36mЗапускаем Telegram Bot с контейнером базы данных...[0m
|
|
||||||
|
|
||||||
:: Проверка, запущены ли контейнеры
|
|
||||||
docker ps -q -f name=telegram-tinder-bot > tmp_containers.txt
|
|
||||||
set /p containers=<tmp_containers.txt
|
|
||||||
del tmp_containers.txt
|
|
||||||
|
|
||||||
if not "%containers%" == "" (
|
|
||||||
set /p restart_containers="Контейнеры уже запущены. Перезапустить? (y/n): "
|
|
||||||
if /I "%restart_containers%" == "y" (
|
|
||||||
docker-compose down
|
|
||||||
docker-compose up -d
|
|
||||||
echo [32mКонтейнеры перезапущены[0m
|
|
||||||
) else (
|
|
||||||
echo [36mПродолжаем работу с уже запущенными контейнерами[0m
|
|
||||||
)
|
|
||||||
) else (
|
|
||||||
docker-compose up -d
|
|
||||||
echo [32mКонтейнеры запущены[0m
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Проверка наличия пароля для БД в .env
|
|
||||||
findstr /C:"DB_PASSWORD=" .env > tmp_db_password.txt
|
|
||||||
set /p db_password_line=<tmp_db_password.txt
|
|
||||||
del tmp_db_password.txt
|
|
||||||
|
|
||||||
:: Проверяем, есть ли значение после DB_PASSWORD=
|
|
||||||
for /f "tokens=2 delims==" %%i in ("%db_password_line%") do (
|
|
||||||
set db_password=%%i
|
|
||||||
)
|
|
||||||
|
|
||||||
if "%db_password%" == "" (
|
|
||||||
:: Генерируем случайный пароль
|
|
||||||
set chars=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
|
|
||||||
set random_password=
|
|
||||||
for /L %%i in (1,1,16) do (
|
|
||||||
set /a random_index=!random! %% 62
|
|
||||||
for %%j in (!random_index!) do set random_password=!random_password!!chars:~%%j,1!
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Обновляем .env файл с новым паролем
|
|
||||||
:: Создаем временный файл
|
|
||||||
type NUL > .env.temp
|
|
||||||
|
|
||||||
:: Читаем .env построчно и заменяем строку с паролем
|
|
||||||
for /f "tokens=*" %%a in (.env) do (
|
|
||||||
set line=%%a
|
|
||||||
set line=!line:DB_PASSWORD=*!
|
|
||||||
if "!line:~0,1!" == "*" (
|
|
||||||
echo DB_PASSWORD=%random_password%>> .env.temp
|
|
||||||
) else (
|
|
||||||
echo %%a>> .env.temp
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Заменяем оригинальный файл
|
|
||||||
move /y .env.temp .env
|
|
||||||
|
|
||||||
echo [33mСгенерирован случайный пароль для базы данных и сохранен в .env[0m
|
|
||||||
)
|
|
||||||
|
|
||||||
echo [32mTelegram Bot запущен с локальной базой данных[0m
|
|
||||||
echo [33mAdminer доступен по адресу: http://localhost:8080/[0m
|
|
||||||
echo [33mДанные для входа в Adminer:[0m
|
|
||||||
echo [33mСистема: PostgreSQL[0m
|
|
||||||
echo [33mСервер: db[0m
|
|
||||||
echo [33mПользователь: postgres[0m
|
|
||||||
echo [33mПароль: (из переменной DB_PASSWORD в .env)[0m
|
|
||||||
echo [33mБаза данных: telegram_tinder_bot[0m
|
|
||||||
)
|
|
||||||
|
|
||||||
:: Проверка статуса контейнеров
|
|
||||||
echo [36mПроверка статуса контейнеров:[0m
|
|
||||||
docker-compose ps
|
|
||||||
|
|
||||||
echo ================================================
|
|
||||||
echo [32mПроцесс запуска Telegram Tinder Bot завершен![0m
|
|
||||||
echo ================================================
|
|
||||||
echo [33mДля просмотра логов используйте: docker-compose logs -f bot[0m
|
|
||||||
echo [33mДля остановки: docker-compose down[0m
|
|
||||||
|
|
||||||
pause
|
|
||||||
229
start.ps1
229
start.ps1
@@ -1,229 +0,0 @@
|
|||||||
function createModifiedDockerCompose {
|
|
||||||
param (
|
|
||||||
[string]$dbHost,
|
|
||||||
[string]$dbPort,
|
|
||||||
[string]$dbName,
|
|
||||||
[string]$dbUser,
|
|
||||||
[string]$dbPassword
|
|
||||||
)
|
|
||||||
|
|
||||||
$dockerComposeContent = @"
|
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
|
||||||
bot:
|
|
||||||
build: .
|
|
||||||
container_name: telegram-tinder-bot
|
|
||||||
restart: unless-stopped
|
|
||||||
env_file: .env
|
|
||||||
environment:
|
|
||||||
- NODE_ENV=production
|
|
||||||
- DB_HOST=$dbHost
|
|
||||||
- DB_PORT=$dbPort
|
|
||||||
- DB_NAME=$dbName
|
|
||||||
- DB_USERNAME=$dbUser
|
|
||||||
- DB_PASSWORD=$dbPassword
|
|
||||||
volumes:
|
|
||||||
- ./uploads:/app/uploads
|
|
||||||
- ./logs:/app/logs
|
|
||||||
networks:
|
|
||||||
- bot-network
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
start_period: 10s
|
|
||||||
|
|
||||||
adminer:
|
|
||||||
image: adminer:latest
|
|
||||||
container_name: adminer-tinder
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
networks:
|
|
||||||
- bot-network
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
||||||
|
|
||||||
networks:
|
|
||||||
bot-network:
|
|
||||||
driver: bridge
|
|
||||||
"@
|
|
||||||
|
|
||||||
return $dockerComposeContent
|
|
||||||
}
|
|
||||||
|
|
||||||
function restoreDockerCompose {
|
|
||||||
if (Test-Path -Path "docker-compose.yml.bak") {
|
|
||||||
Copy-Item -Path "docker-compose.yml.bak" -Destination "docker-compose.yml" -Force
|
|
||||||
Write-Host "docker-compose.yml восстановлен из резервной копии" -ForegroundColor Green
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateEnvFile {
|
|
||||||
param (
|
|
||||||
[string]$dbHost,
|
|
||||||
[string]$dbPort,
|
|
||||||
[string]$dbName,
|
|
||||||
[string]$dbUser,
|
|
||||||
[string]$dbPassword
|
|
||||||
)
|
|
||||||
|
|
||||||
$envContent = Get-Content -Path ".env" -Raw
|
|
||||||
|
|
||||||
$envContent = $envContent -replace "DB_HOST=.*", "DB_HOST=$dbHost"
|
|
||||||
$envContent = $envContent -replace "DB_PORT=.*", "DB_PORT=$dbPort"
|
|
||||||
$envContent = $envContent -replace "DB_NAME=.*", "DB_NAME=$dbName"
|
|
||||||
$envContent = $envContent -replace "DB_USERNAME=.*", "DB_USERNAME=$dbUser"
|
|
||||||
$envContent = $envContent -replace "DB_PASSWORD=.*", "DB_PASSWORD=$dbPassword"
|
|
||||||
|
|
||||||
Set-Content -Path ".env" -Value $envContent
|
|
||||||
|
|
||||||
Write-Host "Файл .env обновлен с параметрами внешней базы данных" -ForegroundColor Green
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateRandomPassword {
|
|
||||||
$length = 16
|
|
||||||
$chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
|
||||||
$bytes = New-Object Byte[] $length
|
|
||||||
$rng = [System.Security.Cryptography.RNGCryptoServiceProvider]::new()
|
|
||||||
$rng.GetBytes($bytes)
|
|
||||||
|
|
||||||
$password = ""
|
|
||||||
for ($i = 0; $i -lt $length; $i++) {
|
|
||||||
$password += $chars[$bytes[$i] % $chars.Length]
|
|
||||||
}
|
|
||||||
|
|
||||||
return $password
|
|
||||||
}
|
|
||||||
|
|
||||||
# Начало основного скрипта
|
|
||||||
Write-Host "==================================================" -ForegroundColor Cyan
|
|
||||||
Write-Host " Запуск Telegram Tinder Bot" -ForegroundColor Cyan
|
|
||||||
Write-Host "==================================================" -ForegroundColor Cyan
|
|
||||||
|
|
||||||
# Проверка наличия Docker
|
|
||||||
try {
|
|
||||||
docker --version | Out-Null
|
|
||||||
} catch {
|
|
||||||
Write-Host "ОШИБКА: Docker не установлен!" -ForegroundColor Red
|
|
||||||
Write-Host "Установите Docker Desktop для Windows: https://docs.docker.com/desktop/install/windows-install/"
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
|
|
||||||
# Проверяем наличие .env файла
|
|
||||||
if (-not (Test-Path -Path ".env")) {
|
|
||||||
Write-Host "Файл .env не найден. Создаем из шаблона..." -ForegroundColor Yellow
|
|
||||||
|
|
||||||
if (Test-Path -Path ".env.example") {
|
|
||||||
Copy-Item -Path ".env.example" -Destination ".env"
|
|
||||||
Write-Host "Файл .env создан из шаблона. Пожалуйста, отредактируйте его с вашими настройками." -ForegroundColor Green
|
|
||||||
} else {
|
|
||||||
Write-Host "ОШИБКА: Файл .env.example не найден. Создайте файл .env вручную." -ForegroundColor Red
|
|
||||||
exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Спрашиваем про запуск базы данных
|
|
||||||
$useContainerDb = Read-Host "Запустить базу данных PostgreSQL в контейнере? (y/n)"
|
|
||||||
|
|
||||||
if ($useContainerDb -ne "y") {
|
|
||||||
# Запрашиваем параметры подключения к внешней БД
|
|
||||||
Write-Host "Введите параметры подключения к внешней базе данных:" -ForegroundColor Cyan
|
|
||||||
$dbHost = Read-Host "Хост (например, localhost)"
|
|
||||||
$dbPort = Read-Host "Порт (например, 5432)"
|
|
||||||
$dbName = Read-Host "Имя базы данных"
|
|
||||||
$dbUser = Read-Host "Имя пользователя"
|
|
||||||
$dbPassword = Read-Host "Пароль" -AsSecureString
|
|
||||||
$dbPasswordText = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($dbPassword))
|
|
||||||
|
|
||||||
# Модифицируем docker-compose.yml
|
|
||||||
Write-Host "Модифицируем docker-compose.yml для работы с внешней базой данных..." -ForegroundColor Yellow
|
|
||||||
|
|
||||||
# Сохраняем оригинальную версию файла
|
|
||||||
Copy-Item -Path "docker-compose.yml" -Destination "docker-compose.yml.bak" -Force
|
|
||||||
|
|
||||||
# Создаем модифицированный docker-compose.yml
|
|
||||||
$dockerComposeContent = createModifiedDockerCompose -dbHost $dbHost -dbPort $dbPort -dbName $dbName -dbUser $dbUser -dbPassword $dbPasswordText
|
|
||||||
Set-Content -Path "docker-compose.yml" -Value $dockerComposeContent
|
|
||||||
|
|
||||||
Write-Host "docker-compose.yml обновлен для работы с внешней базой данных" -ForegroundColor Green
|
|
||||||
|
|
||||||
# Обновляем .env файл
|
|
||||||
Write-Host "Обновляем файл .env с параметрами внешней базы данных..." -ForegroundColor Yellow
|
|
||||||
updateEnvFile -dbHost $dbHost -dbPort $dbPort -dbName $dbName -dbUser $dbUser -dbPassword $dbPasswordText
|
|
||||||
|
|
||||||
# Запускаем только контейнер с ботом
|
|
||||||
Write-Host "Запускаем Telegram Bot без контейнера базы данных..." -ForegroundColor Cyan
|
|
||||||
docker-compose up -d bot adminer
|
|
||||||
|
|
||||||
Write-Host "Бот запущен и использует внешнюю базу данных: $dbHost`:$dbPort/$dbName" -ForegroundColor Green
|
|
||||||
Write-Host "Adminer доступен по адресу: http://localhost:8080/" -ForegroundColor Yellow
|
|
||||||
Write-Host "Данные для входа в Adminer:" -ForegroundColor Yellow
|
|
||||||
Write-Host "Система: PostgreSQL" -ForegroundColor Yellow
|
|
||||||
Write-Host "Сервер: $dbHost" -ForegroundColor Yellow
|
|
||||||
Write-Host "Пользователь: $dbUser" -ForegroundColor Yellow
|
|
||||||
Write-Host "Пароль: (введенный вами)" -ForegroundColor Yellow
|
|
||||||
Write-Host "База данных: $dbName" -ForegroundColor Yellow
|
|
||||||
} else {
|
|
||||||
# Восстанавливаем оригинальный docker-compose.yml если есть бэкап
|
|
||||||
restoreDockerCompose
|
|
||||||
|
|
||||||
Write-Host "Запускаем Telegram Bot с контейнером базы данных..." -ForegroundColor Cyan
|
|
||||||
|
|
||||||
# Проверка, запущены ли контейнеры
|
|
||||||
$containers = docker ps -q -f name=telegram-tinder-bot -f name=postgres-tinder
|
|
||||||
|
|
||||||
if ($containers) {
|
|
||||||
$restartContainers = Read-Host "Контейнеры уже запущены. Перезапустить? (y/n)"
|
|
||||||
if ($restartContainers -eq "y") {
|
|
||||||
docker-compose down
|
|
||||||
docker-compose up -d
|
|
||||||
Write-Host "Контейнеры перезапущены" -ForegroundColor Green
|
|
||||||
} else {
|
|
||||||
Write-Host "Продолжаем работу с уже запущенными контейнерами" -ForegroundColor Cyan
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
docker-compose up -d
|
|
||||||
Write-Host "Контейнеры запущены" -ForegroundColor Green
|
|
||||||
}
|
|
||||||
|
|
||||||
# Проверка наличия пароля для БД в .env
|
|
||||||
$envContent = Get-Content -Path ".env" -Raw
|
|
||||||
$match = [Regex]::Match($envContent, "DB_PASSWORD=(.*)(\r?\n|$)")
|
|
||||||
$dbPassword = if ($match.Success) { $match.Groups[1].Value.Trim() } else { "" }
|
|
||||||
|
|
||||||
if ([string]::IsNullOrWhiteSpace($dbPassword)) {
|
|
||||||
# Генерируем случайный пароль
|
|
||||||
$randomPassword = generateRandomPassword
|
|
||||||
|
|
||||||
# Обновляем .env файл
|
|
||||||
$envContent = $envContent -replace "DB_PASSWORD=.*", "DB_PASSWORD=$randomPassword"
|
|
||||||
Set-Content -Path ".env" -Value $envContent
|
|
||||||
|
|
||||||
Write-Host "Сгенерирован случайный пароль для базы данных и сохранен в .env" -ForegroundColor Yellow
|
|
||||||
}
|
|
||||||
|
|
||||||
Write-Host "Telegram Bot запущен с локальной базой данных" -ForegroundColor Green
|
|
||||||
Write-Host "Adminer доступен по адресу: http://localhost:8080/" -ForegroundColor Yellow
|
|
||||||
Write-Host "Данные для входа в Adminer:" -ForegroundColor Yellow
|
|
||||||
Write-Host "Система: PostgreSQL" -ForegroundColor Yellow
|
|
||||||
Write-Host "Сервер: db" -ForegroundColor Yellow
|
|
||||||
Write-Host "Пользователь: postgres" -ForegroundColor Yellow
|
|
||||||
Write-Host "Пароль: (из переменной DB_PASSWORD в .env)" -ForegroundColor Yellow
|
|
||||||
Write-Host "База данных: telegram_tinder_bot" -ForegroundColor Yellow
|
|
||||||
}
|
|
||||||
|
|
||||||
# Проверка статуса контейнеров
|
|
||||||
Write-Host "Проверка статуса контейнеров:" -ForegroundColor Cyan
|
|
||||||
docker-compose ps
|
|
||||||
|
|
||||||
Write-Host "==================================================" -ForegroundColor Cyan
|
|
||||||
Write-Host "Процесс запуска Telegram Tinder Bot завершен!" -ForegroundColor Green
|
|
||||||
Write-Host "==================================================" -ForegroundColor Cyan
|
|
||||||
Write-Host "Для просмотра логов используйте: docker-compose logs -f bot" -ForegroundColor Yellow
|
|
||||||
Write-Host "Для остановки: docker-compose down" -ForegroundColor Yellow
|
|
||||||
|
|
||||||
Read-Host "Нажмите Enter для выхода"
|
|
||||||
225
start.sh
225
start.sh
@@ -1,225 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# start.sh - Скрипт для запуска Telegram Tinder Bot
|
|
||||||
# Позволяет выбрать между локальной БД в контейнере или внешней БД
|
|
||||||
|
|
||||||
# Цвета для вывода
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
YELLOW='\033[0;33m'
|
|
||||||
RED='\033[0;31m'
|
|
||||||
NC='\033[0m' # No Color
|
|
||||||
|
|
||||||
echo -e "${BLUE}==================================================${NC}"
|
|
||||||
echo -e "${BLUE} Запуск Telegram Tinder Bot ${NC}"
|
|
||||||
echo -e "${BLUE}==================================================${NC}"
|
|
||||||
|
|
||||||
# Проверка наличия Docker и Docker Compose
|
|
||||||
if ! command -v docker &> /dev/null || ! command -v docker-compose &> /dev/null; then
|
|
||||||
echo -e "${RED}ОШИБКА: Docker и/или Docker Compose не установлены!${NC}"
|
|
||||||
echo -e "Для установки Docker следуйте инструкции на: https://docs.docker.com/get-docker/"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Проверяем наличие .env файла
|
|
||||||
if [ ! -f .env ]; then
|
|
||||||
echo -e "${YELLOW}Файл .env не найден. Создаем из шаблона...${NC}"
|
|
||||||
if [ -f .env.example ]; then
|
|
||||||
cp .env.example .env
|
|
||||||
echo -e "${GREEN}Файл .env создан из шаблона. Пожалуйста, отредактируйте его с вашими настройками.${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${RED}ОШИБКА: Файл .env.example не найден. Создайте файл .env вручную.${NC}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Проверяем и исправляем проблему с командой сборки в Dockerfile
|
|
||||||
echo -e "${YELLOW}Проверка конфигурации Dockerfile...${NC}"
|
|
||||||
if grep -q "RUN npm run build" Dockerfile && ! grep -q "RUN npm run build:linux" Dockerfile; then
|
|
||||||
echo -e "${YELLOW}⚠️ Исправление команды сборки в Dockerfile для совместимости с Linux...${NC}"
|
|
||||||
sed -i "s/RUN npm run build/RUN npm run build:linux/g" Dockerfile
|
|
||||||
echo -e "${GREEN}✅ Dockerfile обновлен для использования команды сборки совместимой с Linux${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Спрашиваем про запуск базы данных
|
|
||||||
read -p "Запустить базу данных PostgreSQL в контейнере? (y/n): " use_container_db
|
|
||||||
|
|
||||||
# Функция для изменения docker-compose.yml
|
|
||||||
modify_docker_compose() {
|
|
||||||
local host=$1
|
|
||||||
local port=$2
|
|
||||||
local user=$3
|
|
||||||
local password=$4
|
|
||||||
local db_name=$5
|
|
||||||
|
|
||||||
echo -e "${YELLOW}Модифицируем docker-compose.yml для работы с внешней базой данных...${NC}"
|
|
||||||
|
|
||||||
# Сохраняем оригинальную версию файла
|
|
||||||
cp docker-compose.yml docker-compose.yml.bak
|
|
||||||
|
|
||||||
# Создаем временный файл с модифицированным содержимым
|
|
||||||
cat > docker-compose.temp.yml << EOL
|
|
||||||
version: '3.8'
|
|
||||||
|
|
||||||
services:
|
|
||||||
bot:
|
|
||||||
build: .
|
|
||||||
container_name: telegram-tinder-bot
|
|
||||||
restart: unless-stopped
|
|
||||||
env_file: .env
|
|
||||||
environment:
|
|
||||||
- NODE_ENV=production
|
|
||||||
- DB_HOST=${host}
|
|
||||||
- DB_PORT=${port}
|
|
||||||
- DB_NAME=${db_name}
|
|
||||||
- DB_USERNAME=${user}
|
|
||||||
- DB_PASSWORD=${password}
|
|
||||||
volumes:
|
|
||||||
- ./uploads:/app/uploads
|
|
||||||
- ./logs:/app/logs
|
|
||||||
networks:
|
|
||||||
- bot-network
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 3
|
|
||||||
start_period: 10s
|
|
||||||
|
|
||||||
adminer:
|
|
||||||
image: adminer:latest
|
|
||||||
container_name: adminer-tinder
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "8080:8080"
|
|
||||||
networks:
|
|
||||||
- bot-network
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
||||||
|
|
||||||
networks:
|
|
||||||
bot-network:
|
|
||||||
driver: bridge
|
|
||||||
EOL
|
|
||||||
|
|
||||||
# Заменяем оригинальный файл
|
|
||||||
mv docker-compose.temp.yml docker-compose.yml
|
|
||||||
|
|
||||||
echo -e "${GREEN}docker-compose.yml обновлен для работы с внешней базой данных${NC}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Функция для восстановления docker-compose.yml
|
|
||||||
restore_docker_compose() {
|
|
||||||
if [ -f docker-compose.yml.bak ]; then
|
|
||||||
mv docker-compose.yml.bak docker-compose.yml
|
|
||||||
echo -e "${GREEN}docker-compose.yml восстановлен из резервной копии${NC}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Обработка выбора
|
|
||||||
if [[ "$use_container_db" =~ ^[Nn]$ ]]; then
|
|
||||||
# Запрашиваем параметры подключения к внешней БД
|
|
||||||
echo -e "${BLUE}Введите параметры подключения к внешней базе данных:${NC}"
|
|
||||||
read -p "Хост (например, localhost): " db_host
|
|
||||||
read -p "Порт (например, 5432): " db_port
|
|
||||||
read -p "Имя базы данных: " db_name
|
|
||||||
read -p "Имя пользователя: " db_user
|
|
||||||
read -p "Пароль: " db_password
|
|
||||||
|
|
||||||
# Модифицируем docker-compose.yml
|
|
||||||
modify_docker_compose "$db_host" "$db_port" "$db_user" "$db_password" "$db_name"
|
|
||||||
|
|
||||||
# Обновляем .env файл
|
|
||||||
echo -e "${YELLOW}Обновляем файл .env с параметрами внешней базы данных...${NC}"
|
|
||||||
|
|
||||||
# Используем sed для замены переменных в .env
|
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
||||||
# macOS требует другой синтаксис для sed
|
|
||||||
sed -i '' "s/DB_HOST=.*/DB_HOST=${db_host}/" .env
|
|
||||||
sed -i '' "s/DB_PORT=.*/DB_PORT=${db_port}/" .env
|
|
||||||
sed -i '' "s/DB_NAME=.*/DB_NAME=${db_name}/" .env
|
|
||||||
sed -i '' "s/DB_USERNAME=.*/DB_USERNAME=${db_user}/" .env
|
|
||||||
sed -i '' "s/DB_PASSWORD=.*/DB_PASSWORD=${db_password}/" .env
|
|
||||||
else
|
|
||||||
# Linux и другие системы
|
|
||||||
sed -i "s/DB_HOST=.*/DB_HOST=${db_host}/" .env
|
|
||||||
sed -i "s/DB_PORT=.*/DB_PORT=${db_port}/" .env
|
|
||||||
sed -i "s/DB_NAME=.*/DB_NAME=${db_name}/" .env
|
|
||||||
sed -i "s/DB_USERNAME=.*/DB_USERNAME=${db_user}/" .env
|
|
||||||
sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=${db_password}/" .env
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "${GREEN}Файл .env обновлен с параметрами внешней базы данных${NC}"
|
|
||||||
|
|
||||||
# Запускаем только контейнер с ботом
|
|
||||||
echo -e "${BLUE}Запускаем Telegram Bot без контейнера базы данных...${NC}"
|
|
||||||
docker-compose up -d bot adminer
|
|
||||||
|
|
||||||
echo -e "${GREEN}Бот запущен и использует внешнюю базу данных: ${db_host}:${db_port}/${db_name}${NC}"
|
|
||||||
echo -e "${YELLOW}Adminer доступен по адресу: http://localhost:8080/${NC}"
|
|
||||||
echo -e "${YELLOW}Данные для входа в Adminer:${NC}"
|
|
||||||
echo -e "${YELLOW}Система: PostgreSQL${NC}"
|
|
||||||
echo -e "${YELLOW}Сервер: ${db_host}${NC}"
|
|
||||||
echo -e "${YELLOW}Пользователь: ${db_user}${NC}"
|
|
||||||
echo -e "${YELLOW}Пароль: (введенный вами)${NC}"
|
|
||||||
echo -e "${YELLOW}База данных: ${db_name}${NC}"
|
|
||||||
else
|
|
||||||
# Восстанавливаем оригинальный docker-compose.yml если есть бэкап
|
|
||||||
restore_docker_compose
|
|
||||||
|
|
||||||
echo -e "${BLUE}Запускаем Telegram Bot с контейнером базы данных...${NC}"
|
|
||||||
|
|
||||||
# Проверка, запущены ли контейнеры
|
|
||||||
containers=$(docker ps -q -f name=telegram-tinder-bot -f name=postgres-tinder)
|
|
||||||
if [ -n "$containers" ]; then
|
|
||||||
echo -e "${YELLOW}Контейнеры уже запущены. Перезапустить? (y/n): ${NC}"
|
|
||||||
read restart_containers
|
|
||||||
if [[ "$restart_containers" =~ ^[Yy]$ ]]; then
|
|
||||||
docker-compose down
|
|
||||||
docker-compose up -d
|
|
||||||
echo -e "${GREEN}Контейнеры перезапущены${NC}"
|
|
||||||
else
|
|
||||||
echo -e "${BLUE}Продолжаем работу с уже запущенными контейнерами${NC}"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
docker-compose up -d
|
|
||||||
echo -e "${GREEN}Контейнеры запущены${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Проверка наличия пароля для БД в .env
|
|
||||||
db_password=$(grep DB_PASSWORD .env | cut -d '=' -f2)
|
|
||||||
if [ -z "$db_password" ]; then
|
|
||||||
# Генерируем случайный пароль
|
|
||||||
random_password=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 16)
|
|
||||||
|
|
||||||
# Обновляем .env файл
|
|
||||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
|
||||||
# macOS требует другой синтаксис для sed
|
|
||||||
sed -i '' "s/DB_PASSWORD=.*/DB_PASSWORD=${random_password}/" .env
|
|
||||||
else
|
|
||||||
# Linux и другие системы
|
|
||||||
sed -i "s/DB_PASSWORD=.*/DB_PASSWORD=${random_password}/" .env
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "${YELLOW}Сгенерирован случайный пароль для базы данных и сохранен в .env${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "${GREEN}Telegram Bot запущен с локальной базой данных${NC}"
|
|
||||||
echo -e "${YELLOW}Adminer доступен по адресу: http://localhost:8080/${NC}"
|
|
||||||
echo -e "${YELLOW}Данные для входа в Adminer:${NC}"
|
|
||||||
echo -e "${YELLOW}Система: PostgreSQL${NC}"
|
|
||||||
echo -e "${YELLOW}Сервер: db${NC}"
|
|
||||||
echo -e "${YELLOW}Пользователь: postgres${NC}"
|
|
||||||
echo -e "${YELLOW}Пароль: (из переменной DB_PASSWORD в .env)${NC}"
|
|
||||||
echo -e "${YELLOW}База данных: telegram_tinder_bot${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Проверка статуса контейнеров
|
|
||||||
echo -e "${BLUE}Проверка статуса контейнеров:${NC}"
|
|
||||||
docker-compose ps
|
|
||||||
|
|
||||||
echo -e "${BLUE}==================================================${NC}"
|
|
||||||
echo -e "${GREEN}Процесс запуска Telegram Tinder Bot завершен!${NC}"
|
|
||||||
echo -e "${BLUE}==================================================${NC}"
|
|
||||||
echo -e "${YELLOW}Для просмотра логов используйте: docker-compose logs -f bot${NC}"
|
|
||||||
echo -e "${YELLOW}Для остановки: docker-compose down${NC}"
|
|
||||||
Reference in New Issue
Block a user