- Полная инструкция по установке DevOps-стенда с Bash-инсталлером
- 🔧 Что делает инсталлер
- 🖥 Требования
- 📥 1. Скачайте и создайте файл инсталлер
- 🔑 2. Дайте права на запуск
- 🚀 3. Запустите установку
- 🌐 4. Как создать первый сайт
- 🗑 5. Как удалить сайт
- 💾 6. Как сделать бэкап всех сайтов
- 🔄 7. Как восстановить сайт из бэкапа
- 🧩 8. Где хранятся сайты и конфигурации
- 🔒 9. HTTPS у каждого сайта автоматически
- 🎯 10. Что можно делать дальше
- 🧨 Заключение
Полная инструкция по установке DevOps-стенда с Bash-инсталлером
Старый ноутбук или ПК легко превратить в полноценный локальный хостинг для WordPress — с автоматическим созданием сайтов, резервными копиями, HTTPS и полной структурой, как на настоящем сервере.
Ниже — пошаговая инструкция, как развернуть такой стенд при помощи единственного Bash-скрипта-инсталлера.
Этот подход идеально подходит:
- для обучения WordPress и DevOps,
- для локальной разработки,
- для теста плагинов и тем,
- для создания изолированной среды, которую не жалко сломать.
Готовим машину — и запускаем автоснабжение магией.
🔧 Что делает инсталлер
После запуска скрипт автоматически:
- Устанавливает Apache, PHP, MariaDB.
- Настраивает PHP-модули, SSL, rewrite.
- Устанавливает WP-CLI.
- Создаёт структуру
/var/www/wp-sites/. - Создаёт 4 системных команды:
create-wp— создать WordPress-сайт за 10 секундdelete-wp— удалить сайт полностьюbackup-wp— бэкап всех сайтовrestore-wp— восстановление из бэкапа
- Настраивает HTTPS для каждого сайта.
- Добавляет домены в
/etc/hosts
Стенд превращается в домашний мини-хостинг, как Timeweb или VDS, только полностью у вас под рукой и с полным контролем.
🖥 Требования
- Ubuntu 22.04 / 24.04 (Desktop или Server)
- Доступ через sudo
- Старый ноутбук или ПК (2–4 ГБ RAM — достаточно)
📥 1. Скачайте и создайте файл инсталлер
Создание
nano install_wp_stand.sh
Вставь в него весь код ниже.
!/usr/bin/env bash
set -e
if [ "$EUID" -ne 0 ]; then
echo "Запусти этот скрипт через sudo:"
echo " sudo $0"
exit 1
fi
MAIN_USER=${SUDO_USER:-$(logname 2>/dev/null || echo "")}
if [ -z "$MAIN_USER" ]; then
echo "Не получилось определить основного пользователя (SUDO_USER)."
echo "Отредактируй скрипт и подставь своё имя пользователя вручную в переменную MAIN_USER."
exit 1
fi
echo "----------------------------------"
echo "Устанавливаем LAMP-стенд для WordPress"
echo "Основной пользователь: $MAIN_USER"
echo "----------------------------------"
apt update
apt install -y apache2 mariadb-server \
php libapache2-mod-php php-mysql php-xml php-mbstring php-curl php-gd php-zip php-intl \
unzip curl ssl-cert
echo "Включаем модули Apache (rewrite, ssl, headers)…"
a2enmod rewrite ssl headers >/dev/null || true
Определяем версию PHP и включаем модуль phpX.Y
if command -v php >/dev/null 2>&1; then
PHP_V=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;')
if [ -n "$PHP_V" ]; then
a2enmod "php$PHP_V" >/dev/null 2>&1 || true
fi
fi
Убираем ворнинг AH00558 (ServerName)
if ! grep -q "^ServerName " /etc/apache2/apache2.conf; then
echo "ServerName localhost" >> /etc/apache2/apache2.conf
fi
systemctl restart apache2
systemctl enable apache2 mariadb >/dev/null
echo "Создаём каталог для сайтов…"
mkdir -p /var/www/wp-sites
chown "$MAIN_USER":www-data /var/www/wp-sites
chmod 775 /var/www/wp-sites
echo "Устанавливаем WP-CLI…"
cd /tmp
curl -sS -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
php wp-cli.phar --info >/dev/null
chmod +x wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp
echo "Создаём директорию для SSL-сертов…"
mkdir -p /etc/apache2/ssl
echo "----------------------------------"
echo "Создаём скрипт: create-wp"
echo "----------------------------------"
cat <<'EOF' > /usr/local/bin/create-wp
!/bin/bash
set -e
if [ -z "$1" ]; then
echo "Использование: create-wp example.local"
exit 1
fi
DOMAIN=$1
SITENAME=${DOMAIN%.*}
WEBROOT="/var/www/wp-sites/$SITENAME"
DBNAME="wp_${SITENAME//./_}"
DBUSER="${SITENAME}_user"
DBPASS=$(openssl rand -base64 12)
CURRENT_USER=${SUDO_USER:-$(whoami)}
echo "Создаю новый сайт WordPress:"
echo " Домен: $DOMAIN"
echo " Папка: $WEBROOT"
echo " База: $DBNAME"
echo " DB user: $DBUSER"
echo " DB pass: $DBPASS"
echo "----------------------------------"
sudo mkdir -p "$WEBROOT"
sudo chown "$CURRENT_USER":www-data "$WEBROOT"
sudo chmod 775 "$WEBROOT"
cd "$WEBROOT"
echo "Скачиваю ядро WordPress…"
wp core download
echo "Создаю базу и пользователя…"
sudo mysql -e "CREATE DATABASE IF NOT EXISTS `$DBNAME` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
sudo mysql -e "CREATE USER IF NOT EXISTS '$DBUSER'@'localhost' IDENTIFIED BY '$DBPASS';"
sudo mysql -e "GRANT ALL PRIVILEGES ON `$DBNAME`.* TO '$DBUSER'@'localhost';"
sudo mysql -e "FLUSH PRIVILEGES;"
echo "Создаю wp-config.php…"
wp config create --dbname="$DBNAME" --dbuser="$DBUSER" --dbpass="$DBPASS" --dbhost=localhost --skip-check
Разрешаем прямую запись (без FTP)
echo "define('FS_METHOD','direct');" >> wp-config.php
echo "Устанавливаю WordPress…"
wp core install \
--url="http://$DOMAIN" \
--title="$SITENAME" \
--admin_user="admin" \
--admin_password="admin123" \
--admin_email="admin@$DOMAIN"
sudo chown -R "$CURRENT_USER":www-data "$WEBROOT"
sudo find "$WEBROOT" -type d -exec chmod 775 {} \;
sudo find "$WEBROOT" -type f -exec chmod 664 {} \;
VHOST="/etc/apache2/sites-available/$SITENAME.conf"
echo "Создаю виртуальный хост Apache (HTTP)…"
sudo tee "$VHOST" >/dev/null <
ServerName $DOMAIN
DocumentRoot $WEBROOT
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}\$1 [R=301,L]
<Directory $WEBROOT>
AllowOverride All
Require all granted
DirectoryIndex index.php index.html
</Directory>
EOV
Создаём самоподписанный SSL-сертификат для домена
SSL_KEY="/etc/apache2/ssl/${DOMAIN}.key"
SSL_CRT="/etc/apache2/ssl/${DOMAIN}.crt"
if [ ! -f "$SSL_KEY" ] || [ ! -f "$SSL_CRT" ]; then
echo "Создаю самоподписанный SSL-сертификат для $DOMAIN…"
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout "$SSL_KEY" \
-out "$SSL_CRT" \
-subj "/CN=$DOMAIN" \
-addext "subjectAltName=DNS:$DOMAIN" >/dev/null 2>&1
fi
SSL_VHOST="/etc/apache2/sites-available/${SITENAME}-ssl.conf"
echo "Создаю виртуальный хост Apache (HTTPS)…"
sudo tee "$SSL_VHOST" >/dev/null <
ServerName $DOMAIN
DocumentRoot $WEBROOT
SSLEngine on
SSLCertificateFile $SSL_CRT
SSLCertificateKeyFile $SSL_KEY
<Directory $WEBROOT>
AllowOverride All
Require all granted
DirectoryIndex index.php index.html
</Directory>
Header always set Strict-Transport-Security "max-age=31536000" env=HTTPS
EOSS
sudo a2ensite "$SITENAME.conf" >/dev/null
sudo a2ensite "${SITENAME}-ssl.conf" >/dev/null
Добавляем домен в /etc/hosts, если нет
if ! grep -q "$DOMAIN" /etc/hosts; then
echo "127.0.0.1 $DOMAIN" | sudo tee -a /etc/hosts >/dev/null
fi
sudo systemctl reload apache2
echo "----------------------------------"
echo "Сайт создан!"
echo "URL: http://$DOMAIN"
echo "URL HTTPS: https://$DOMAIN"
echo "Admin: https://$DOMAIN/wp-admin/"
echo "Логин: admin"
echo "Пароль: admin123"
echo "----------------------------------"
EOF
chmod +x /usr/local/bin/create-wp
echo "----------------------------------"
echo "Создаём скрипт: delete-wp"
echo "----------------------------------"
cat <<'EOF' > /usr/local/bin/delete-wp
!/bin/bash
set -e
if [ -z "$1" ]; then
echo "Использование: delete-wp example.local"
exit 1
fi
DOMAIN=$1
SITENAME=${DOMAIN%.*}
WEBROOT="/var/www/wp-sites/$SITENAME"
DBNAME="wp_${SITENAME//./_}"
DBUSER="${SITENAME}_user"
echo "Удаляю сайт:"
echo " Домен: $DOMAIN"
echo " Папка: $WEBROOT"
echo " База: $DBNAME"
echo " DB user:$DBUSER"
echo "----------------------------------"
Отключаем и удаляем виртуальные хосты
if [ -f "/etc/apache2/sites-available/${SITENAME}.conf" ]; then
sudo a2dissite "${SITENAME}.conf" >/dev/null || true
sudo rm "/etc/apache2/sites-available/${SITENAME}.conf"
fi
if [ -f "/etc/apache2/sites-available/${SITENAME}-ssl.conf" ]; then
sudo a2dissite "${SITENAME}-ssl.conf" >/dev/null || true
sudo rm "/etc/apache2/sites-available/${SITENAME}-ssl.conf"
fi
Чистим /etc/hosts
if grep -q "$DOMAIN" /etc/hosts; then
sudo sed -i "/$DOMAIN/d" /etc/hosts
fi
Удаляем директорию сайта
if [ -d "$WEBROOT" ]; then
sudo rm -rf "$WEBROOT"
fi
Удаляем базу и пользователя
sudo mysql -e "DROP DATABASE IF EXISTS `$DBNAME`;"
sudo mysql -e "DROP USER IF EXISTS '$DBUSER'@'localhost';"
sudo mysql -e "FLUSH PRIVILEGES;"
sudo systemctl reload apache2
echo "Сайт $DOMAIN полностью удалён."
EOF
chmod +x /usr/local/bin/delete-wp
echo "----------------------------------"
echo "Создаём скрипт: backup-wp"
echo "----------------------------------"
cat <<'EOF' > /usr/local/bin/backup-wp
!/bin/bash
set -e
SITES_ROOT="/var/www/wp-sites"
CURRENT_USER=${SUDO_USER:-$(whoami)}
BACKUP_ROOT="/home/$CURRENT_USER/wp-backups"
DATE=$(date +"%Y-%m-%d")
echo "--------------------------------------"
echo "Резервное копирование всех WordPress-сайтов"
echo "Дата: $DATE"
echo "Папка: $BACKUP_ROOT/$DATE"
echo "--------------------------------------"
mkdir -p "$BACKUP_ROOT/$DATE"
for SITE_DIR in "$SITES_ROOT"/*; do
if [ -d "$SITE_DIR" ]; then
SITE_NAME=$(basename "$SITE_DIR")
echo "Обрабатываю сайт: $SITE_NAME"
SITE_BACKUP_DIR="$BACKUP_ROOT/$DATE/$SITE_NAME"
mkdir -p "$SITE_BACKUP_DIR"
cd "$SITE_DIR"
if [ ! -f "wp-config.php" ]; then
echo "- Пропуск: нет wp-config.php"
echo "--------------------------------------"
continue
fi
DB_NAME=$(php -r "include 'wp-config.php'; echo DB_NAME;")
echo "- Дамп базы данных: $DB_NAME"
if ! wp db export "$SITE_BACKUP_DIR/${DB_NAME}.sql" 2>/dev/null; then
echo " ! Не удалось сделать dump через wp db export"
exit 1
fi
echo "- Архивация файлов сайта..."
tar -czf "$SITE_BACKUP_DIR/${SITE_NAME}.tar.gz" ./
echo "✓ Бэкап $SITE_NAME завершён"
echo "--------------------------------------"
fi
done
echo "Все бэкапы завершены."
echo "Хранятся в: $BACKUP_ROOT/$DATE"
EOF
chmod +x /usr/local/bin/backup-wp
echo "----------------------------------"
echo "Создаём скрипт: restore-wp"
echo "----------------------------------"
cat <<'EOF' > /usr/local/bin/restore-wp
!/bin/bash
set -e
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Использование: restore-wp domain.local YYYY-MM-DD"
exit 1
fi
DOMAIN=$1
DATE=$2
SITENAME=${DOMAIN%.*}
WEBROOT="/var/www/wp-sites/$SITENAME"
CURRENT_USER=${SUDO_USER:-$(whoami)}
BACKUP_ROOT="/home/$CURRENT_USER/wp-backups"
BACKUP_DIR="$BACKUP_ROOT/$DATE/$SITENAME"
echo "----------------------------------"
echo "Восстановление сайта: $DOMAIN"
echo "Дата бэкапа: $DATE"
echo "Папка бэкапа: $BACKUP_DIR"
echo "----------------------------------"
if [ ! -d "$BACKUP_DIR" ]; then
echo "Ошибка: папка бэкапа не найдена: $BACKUP_DIR"
exit 1
fi
SQL_FILE=$(ls "$BACKUP_DIR"/.sql 2>/dev/null | head -n 1) TAR_FILE=$(ls "$BACKUP_DIR"/.tar.gz 2>/dev/null | head -n 1)
if [ -z "$SQL_FILE" ] || [ -z "$TAR_FILE" ]; then
echo "Ошибка: отсутствует SQL или TAR.GZ в $BACKUP_DIR"
exit 1
fi
echo "SQL-файл: $SQL_FILE"
echo "TAR-файл: $TAR_FILE"
if [ -d "$WEBROOT" ]; then
echo "Удаляю текущие файлы сайта в $WEBROOT…"
sudo rm -rf "$WEBROOT"
fi
sudo mkdir -p "$WEBROOT"
sudo chown "$CURRENT_USER":www-data "$WEBROOT"
echo "Распаковка файлов…"
sudo tar -xzf "$TAR_FILE" -C "$WEBROOT"
if [ ! -f "$WEBROOT/wp-config.php" ]; then
echo "Ошибка: после распаковки нет wp-config.php"
exit 1
fi
DB_NAME=$(php -r "include '$WEBROOT/wp-config.php'; echo DB_NAME;")
DB_USER=$(php -r "include '$WEBROOT/wp-config.php'; echo DB_USER;")
DB_PASS=$(php -r "include '$WEBROOT/wp-config.php'; echo DB_PASSWORD;")
echo "База данных для восстановления: $DB_NAME (user: $DB_USER)"
echo "Пересоздаю базу данных…"
sudo mysql -e "DROP DATABASE IF EXISTS `$DB_NAME`;"
sudo mysql -e "CREATE DATABASE `$DB_NAME` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
echo "Импорт дампа…"
sudo mysql "$DB_NAME" < "$SQL_FILE"
VHOST="/etc/apache2/sites-available/$SITENAME.conf"
if [ ! -f "$VHOST" ]; then
echo "Создаю HTTP-виртхост…"
sudo tee "$VHOST" >/dev/null <
ServerName $DOMAIN
DocumentRoot $WEBROOT
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}\$1 [R=301,L]
<Directory $WEBROOT>
AllowOverride All
Require all granted
DirectoryIndex index.php index.html
</Directory>
EOV
sudo a2ensite "$SITENAME.conf" >/dev/null
fi
if ! grep -q "$DOMAIN" /etc/hosts; then
echo "127.0.0.1 $DOMAIN" | sudo tee -a /etc/hosts >/dev/null
fi
sudo systemctl reload apache2
echo "----------------------------------"
echo "Сайт $DOMAIN восстановлен!"
echo "URL: http://$DOMAIN"
echo "URL: https://$DOMAIN (если есть SSL-конфиг)"
echo "----------------------------------"
EOF
chmod +x /usr/local/bin/restore-wp
echo "----------------------------------"
echo "Готово!"
echo "Доступные команды:"
echo " create-wp example.local - создать новый WP-сайт"
echo " delete-wp example.local - удалить сайт"
echo " backup-wp - бэкап всех сайтов"
echo " restore-wp site.local ДАТА - восстановить сайт"
echo "----------------------------------"
echo "Создай первый сайт, например:"
echo " create-wp testsite.local"
echo "и открой: https://testsite.local"
echo "(в браузере нужно будет один раз доверить самоподписанный сертификат)"
echo "----------------------------------"
Сохрани (Ctrl+O, Enter, Ctrl+X).
🔑 2. Дайте права на запуск
chmod +x install_wp_stand.sh
🚀 3. Запустите установку
Важно: запускать через sudo, иначе инсталляция не сможет создавать конфиги и сервисы.
sudo ./install_wp_stand.sh
Скрипт автоматически:
- установит весь LAMP-стек
- сконфигурирует Apache
- подготовит SSL
- установит WP-CLI
- создаст каталоги
- установит команды
create-wp,delete-wp,backup-wp,restore-wp
После завершения вы увидите список доступных команд.
🌐 4. Как создать первый сайт
Например, создадим сайт:
create-wp testsite.local
Через 10 секунд у вас будет полностью готовый WordPress:
- файлы:
/var/www/wp-sites/testsite/ - база данных:
wp_testsite - админ-доступ:
- URL: https://testsite.local/wp-admin/
- логин:
admin - пароль:
admin123
Если браузер спросит — подтвердите самоподписанный сертификат (это нормально для локальной разработки).
🗑 5. Как удалить сайт
delete-wp testsite.local
Будут удалены:
- виртуальные хосты,
- файлы сайта,
- база данных и пользователь MySQL,
- запись в
/etc/hosts.
Без ручных действий.
💾 6. Как сделать бэкап всех сайтов
backup-wp
Бэкапы сохраняются в:
/home/ИМЯ_ПОЛЬЗОВАТЕЛЯ/wp-backups/ГОД-МЕСЯЦ-ДЕНЬ/
Для каждого сайта сохраняются:
- архив файлов (
.tar.gz) - дамп базы (
.sql)
🔄 7. Как восстановить сайт из бэкапа
Например, восстановить сайт testsite.local из бэкапа от 2025-11-16:
restore-wp testsite.local 2025-11-16
Скрипт:
- удалит текущую версию,
- восстановит файлы,
- создаст базу,
- импортирует SQL,
- проверит virtualhost,
- перезапустит Apache.
Сайт мгновенно оживает — как «откат» на продакшене.
🧩 8. Где хранятся сайты и конфигурации
Сайты:
/var/www/wp-sites/
Конфиги виртуальных хостов:
/etc/apache2/sites-available/
Бэкапы:
/home/USERNAME/wp-backups/
SSL-сертификаты:
/etc/apache2/ssl/
🔒 9. HTTPS у каждого сайта автоматически
Инсталлер автоматически создаёт:
- HTTP-виртхост с редиректом на HTTPS
- HTTPS-виртхост с самоподписанным сертификатом
Это:
- защищает авторизацию WordPress
- позволяет тестировать плагины, требующие HTTPS
- делает стенд похожим на настоящий боевой сервер
🎯 10. Что можно делать дальше
После развёртывания можно:
- создавать staging-копии через
create-wp newsite.local - тестировать темы и плагины
- готовить проекты к релизу
- моделировать падения и восстановления
- обучаться DevOps-процессам
Этот стенд — идеальная песочница.
🧨 Заключение
Вы получаете полный автономный WordPress-хостинг прямо дома — с HTTPS, базами, бэкапами и автоматическим деплоем сайтов в одну команду.
Инсталлер превращает старый ноутбук в мини-сервер уровня VDS, которым удобно управлять и на котором можно безопасно экспериментировать.
