#!/usr/bin/env bash RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' CYAN='\033[0;36m' NC='\033[0m' log() { echo -e "${GREEN}[INFO]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } err() { echo -e "${RED}[ERROR]${NC} $*" >&2; } init_script_dir() { SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[1]}")" && pwd)" cd "$SCRIPT_DIR" } check_dependencies() { if ! command -v docker >/dev/null 2>&1; then err "Не найдена команда: docker" exit 1 fi if ! docker compose version >/dev/null 2>&1; then err "Docker Compose v2 не найден. Установите docker compose plugin." exit 1 fi } load_env_from_file() { local file="$1" [[ -f "$file" ]] || return 0 while IFS= read -r line || [[ -n "$line" ]]; do [[ "$line" =~ ^[[:space:]]*# ]] && continue [[ -z "${line// }" ]] && continue if [[ "$line" =~ ^([A-Za-z_][A-Za-z0-9_]*)=(.*)$ ]]; then export "${BASH_REMATCH[1]}=${BASH_REMATCH[2]}" fi done < "$file" } generate_password() { if command -v openssl >/dev/null 2>&1; then openssl rand -base64 24 | tr -dc 'A-Za-z0-9' | head -c 20 else tr -dc 'A-Za-z0-9' /dev/null | head -c 20 fi } prompt_value() { local prompt_text="$1" local default_value="$2" local secret="${3:-false}" local input="" if [[ "$secret" == true ]]; then read -rs -p "$prompt_text (Enter — автогенерация): " input echo if [[ -z "$input" ]]; then input="$(generate_password)" warn "Сгенерирован пароль PostgreSQL: $input" fi else read -r -p "$prompt_text [$default_value]: " input if [[ -z "$input" ]]; then input="$default_value" fi fi printf '%s' "$input" } write_env_file() { cat > .env </dev/null || date) # Домен или IP сервера (без http/https) GITEA_DOMAIN=${GITEA_DOMAIN} # Порт веб-интерфейса Gitea GITEA_HTTP_PORT=${GITEA_HTTP_PORT} # Порт SSH для git clone/push GITEA_SSH_PORT=${GITEA_SSH_PORT} # Версия образа Gitea GITEA_VERSION=${GITEA_VERSION} # База данных PostgreSQL POSTGRES_USER=${POSTGRES_USER} POSTGRES_PASSWORD=${POSTGRES_PASSWORD} POSTGRES_DB=${POSTGRES_DB} # Часовой пояс TZ=${TZ} EOF } setup_env_interactive() { local non_interactive="${1:-false}" local defaults_file=".env.example" if [[ -f .env ]]; then defaults_file=".env" if [[ "$non_interactive" != true ]]; then warn "Файл .env уже существует." read -r -p "Пересоздать конфигурацию? [y/N] " confirm if [[ ! "$confirm" =~ ^[Yy]$ ]]; then load_env_from_file .env return 0 fi fi fi if [[ ! -f "$defaults_file" && ! -f .env.example ]]; then err "Не найден .env.example" exit 1 fi [[ -f "$defaults_file" ]] || defaults_file=".env.example" unset GITEA_DOMAIN GITEA_HTTP_PORT GITEA_SSH_PORT GITEA_VERSION unset POSTGRES_USER POSTGRES_PASSWORD POSTGRES_DB TZ load_env_from_file "$defaults_file" GITEA_DOMAIN="${GITEA_DOMAIN:-localhost}" GITEA_HTTP_PORT="${GITEA_HTTP_PORT:-3000}" GITEA_SSH_PORT="${GITEA_SSH_PORT:-2222}" GITEA_VERSION="${GITEA_VERSION:-1.22.6}" POSTGRES_USER="${POSTGRES_USER:-gitea}" POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-}" POSTGRES_DB="${POSTGRES_DB:-gitea}" TZ="${TZ:-Europe/Moscow}" if [[ "$non_interactive" == true ]]; then if [[ -z "$POSTGRES_PASSWORD" || "$POSTGRES_PASSWORD" == "change_me_strong_password" ]]; then POSTGRES_PASSWORD="$(generate_password)" warn "Сгенерирован пароль PostgreSQL: $POSTGRES_PASSWORD" fi write_env_file load_env_from_file .env return 0 fi echo echo -e "${CYAN}=== Настройка Gitea ===${NC}" echo "Enter — оставить значение в скобках." echo GITEA_DOMAIN="$(prompt_value "Домен или IP сервера" "$GITEA_DOMAIN")" GITEA_HTTP_PORT="$(prompt_value "Порт веб-интерфейса" "$GITEA_HTTP_PORT")" GITEA_SSH_PORT="$(prompt_value "Порт SSH для Git" "$GITEA_SSH_PORT")" GITEA_VERSION="$(prompt_value "Версия образа Gitea" "$GITEA_VERSION")" POSTGRES_USER="$(prompt_value "Пользователь PostgreSQL" "$POSTGRES_USER")" POSTGRES_DB="$(prompt_value "Имя базы данных" "$POSTGRES_DB")" TZ="$(prompt_value "Часовой пояс (TZ)" "$TZ")" echo POSTGRES_PASSWORD="$(prompt_value "Пароль PostgreSQL" "" true)" write_env_file load_env_from_file .env log "Конфигурация сохранена в .env" } ensure_env() { if [[ ! -f .env ]]; then err "Файл .env не найден. Выполните: ./deploy.sh install" exit 1 fi load_env_from_file .env if [[ "${POSTGRES_PASSWORD:-}" == "change_me_strong_password" ]]; then warn "Используется пароль по умолчанию! Измените POSTGRES_PASSWORD в .env" fi } confirm_or_exit() { local message="${1:-Продолжить?}" read -r -p "$message [y/N] " confirm if [[ ! "$confirm" =~ ^[Yy]$ ]]; then log "Отменено." exit 0 fi } get_compose_project_name() { local project_name project_name="$(basename "$SCRIPT_DIR" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9_-]/_/g')" echo "${COMPOSE_PROJECT_NAME:-$project_name}" } get_volume_names() { local prefix prefix="$(get_compose_project_name)" echo "${prefix}_gitea_data ${prefix}_postgres_data" }