Що потрібно перед налаштуванням Nginx
У цьому посібнику використано Ubuntu 24.04 LTS, Nginx, PHP-FPM, MariaDB і два приклади доменів: site1.com та site2.com. Замініть ці назви своїми фактичними доменами. Ця схема підходить для статичних сайтів, WordPress, Laravel, PHP-застосунків, сайтів документації та невеликих API.
Мінімальні вимоги для продакшену
- CPU: 4 vCPU для кількох легких вебсайтів; використовуйте виділені фізичні ядра для постійного трафіку або застосунків із високим навантаженням на CPU.
- Пам’ять: щонайменше 8 ГБ RAM. Виділіть більше, якщо кілька сайтів використовують PHP, MariaDB, Redis або служби пошуку.
- Сховище: щонайменше 100 ГБ NVMe SSD, резервні копії мають зберігатися окремо.
- Операційна система: Ubuntu 24.04 LTS із доступом root або sudo.
- Мережа: статична публічна IPv4-адреса та правильно налаштований DNS.
- Доступ: SSH-клієнт і локальна копія кожного вебсайту.
VPS достатньо для кількох сайтів із низьким трафіком, але виділений або bare-metal сервер є кращим вибором для постійного трафіку, великих баз даних, суворої ізоляції або передбачуваної продуктивності диска й CPU. Один сервер також створює єдиний домен відмови, тому зберігайте резервні копії поза сервером і майте план відновлення.
Планування продуктивності для продакшену
Використовуйте таблицю нижче як відправну точку для визначення розміру продакшен-середовища; фактична продуктивність залежить від кешування, коду застосунку, запитів до бази даних, розмірів зображень і шаблонів трафіку.
| Масштаб: активні сайти та сукупне пікове навантаження | vCPU | RAM | Диск | Щомісячний трафік |
|---|---|---|---|---|
| 5 сайтів, до 20 динамічних запитів/с | 4 vCPU | 8 ГБ | 160 ГБ NVMe SSD | 5 ТБ |
| 20 сайтів, до 100 динамічних запитів/с | 8 vCPU | 32 ГБ | 480 ГБ NVMe SSD | 15 ТБ |
| 50 сайтів, до 300 динамічних запитів/с | 16 виділених ядер | 64 ГБ | 960 ГБ NVMe SSD із RAID1 | 30 ТБ |
Для постійного трафіку, баз даних або клієнтів, яким потрібна ізоляція, обирайте bare metal із виділеними ядрами та корпоративним NVMe-сховищем замість перевантаження невеликого VPS.
Крок 1: Оновіть Ubuntu та створіть адміністративного користувача
Підключіться через SSH, оновіть пакети та створіть обліковий запис не-root користувача. Замініть deploy на бажане ім’я користувача.
ssh root@SERVER_IP
apt update && apt -y full-upgrade
apt install -y sudo
adduser deploy
usermod -aG sudo deploy
Скопіюйте свій SSH-ключ до нового облікового запису, перш ніж вимикати вхід root:
ssh-copy-id deploy@SERVER_IP
ssh deploy@SERVER_IP
sudo hostnamectl set-hostname web01.example.net
Після підтвердження роботи входу за ключем відредагуйте налаштування SSH:
sudo nano /etc/ssh/sshd_configУстановіть PermitRootLogin no і, якщо кожен адміністратор використовує ключі, установіть PasswordAuthentication no. Перевірте та перезавантажте:
sudo sshd -t && sudo systemctl reload ssh
Крок 2: Встановіть Nginx, PHP-FPM, MariaDB та інструменти брандмауера
Встановіть вебстек і поширені розширення PHP. Видаліть розширення, які не потрібні вашим застосункам.
sudo apt install -y nginx mariadb-server php-fpm php-mysql php-curl php-gd php-mbstring php-xml php-zip php-intl unzip curl ufw fail2ban
sudo systemctl enable --now nginx mariadb php8.3-fpm fail2ban
sudo mariadb-secure-installationПеревірте встановлений сокет PHP-FPM, оскільки версія може відрізнятися в іншому випуску Ubuntu:
ls /run/php/php*-fpm.sock
systemctl status nginx --no-pager
Дозвольте лише необхідні публічні служби. За можливості доступ SSH слід обмежити довіреним діапазоном IP-адрес.
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable
sudo ufw status verboseКрок 3: Створіть окремі каталоги та налаштуйте дозволи
Надайте кожному вебсайту власний кореневий каталог документів. Розділення сайтів спрощує розгортання, керування дозволами, журналами та майбутню міграцію.
sudo mkdir -p /var/www/site1.com/public
sudo mkdir -p /var/www/site2.com/public
sudo chown -R deploy:www-data /var/www/site1.com /var/www/site2.com
sudo find /var/www/site1.com /var/www/site2.com -type d -exec chmod 755 {} \;
sudo find /var/www/site1.com /var/www/site2.com -type f -exec chmod 644 {} \;
Створіть тестові файли:
printf '%s\n' '<h1>site1.com works</h1>' | sudo tee /var/www/site1.com/public/index.html
printf '%s\n' '<h1>site2.com works</h1>' | sudo tee /var/www/site2.com/public/index.html
Для WordPress або іншого PHP-застосунку завантажте файли у відповідний каталог public і переконайтеся, що лише каталоги, які потребують завантаження файлів, доступні для запису вебпроцесу.
Крок 4: Налаштуйте блоки сервера Nginx
Nginx вибирає блок сервера за запитаним ім’ям хоста. Створіть окремий файл конфігурації для кожного сайту.
sudo nano /etc/nginx/sites-available/site1.comВикористовуйте цю конфігурацію для статичного або PHP-сайту:
server {
listen 80;
listen [::]:80;
server_name site1.com www.site1.com;
root /var/www/site1.com/public;
index index.php index.html;
access_log /var/log/nginx/site1.access.log;
error_log /var/log/nginx/site1.error.log;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Створіть другий блок, змінивши домен і шлях:
sudo cp /etc/nginx/sites-available/site1.com /etc/nginx/sites-available/site2.com
sudo sed -i 's/site1\.com/site2.com/g; s#/var/www/site1.com#/var/www/site2.com#g; s#site1#site2#g' /etc/nginx/sites-available/site2.com
sudo ln -s /etc/nginx/sites-available/site1.com /etc/nginx/sites-enabled/site1.com
sudo ln -s /etc/nginx/sites-available/site2.com /etc/nginx/sites-enabled/site2.com
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx
Правило try_files підходить для багатьох застосунків із front-controller. Суто статичний сайт може натомість використовувати try_files $uri $uri/ =404;, що запобігає надсиланню невідомих шляхів до PHP.
Крок 5: Спрямуйте DNS-записи на виділений сервер
У свого DNS-провайдера створіть такі записи:
- Запис
Aдляsite1.com, що вказує на IPv4-адресу сервера. - Запис
Aдляwww.site1.com, що вказує на ту саму адресу, або CNAME наsite1.com. - Еквівалентні записи для
site2.comіwww.site2.com. - Запис
AAAAлише якщо IPv6 налаштовано та протестовано на сервері.
Перевірте DNS перед запитом сертифікатів:
sudo apt install -y dnsutils
dig +short site1.com A
dig +short site2.com A
curl -I http://site1.com
Зміни DNS можуть затримуватися через кешовані значення TTL. Відповідь від dig повинна містити адресу сервера перед продовженням.
Крок 6: Увімкніть HTTPS за допомогою Let's Encrypt
Встановіть Certbot і запитайте один сертифікат, що охоплює і кореневе ім’я, і ім’я хоста www для кожного сайту.
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d site1.com -d www.site1.com
sudo certbot --nginx -d site2.com -d www.site2.com
Оберіть опцію перенаправлення, коли Certbot запитає, чи має HTTP перенаправлятися на HTTPS. Перевірте поновлення без зміни активних сертифікатів:
sudo certbot renew --dry-run
sudo nginx -t
curl -I https://site1.com
curl -I https://site2.com
Тримайте порти 80 і 443 відкритими, оскільки для поновлення сертифікатів HTTP-01 потрібен порт 80, якщо ви не використовуєте перевірку DNS.
Крок 7: Додайте ізоляцію PHP-FPM і користувачів бази даних
Для кількох незалежних PHP-застосунків окремі пули PHP-FPM зменшують міжсайтовий доступ і спрощують застосування лімітів ресурсів. Створіть пул для site1:
sudo nano /etc/php/8.3/fpm/pool.d/site1.conf[site1]
user = site1
group = site1
listen = /run/php/site1.sock
listen.owner = www-data
listen.group = www-data
pm = dynamic
pm.max_children = 12
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 4
php_admin_value[open_basedir] = /var/www/site1.com:/tmp
Створіть системного користувача та повторіть налаштування пулу зі значеннями для site2:
sudo useradd --system --home /var/www/site1.com --shell /usr/sbin/nologin site1
sudo chown -R site1:site1 /var/www/site1.com
sudo systemctl restart php8.3-fpm
sudo systemctl status php8.3-fpm --no-pager
Змініть PHP-рядок Nginx для site1 на fastcgi_pass unix:/run/php/site1.sock;. Не встановлюйте pm.max_children надто високим: практичною початковою точкою є від 2 до 4 воркерів на ГБ RAM, доступної для PHP, а потім скоригуйте значення після вимірювання використання пам’яті воркерами.
Створюйте окремі облікові дані MariaDB замість використання root:
sudo mariadbCREATE DATABASE site1db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'site1user'@'localhost' IDENTIFIED BY 'CHANGE_THIS_LONG_PASSWORD';
GRANT ALL PRIVILEGES ON site1db.* TO 'site1user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Крок 8: Перевірте кожен вебсайт і відстежуйте журнали
Перевірте синтаксис конфігурації, статус HTTP, маршрутизацію віртуальних хостів, виконання PHP і поновлення сертифікатів:
sudo nginx -t
curl -I https://site1.com
curl -I https://site2.com
curl -s https://site1.com | head
sudo tail -f /var/log/nginx/site1.access.log /var/log/nginx/site1.error.log
Перевірте маршрутизацію імені хоста безпосередньо за адресою сервера, якщо DNS ще не готовий:
curl --resolve site1.com:80:SERVER_IP http://site1.com
curl --resolve site2.com:80:SERVER_IP http://site2.com
Відстежуйте навантаження на ресурси за допомогою:
free -h
uptime
df -h
sudo systemctl --failed
sudo journalctl -u nginx -u php8.3-fpm --since '1 hour ago'
Налаштуйте ротацію журналів, збирайте метрики CPU, RAM, затримки диска, використання диска, кодів стану HTTP і строку дії сертифікатів, а також зберігайте щонайменше одну резервну копію поза сервером. Дамп бази даних можна створити так:
sudo mysqldump --single-transaction site1db | gzip | sudo tee /var/backups/site1db-$(date +%F).sql.gz > /dev/nullУсунення поширених проблем
Кожен домен відображає той самий вебсайт
Перевірте, чи правильне кожне server_name, чи сайт увімкнено та чи видалено блок за замовчуванням. Запустіть sudo nginx -T і знайдіть дублікати імен хостів.
Nginx повертає 403 Forbidden
Переконайтеся, що кореневий каталог документів існує, каталоги мають дозвіл на виконання, а користувач Nginx може проходити шляхом:
namei -l /var/www/site1.com/public
sudo tail -n 50 /var/log/nginx/site1.error.logPHP повертає 502 Bad Gateway
Сокет PHP-FPM може бути неправильним або службу може бути зупинено. Виконайте:
ls -l /run/php/
sudo systemctl status php8.3-fpm
sudo journalctl -u php8.3-fpm -n 50 --no-pagerCertbot не може перевірити домен
Переконайтеся, що DNS вказує на цей сервер, порт 80 доступний, а Nginx завантажує правильний блок сервера. Проксі або CDN також повинні правильно переспрямовувати HTTP-запити перевірки.
Один сайт споживає всі ресурси
Перевірте журнали доступу та воркери PHP-FPM, увімкніть кешування застосунку, обмежте розміри завантажень і зменште ліміти пулу цього сайту. Для проблемних сусідів або вимог відповідності перенесіть застосунок на окремий VPS або виділений сервер.
Операційні рекомендації
- Використовуйте файли розгортання під контролем версій і перевіряйте зміни Nginx за допомогою
nginx -tперед кожним перезавантаженням. - Підтримуйте застосунки, плагіни, пакети Ubuntu та PHP в актуальному стані.
- Використовуйте окремих Unix-користувачів, бази даних, журнали та каталоги розгортання для кожного сайту.
- Увімкніть автоматизоване резервне копіювання та періодично виконуйте повну перевірку відновлення.
- Використовуйте CDN або об’єктне сховище для великих статичних ресурсів і відео, замість того щоб споживати всю пропускну здатність сервера.
- Для пошти використовуйте окрему поштову службу або сервер, якщо доставлюваність і репутація критично важливі для бізнесу.