#!/bin/bash # # Скрипт инициализации F7cloud клиента # Устанавливает зависимости, настраивает Apache, Redis, PostgreSQL # set -e SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" INSTALL_DIR="$SCRIPT_DIR" CONFIG_FILE="$INSTALL_DIR/config/config.php" DATA_DIR="/data" APACHE_USER="www-data" echo "==========================================" echo "F7cloud Client Installation Script" echo "==========================================" echo "" # Проверка прав root if [ "$EUID" -ne 0 ]; then echo "Ошибка: Скрипт должен запускаться от root" exit 1 fi # Проверка переменных окружения для неинтерактивного режима NON_INTERACTIVE=false if [ -n "${DOMAIN:-}" ] && [ -n "${DB_NAME:-}" ] && [ -n "${DB_USER:-}" ] && \ [ -n "${DB_PASSWORD:-}" ] && [ -n "${ADMIN_USER:-}" ] && [ -n "${ADMIN_PASSWORD:-}" ]; then NON_INTERACTIVE=true echo "Обнаружен неинтерактивный режим (переменные окружения заданы)" fi # Функция генерации случайной строки generate_random() { openssl rand -hex 32 } # Функция генерации instanceid generate_instanceid() { openssl rand -hex 4 } # Проверка и установка зависимостей echo "[1/7] Проверка зависимостей..." # PHP if ! command -v php &> /dev/null; then echo "Установка PHP..." apt-get update -qq apt-get install -y php-fpm php-cli php-common php-mysql php-pgsql php-curl php-gd php-mbstring php-xml php-zip php-bcmath php-intl php-redis php-apcu php-imagick 2>/dev/null fi PHP_VERSION=$(php -r 'echo PHP_VERSION;') echo "✓ PHP $PHP_VERSION установлен" # Apache if ! command -v apache2 &> /dev/null && ! command -v httpd &> /dev/null; then echo "Установка Apache..." apt-get install -y apache2 libapache2-mod-php 2>/dev/null fi if command -v apache2 &> /dev/null; then APACHE_CMD="apache2ctl" APACHE_SERVICE="apache2" elif command -v httpd &> /dev/null; then APACHE_CMD="apachectl" APACHE_SERVICE="httpd" else echo "Ошибка: Apache не найден" exit 1 fi echo "✓ Apache установлен" # Включить необходимые модули Apache echo "Включение модулей Apache..." a2enmod rewrite headers env dir mime setenvif 2>/dev/null || true a2enmod php* 2>/dev/null || true # PostgreSQL клиент if ! command -v psql &> /dev/null; then echo "Установка PostgreSQL клиента..." apt-get install -y postgresql-client 2>/dev/null fi echo "✓ PostgreSQL клиент установлен" # Redis if ! command -v redis-cli &> /dev/null; then echo "[2/7] Установка Redis..." apt-get install -y redis-server 2>/dev/null # Настройка Redis sed -i 's/^# maxmemory /maxmemory 256mb/' /etc/redis/redis.conf 2>/dev/null || true sed -i 's/^# maxmemory-policy noeviction/maxmemory-policy allkeys-lru/' /etc/redis/redis.conf 2>/dev/null || true systemctl enable redis-server 2>/dev/null || systemctl enable redis 2>/dev/null || true systemctl restart redis-server 2>/dev/null || systemctl restart redis 2>/dev/null || true echo "✓ Redis установлен и запущен" else echo "[2/7] ✓ Redis уже установлен" systemctl start redis-server 2>/dev/null || systemctl start redis 2>/dev/null || true fi # Проверка подключения к Redis if redis-cli ping &> /dev/null; then echo "✓ Redis работает" else echo "⚠ Предупреждение: Redis не отвечает на ping" fi # Настройка Apache echo "[3/7] Настройка Apache..." # Определить домен if [ -z "${DOMAIN:-}" ]; then read -p "Введите доменное имя для F7cloud (например: cloud.example.com): " DOMAIN if [ -z "$DOMAIN" ]; then echo "Ошибка: Домен обязателен" exit 1 fi else echo "Используется домен из переменной окружения: $DOMAIN" fi # Определить путь установки (DocumentRoot) if [ -z "${INSTALL_PATH:-}" ]; then read -p "Путь установки F7cloud [$INSTALL_DIR]: " INSTALL_PATH INSTALL_PATH=${INSTALL_PATH:-$INSTALL_DIR} else echo "Используется путь установки из переменной окружения: $INSTALL_PATH" fi # Создать виртуальный хост Apache APACHE_SITE_FILE="/etc/apache2/sites-available/f7cloud.conf" if [ -f "/etc/httpd/conf.d/f7cloud.conf" ] || [ -f "/etc/apache2/sites-available/f7cloud.conf" ]; then read -p "Конфиг Apache для f7cloud уже существует. Перезаписать? (y/N): " OVERWRITE if [[ ! "$OVERWRITE" =~ ^[Yy]$ ]]; then echo "Пропуск создания конфига Apache" else rm -f /etc/apache2/sites-available/f7cloud.conf /etc/httpd/conf.d/f7cloud.conf fi fi if [ ! -f "/etc/apache2/sites-available/f7cloud.conf" ] && [ ! -f "/etc/httpd/conf.d/f7cloud.conf" ]; then cat > "$APACHE_SITE_FILE" < ServerName $DOMAIN DocumentRoot $INSTALL_PATH Options -Indexes +FollowSymLinks AllowOverride All Require all granted ErrorLog \${APACHE_LOG_DIR}/f7cloud_error.log CustomLog \${APACHE_LOG_DIR}/f7cloud_access.log combined EOF # Если Apache 2.4+ if [ -d "/etc/apache2/sites-available" ]; then a2ensite f7cloud.conf 2>/dev/null || true fi echo "✓ Конфиг Apache создан: $APACHE_SITE_FILE" fi # Запрос данных PostgreSQL echo "[4/7] Настройка PostgreSQL..." if [ -z "${DB_HOST:-}" ]; then read -p "Хост PostgreSQL [localhost]: " DB_HOST DB_HOST=${DB_HOST:-localhost} else echo "Используется хост PostgreSQL из переменной окружения: $DB_HOST" fi if [ -z "${DB_PORT:-}" ]; then read -p "Порт PostgreSQL [5432]: " DB_PORT DB_PORT=${DB_PORT:-5432} else echo "Используется порт PostgreSQL из переменной окружения: $DB_PORT" fi if [ -z "${DB_NAME:-}" ]; then read -p "Имя базы данных: " DB_NAME if [ -z "$DB_NAME" ]; then echo "Ошибка: Имя базы данных обязательно" exit 1 fi else echo "Используется имя базы данных из переменной окружения: $DB_NAME" fi if [ -z "${DB_USER:-}" ]; then read -p "Пользователь PostgreSQL: " DB_USER if [ -z "$DB_USER" ]; then echo "Ошибка: Пользователь обязателен" exit 1 fi else echo "Используется пользователь PostgreSQL из переменной окружения: $DB_USER" fi if [ -z "${DB_PASSWORD:-}" ]; then read -sp "Пароль PostgreSQL: " DB_PASSWORD echo "" if [ -z "$DB_PASSWORD" ]; then echo "Ошибка: Пароль обязателен" exit 1 fi else echo "Используется пароль PostgreSQL из переменной окружения" fi if [ -z "${DB_PREFIX:-}" ]; then read -p "Префикс таблиц [oc_]: " DB_PREFIX DB_PREFIX=${DB_PREFIX:-oc_} else echo "Используется префикс таблиц из переменной окружения: $DB_PREFIX" fi # Проверка подключения к БД echo "Проверка подключения к PostgreSQL..." export PGPASSWORD="$DB_PASSWORD" if psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "SELECT 1;" &> /dev/null; then echo "✓ Подключение к PostgreSQL успешно" else echo "⚠ Предупреждение: Не удалось подключиться к PostgreSQL" echo " Убедитесь, что база данных создана и пользователь имеет права" fi unset PGPASSWORD # Дополнительные настройки echo "[5/8] Дополнительные настройки..." if [ -z "${DATA_DIR_INPUT:-}" ]; then read -p "Директория данных [$DATA_DIR]: " DATA_DIR_INPUT DATA_DIR=${DATA_DIR_INPUT:-$DATA_DIR} else DATA_DIR=${DATA_DIR_INPUT:-$DATA_DIR} echo "Используется директория данных из переменной окружения: $DATA_DIR" fi if [ -z "${TRUSTED_DOMAINS_INPUT:-}" ]; then read -p "Trusted domains (через запятую) [$DOMAIN]: " TRUSTED_DOMAINS_INPUT TRUSTED_DOMAINS=${TRUSTED_DOMAINS_INPUT:-$DOMAIN} else TRUSTED_DOMAINS=${TRUSTED_DOMAINS_INPUT:-$DOMAIN} echo "Используются trusted domains из переменной окружения: $TRUSTED_DOMAINS" fi if [ -z "${TRUSTED_PROXIES:-}" ]; then read -p "Trusted proxies (IP через запятую, Enter для пропуска): " TRUSTED_PROXIES else echo "Используются trusted proxies из переменной окружения: $TRUSTED_PROXIES" fi if [ -z "${CLI_URL:-}" ]; then read -p "CLI URL (для occ команд) [https://$DOMAIN]: " CLI_URL CLI_URL=${CLI_URL:-https://$DOMAIN} else echo "Используется CLI URL из переменной окружения: $CLI_URL" fi # Данные администратора echo "[6/8] Создание администратора..." if [ -z "${ADMIN_USER:-}" ]; then read -p "Логин администратора [admin]: " ADMIN_USER ADMIN_USER=${ADMIN_USER:-admin} else echo "Используется логин администратора из переменной окружения: $ADMIN_USER" fi if [ -z "${ADMIN_PASSWORD:-}" ]; then read -sp "Пароль администратора: " ADMIN_PASSWORD echo "" if [ -z "$ADMIN_PASSWORD" ]; then echo "Ошибка: Пароль администратора обязателен" exit 1 fi else echo "Используется пароль администратора из переменной окружения" fi # Генерация секретов echo "[7/8] Генерация секретов..." PASSWORD_SALT=$(generate_random) SECRET=$(generate_random) INSTANCE_ID=$(generate_instanceid) # Создание config.php echo "[8/8] Создание config.php..." # Создать директорию config если нет mkdir -p "$INSTALL_DIR/config" # Бэкап существующего config.php if [ -f "$CONFIG_FILE" ]; then cp "$CONFIG_FILE" "$CONFIG_FILE.backup.$(date +%Y%m%d_%H%M%S)" echo "✓ Старый config.php сохранен в бэкап" fi # Создать config.php cat > "$CONFIG_FILE" < '$PASSWORD_SALT', 'secret' => '$SECRET', 'trusted_domains' => array ( EOF # Добавить trusted domains IFS=',' read -ra DOMAINS <<< "$TRUSTED_DOMAINS" for i in "${!DOMAINS[@]}"; do DOMAIN_CLEAN=$(echo "${DOMAINS[$i]}" | xargs) echo " $i => '$DOMAIN_CLEAN'," >> "$CONFIG_FILE" done cat >> "$CONFIG_FILE" < " >> "$CONFIG_FILE" echo " array (" >> "$CONFIG_FILE" IFS=',' read -ra PROXIES <<< "$TRUSTED_PROXIES" for i in "${!PROXIES[@]}"; do PROXY_CLEAN=$(echo "${PROXIES[$i]}" | xargs) echo " $i => '$PROXY_CLEAN'," >> "$CONFIG_FILE" done echo " )," >> "$CONFIG_FILE" fi cat >> "$CONFIG_FILE" < '$DATA_DIR', 'dbtype' => 'pgsql', 'version' => '1.0.0', 'dbname' => '$DB_NAME', 'dbhost' => '$DB_HOST', 'dbport' => '$DB_PORT', 'dbtableprefix' => '$DB_PREFIX', 'dbuser' => '$DB_USER', 'dbpassword' => '$DB_PASSWORD', 'installed' => false, 'instanceid' => '$INSTANCE_ID', 'memcache.local' => '\\\\OC\\\\Memcache\\\\APCu', 'memcache.distributed' => '\\\\OC\\\\Memcache\\\\Redis', 'memcache.locking' => '\\\\OC\\\\Memcache\\\\Redis', 'redis' => array ( 'host' => '127.0.0.1', 'port' => 6379, 'timeout' => 1.5, 'dbindex' => 0, ), 'maintenance' => false, 'loglevel' => 0, 'overwrite.cli.url' => '$CLI_URL', 'htaccess.RewriteBase' => '/', ); EOF chmod 640 "$CONFIG_FILE" chown root:$APACHE_USER "$CONFIG_FILE" echo "✓ config.php создан" # Создание директории данных if [ ! -d "$DATA_DIR" ]; then mkdir -p "$DATA_DIR" echo "✓ Директория данных создана: $DATA_DIR" fi chown -R $APACHE_USER:$APACHE_USER "$DATA_DIR" chmod 750 "$DATA_DIR" echo "✓ Права на директорию данных установлены" # Права на установочную директорию chown -R $APACHE_USER:$APACHE_USER "$INSTALL_DIR" find "$INSTALL_DIR" -type f -exec chmod 640 {} \; find "$INSTALL_DIR" -type d -exec chmod 750 {} \; find "$INSTALL_DIR" -name "*.sh" -exec chmod 750 {} \; find "$INSTALL_DIR" -name "*.php" -exec chmod 640 {} \; echo "✓ Права на файлы установлены" # Перезапуск Apache echo "" echo "Перезапуск Apache..." systemctl reload apache2 2>/dev/null || systemctl reload httpd 2>/dev/null || $APACHE_CMD graceful 2>/dev/null || true echo "✓ Apache перезапущен" # Запуск occ maintenance:install echo "" echo "[9/9] Инициализация F7cloud через occ..." cd "$INSTALL_DIR" # Проверка что база данных существует export PGPASSWORD="$DB_PASSWORD" if ! psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d "$DB_NAME" -c "SELECT 1;" &> /dev/null; then echo "⚠ Предупреждение: База данных '$DB_NAME' не доступна" echo " Создайте базу данных перед продолжением:" echo " CREATE DATABASE $DB_NAME OWNER $DB_USER;" read -p "Продолжить установку? (y/N): " CONTINUE if [[ ! "$CONTINUE" =~ ^[Yy]$ ]]; then echo "Установка прервана" exit 1 fi fi unset PGPASSWORD # Запуск maintenance:install echo "Запуск occ maintenance:install..." if sudo -u $APACHE_USER php occ maintenance:install \ --database pgsql \ --database-name "$DB_NAME" \ --database-host "$DB_HOST:$DB_PORT" \ --database-user "$DB_USER" \ --database-pass "$DB_PASSWORD" \ --admin-user "$ADMIN_USER" \ --admin-pass "$ADMIN_PASSWORD" \ --data-dir "$DATA_DIR" 2>&1; then echo "✓ F7cloud успешно инициализирован" # Обновить config.php - установить installed => true if grep -q "'installed' => false" "$CONFIG_FILE"; then sed -i "s/'installed' => false/'installed' => true/" "$CONFIG_FILE" echo "✓ config.php обновлен (installed => true)" fi # Если есть overwriteprotocol, установить https (если прокси использует HTTPS) if ! grep -q "overwriteprotocol" "$CONFIG_FILE"; then sed -i "/'htaccess.RewriteBase' => '/a\\ 'overwriteprotocol' => 'https'," "$CONFIG_FILE" echo "✓ Добавлен overwriteprotocol => https (для работы за прокси)" fi # Настройка F7Talk (если приложение установлено) echo "" TALK_CONFIG_FILE="$INSTALL_DIR/config/talk-config.php" if [ -f "$TALK_CONFIG_FILE" ]; then echo "Найдён файл конфигурации F7Talk: $TALK_CONFIG_FILE" echo "Применение настроек из файла..." USE_TALK_CONFIG_FILE=true else if [ -z "${CONFIGURE_TALK:-}" ]; then read -p "Настроить F7Talk (Talk)? (y/N): " CONFIGURE_TALK USE_TALK_CONFIG_FILE=false if [[ ! "$CONFIGURE_TALK" =~ ^[Yy]$ ]]; then echo "Пропуск настройки F7Talk" USE_TALK_CONFIG_FILE=false fi else USE_TALK_CONFIG_FILE=false if [[ "$CONFIGURE_TALK" =~ ^[Yy]$ ]] || [ "$CONFIGURE_TALK" = "yes" ] || [ "$CONFIGURE_TALK" = "true" ]; then echo "Настройка F7Talk включена через переменную окружения" else echo "Пропуск настройки F7Talk (задано через переменную окружения)" fi fi fi # Проверка, нужно ли настраивать F7Talk SHOULD_CONFIGURE_TALK=false if [ "$USE_TALK_CONFIG_FILE" = true ]; then SHOULD_CONFIGURE_TALK=true elif [[ "$CONFIGURE_TALK" =~ ^[Yy]$ ]] || [ "$CONFIGURE_TALK" = "yes" ] || [ "$CONFIGURE_TALK" = "true" ]; then SHOULD_CONFIGURE_TALK=true fi if [ "$SHOULD_CONFIGURE_TALK" = true ]; then echo "Настройка F7Talk..." # Проверка, включён ли Talk TALK_APP_ID="" if sudo -u $APACHE_USER php occ app:list 2>/dev/null | grep -qE "(f7talk|spreed).*enabled"; then TALK_APP_ID=$(sudo -u $APACHE_USER php occ app:list 2>/dev/null | grep -E "(f7talk|spreed)" | grep enabled | awk '{print $1}' | head -1) fi if [ -z "$TALK_APP_ID" ]; then echo "⚠ F7Talk не включен. Попытка включить..." sudo -u $APACHE_USER php occ app:enable f7talk 2>/dev/null || sudo -u $APACHE_USER php occ app:enable spreed 2>/dev/null || true TALK_APP_ID=$(sudo -u $APACHE_USER php occ app:list 2>/dev/null | grep -E "(f7talk|spreed)" | grep enabled | awk '{print $1}' | head -1) fi if [ -n "$TALK_APP_ID" ]; then # Если есть файл конфига - читаем из него if [ -f "$TALK_CONFIG_FILE" ]; then # Читаем настройки из PHP файла через php TALK_FEDERATION=$(php -r "require '$TALK_CONFIG_FILE'; echo \$config['federation_enabled'] ?? 'no';" 2>/dev/null || echo "no") TALK_ALLOWED_GROUPS=$(php -r "require '$TALK_CONFIG_FILE'; echo json_encode(\$config['allowed_groups'] ?? []);" 2>/dev/null || echo "[]") TALK_START_CONVERSATIONS=$(php -r "require '$TALK_CONFIG_FILE'; echo json_encode(\$config['start_conversations'] ?? []);" 2>/dev/null || echo "[]") TALK_STUN_SERVERS=$(php -r "require '$TALK_CONFIG_FILE'; echo json_encode(\$config['stun_servers'] ?? []);" 2>/dev/null || echo "[]") TALK_BREAKOUT_ROOMS=$(php -r "require '$TALK_CONFIG_FILE'; echo \$config['breakout_rooms'] ?? 'yes';" 2>/dev/null || echo "yes") TALK_CALL_RECORDING=$(php -r "require '$TALK_CONFIG_FILE'; echo \$config['call_recording'] ?? 'yes';" 2>/dev/null || echo "yes") TALK_ATTACHMENT_FOLDER=$(php -r "require '$TALK_CONFIG_FILE'; echo \$config['default_attachment_folder'] ?? '/Talk';" 2>/dev/null || echo "/Talk") echo "✓ Настройки прочитаны из $TALK_CONFIG_FILE" else # Интерактивный ввод read -p "Включить федерацию Talk? (y/N): " TALK_FEDERATION_INPUT TALK_FEDERATION=$([ "$TALK_FEDERATION_INPUT" = "y" ] || [ "$TALK_FEDERATION_INPUT" = "Y" ] && echo "yes" || echo "no") read -p "Группы для доступа к Talk (через запятую, Enter для всех): " TALK_ALLOWED_GROUPS_INPUT if [ -n "$TALK_ALLOWED_GROUPS_INPUT" ]; then TALK_ALLOWED_GROUPS=$(echo "$TALK_ALLOWED_GROUPS_INPUT" | awk -F',' '{printf "["; for(i=1;i<=NF;i++) {gsub(/^[ \t]+|[ \t]+$/, "", $i); if(i>1) printf ","; printf "\"%s\"", $i} printf "]"}') else TALK_ALLOWED_GROUPS="[]" fi read -p "STUN серверы (через запятую, Enter для пропуска): " TALK_STUN_SERVERS_INPUT if [ -n "$TALK_STUN_SERVERS_INPUT" ]; then TALK_STUN_SERVERS=$(echo "$TALK_STUN_SERVERS_INPUT" | awk -F',' '{printf "["; for(i=1;i<=NF;i++) {gsub(/^[ \t]+|[ \t]+$/, "", $i); if(i>1) printf ","; printf "\"%s\"", $i} printf "]"}') else TALK_STUN_SERVERS="[]" fi TALK_START_CONVERSATIONS="[]" TALK_BREAKOUT_ROOMS="yes" TALK_CALL_RECORDING="yes" TALK_ATTACHMENT_FOLDER="/Talk" fi # Применение настроек через occ if [ "$TALK_FEDERATION" = "yes" ]; then sudo -u $APACHE_USER php occ config:app:set "$TALK_APP_ID" federation_enabled --value="yes" 2>/dev/null || true echo "✓ Федерация Talk включена" fi if [ "$TALK_ALLOWED_GROUPS" != "[]" ]; then sudo -u $APACHE_USER php occ config:app:set "$TALK_APP_ID" allowed_groups --value="$TALK_ALLOWED_GROUPS" 2>/dev/null || true echo "✓ Группы для Talk настроены: $TALK_ALLOWED_GROUPS" fi if [ "$TALK_START_CONVERSATIONS" != "[]" ]; then sudo -u $APACHE_USER php occ config:app:set "$TALK_APP_ID" start_conversations --value="$TALK_START_CONVERSATIONS" 2>/dev/null || true echo "✓ Группы для создания бесед настроены" fi if [ "$TALK_STUN_SERVERS" != "[]" ]; then sudo -u $APACHE_USER php occ config:app:set "$TALK_APP_ID" stun_servers --value="$TALK_STUN_SERVERS" 2>/dev/null || true echo "✓ STUN серверы настроены: $TALK_STUN_SERVERS" fi sudo -u $APACHE_USER php occ config:app:set "$TALK_APP_ID" breakout_rooms --value="$TALK_BREAKOUT_ROOMS" 2>/dev/null || true sudo -u $APACHE_USER php occ config:app:set "$TALK_APP_ID" call_recording --value="$TALK_CALL_RECORDING" 2>/dev/null || true sudo -u $APACHE_USER php occ config:app:set "$TALK_APP_ID" default_attachment_folder --value="$TALK_ATTACHMENT_FOLDER" 2>/dev/null || true echo "✓ Настройки F7Talk применены" else echo "⚠ F7Talk не найден. Убедитесь, что приложение установлено." fi fi else echo "⚠ Ошибка при запуске occ maintenance:install" echo " Проверьте логи и убедитесь, что база данных создана" exit 1 fi echo "" echo "==========================================" echo "Установка завершена!" echo "==========================================" echo "" echo "F7cloud успешно установлен и настроен." echo "" echo "Данные для входа:" echo " URL: https://$DOMAIN" echo " Логин: $ADMIN_USER" echo " Пароль: <указанный вами>" echo "" echo "Конфигурация сохранена в: $CONFIG_FILE" echo "Директория данных: $DATA_DIR" echo "" echo "Примечание: SSL сертификаты должны быть настроены на прокси-сервере." echo ""