Files
news_all_spo/init_db.sh
2026-05-15 03:31:28 +05:00

186 lines
8.2 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
set -euo pipefail
# ─── Загрузка переменных из .env ─────────────────────────────────────────────
if [ -f .env ]; then
export $(grep -v '^#' .env | grep -v '^$' | xargs)
fi
POSTGRES_ROOT_PASSWORD=${POSTGRES_ROOT_PASSWORD:-PgRootNews2026Rz}
NEWS_DB_PASSWORD=${NEWS_DB_PASSWORD:-NewsAdmPass2026Xk}
DB_USER="news_admin"
DB_NAME="news"
DB_CONTAINER="news_flet-db-1" # имя контейнера по умолчанию (docker compose project name)
# ─── Цвета вывода ────────────────────────────────────────────────────────────
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
info() { echo -e "${GREEN}[INFO]${NC} $*"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
error() { echo -e "${RED}[ERROR]${NC} $*"; exit 1; }
# ─── Поиск контейнера postgres ────────────────────────────────────────────────
find_container() {
# Пробуем стандартные варианты имён контейнера
for name in "news_flet-db-1" "news_flet_db_1" "db"; do
if docker inspect "$name" &>/dev/null 2>&1; then
echo "$name"
return
fi
done
# Ищем по образу
local found
found=$(docker ps --filter "ancestor=postgres" --format "{{.Names}}" | head -1)
if [ -n "$found" ]; then
echo "$found"
return
fi
error "Контейнер PostgreSQL не найден. Запусти: docker compose -f docker-compose_db.yml up -d"
}
psql_cmd() {
docker exec -i "$DB_CONTAINER" psql -U postgres "$@"
}
# ─── Ожидание готовности PostgreSQL ──────────────────────────────────────────
wait_for_postgres() {
info "Ожидание готовности PostgreSQL..."
local retries=30
until docker exec "$DB_CONTAINER" pg_isready -U postgres -q 2>/dev/null; do
retries=$((retries - 1))
if [ $retries -le 0 ]; then
error "PostgreSQL не стал доступен за 60 секунд."
fi
echo -n "."
sleep 2
done
echo ""
info "PostgreSQL готов."
}
# ─── Создание пользователя ────────────────────────────────────────────────────
create_user() {
info "Проверка пользователя '$DB_USER'..."
local exists
exists=$(psql_cmd -tAc "SELECT 1 FROM pg_roles WHERE rolname='$DB_USER';" 2>/dev/null || echo "")
if [ "$exists" = "1" ]; then
warn "Пользователь '$DB_USER' уже существует — обновляю пароль."
psql_cmd -c "ALTER USER $DB_USER WITH PASSWORD '$NEWS_DB_PASSWORD';" > /dev/null
else
psql_cmd -c "CREATE USER $DB_USER WITH PASSWORD '$NEWS_DB_PASSWORD';" > /dev/null
info "Пользователь '$DB_USER' создан."
fi
}
# ─── Создание базы данных ─────────────────────────────────────────────────────
create_database() {
info "Проверка базы данных '$DB_NAME'..."
local exists
exists=$(psql_cmd -tAc "SELECT 1 FROM pg_database WHERE datname='$DB_NAME';" 2>/dev/null || echo "")
if [ "$exists" = "1" ]; then
warn "База данных '$DB_NAME' уже существует — пропускаю создание."
else
psql_cmd -c "CREATE DATABASE $DB_NAME OWNER $DB_USER ENCODING 'UTF8' LC_COLLATE 'en_US.UTF-8' LC_CTYPE 'en_US.UTF-8' TEMPLATE template0;" > /dev/null
info "База данных '$DB_NAME' создана."
fi
}
# ─── Настройка прав ───────────────────────────────────────────────────────────
grant_privileges() {
info "Настройка привилегий..."
psql_cmd -d "$DB_NAME" << 'SQL' > /dev/null
GRANT ALL PRIVILEGES ON DATABASE news TO news_admin;
GRANT ALL ON SCHEMA public TO news_admin;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO news_admin;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO news_admin;
SQL
info "Привилегии настроены."
}
# ─── Проверка подключения ─────────────────────────────────────────────────────
verify_connection() {
info "Проверка подключения от '$DB_USER' к '$DB_NAME'..."
if docker exec "$DB_CONTAINER" psql -U "$DB_USER" -d "$DB_NAME" -c "SELECT 1;" > /dev/null 2>&1; then
info "Подключение успешно."
else
error "Не удалось подключиться от '$DB_USER' к '$DB_NAME'."
fi
}
# ─── Ожидание Redis ───────────────────────────────────────────────────────────
wait_for_redis() {
info "Ожидание готовности Redis..."
local redis_container
redis_container=$(docker ps --filter "ancestor=redis" --format "{{.Names}}" | head -1)
if [ -z "$redis_container" ]; then
warn "Контейнер Redis не найден — пропускаю проверку."
return
fi
local retries=15
local redis_pass=${REDIS_PASSWORD:-RedisNewsMk2026}
until docker exec "$redis_container" redis-cli -a "$redis_pass" ping 2>/dev/null | grep -q PONG; do
retries=$((retries - 1))
if [ $retries -le 0 ]; then
warn "Redis не ответил за 30 секунд — продолжаю без него."
return
fi
echo -n "."
sleep 2
done
echo ""
info "Redis готов."
}
# ─── Создание директорий для данных ──────────────────────────────────────────
create_data_dirs() {
info "Создание директорий для хранения данных..."
mkdir -p ./data/postgres ./data/redis ./data/minio
info "Директории: ./data/postgres ./data/redis ./data/minio"
}
# ─── Главная функция ──────────────────────────────────────────────────────────
main() {
echo ""
echo "══════════════════════════════════════════════"
echo " Инициализация баз данных — News CMS"
echo "══════════════════════════════════════════════"
echo ""
create_data_dirs
# Запуск docker-compose_db.yml если не запущен
if ! docker compose -f docker-compose_db.yml ps --services --filter "status=running" 2>/dev/null | grep -q "db"; then
info "Запуск docker-compose_db.yml..."
docker compose -f docker-compose_db.yml up -d
sleep 3
fi
DB_CONTAINER=$(find_container)
info "Контейнер PostgreSQL: $DB_CONTAINER"
wait_for_postgres
create_user
create_database
grant_privileges
verify_connection
wait_for_redis
echo ""
echo "══════════════════════════════════════════════"
info "Готово! Теперь запускай:"
echo ""
echo " docker compose up -d --build"
echo ""
echo " Сайт: http://localhost"
echo " Админка: http://localhost/admin"
echo " MinIO консоль: http://localhost:9001"
echo "══════════════════════════════════════════════"
echo ""
}
main "$@"