Как превратить старый ноутбук в локальный WordPress-хостинг за 10 минут

Полная инструкция по установке DevOps-стенда с Bash-инсталлером

Старый ноутбук или ПК легко превратить в полноценный локальный хостинг для WordPress — с автоматическим созданием сайтов, резервными копиями, HTTPS и полной структурой, как на настоящем сервере.

Ниже — пошаговая инструкция, как развернуть такой стенд при помощи единственного Bash-скрипта-инсталлера.

Этот подход идеально подходит:

  • для обучения WordPress и DevOps,
  • для локальной разработки,
  • для теста плагинов и тем,
  • для создания изолированной среды, которую не жалко сломать.

Готовим машину — и запускаем автоснабжение магией.


🔧 Что делает инсталлер

После запуска скрипт автоматически:

  1. Устанавливает Apache, PHP, MariaDB.
  2. Настраивает PHP-модули, SSL, rewrite.
  3. Устанавливает WP-CLI.
  4. Создаёт структуру /var/www/wp-sites/.
  5. Создаёт 4 системных команды:
    • create-wp — создать WordPress-сайт за 10 секунд
    • delete-wp — удалить сайт полностью
    • backup-wp — бэкап всех сайтов
    • restore-wp — восстановление из бэкапа
  6. Настраивает HTTPS для каждого сайта.
  7. Добавляет домены в /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
  • админ-доступ:

Если браузер спросит — подтвердите самоподписанный сертификат (это нормально для локальной разработки).


🗑 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, которым удобно управлять и на котором можно безопасно экспериментировать.

Понравилась статья? Поделиться с друзьями:
Блог одного ITшника
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: