Как развернуть статический или PHP-сайт на Nginx (server block)
Запустить на сервере одной командой (сначала проверьте содержимое скрипта ниже):
curl -sSL https://cp.lv/scripts/razvernut-sajt-na-nginx.sh | sudo bash…или через wget:
wget -qO- https://cp.lv/scripts/razvernut-sajt-na-nginx.sh | sudo bashСодержимое скрипта razvernut-sajt-na-nginx.sh:
#!/usr/bin/env bash
set -e
# 1. Каталог сайта и права
sudo mkdir -p /var/www/example.com
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
echo "<h1>example.com работает</h1>" | sudo tee /var/www/example.com/index.html > /dev/null
# 2. server block (кавычки 'EOF' — переменные Nginx не трогаем)
sudo tee /etc/nginx/sites-available/example.com > /dev/null << 'EOF'
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
location ~* \.(jpg|jpeg|png|webp|css|js|woff2)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
}
EOF
# 3. Активация сайта и отключение дефолтного конфига
sudo ln -sf /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/example.com
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo systemctl reload nginx
echo "Сайт развёрнут: откройте http://example.com"
Чтобы Nginx обслуживал ваш сайт, ему нужно описать «виртуальный хост» — server block: где лежат файлы, какой домен обслуживать и как обрабатывать запросы. Ниже — рабочая схема и для статики, и для PHP.
Шаг 1. Подготовка каталога сайта
Разместите файлы сайта в отдельной директории и назначьте владельцем веб-пользователя www-data:
sudo mkdir -p /var/www/example.com
sudo chown -R www-data:www-data /var/www/example.com
sudo chmod -R 755 /var/www/example.com
Загрузите файлы (например, через rsync или git clone). Для проверки создайте стартовую страницу:
echo "<h1>example.com работает</h1>" | sudo tee /var/www/example.com/index.html
Шаг 2. Server block для статического сайта
Откройте /etc/nginx/sites-available/example.com в редакторе:
sudo nano /etc/nginx/sites-available/example.com
Содержимое файла:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
location ~* \.(jpg|jpeg|png|webp|css|js|woff2)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
}
Либо создайте конфиг целиком одной командой — скопируйте и вставьте в консоль (кавычки 'EOF' важны, чтобы переменные Nginx $uri остались как есть):
sudo tee /etc/nginx/sites-available/example.com > /dev/null << 'EOF'
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
location / {
try_files $uri $uri/ =404;
}
location ~* \.(jpg|jpeg|png|webp|css|js|woff2)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
}
EOF
Директива try_files ... =404 отдаёт файл, если он существует, иначе честную 404. Блок с expires включает кэширование статики в браузере.
Шаг 3. Вариант для PHP-сайта
Если сайт на PHP, добавьте обработку через PHP-FPM и index.php. Откройте тот же файл в редакторе (sudo nano /etc/nginx/sites-available/example.com) и приведите его к виду:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.php index.html;
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;
}
}
Либо запишите PHP-вариант целиком одной командой (кавычки 'EOF' важны, чтобы переменные Nginx $uri остались как есть):
sudo tee /etc/nginx/sites-available/example.com > /dev/null << 'EOF'
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.php index.html;
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;
}
}
EOF
Здесь try_files с фолбэком на /index.php — стандарт для CMS и фреймворков с ЧПУ (WordPress, Laravel).
Шаг 4. Активация и проверка
Включите сайт символической ссылкой, проверьте синтаксис и перезагрузите:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
nginx -t должен ответить syntax is ok и test is successful. Если нет — ошибка укажет файл и строку.
Шаг 5. Отключение дефолтного сайта
Чтобы Nginx не отдавал заглушку по умолчанию, снимите дефолтный конфиг:
sudo rm /etc/nginx/sites-enabled/default
sudo systemctl reload nginx
Типовые ошибки
| Симптом | Причина | Решение |
|---|---|---|
| 403 Forbidden | нет прав на файлы | chown www-data и chmod 755 |
| 404 на всех URL | неверный root |
проверьте путь к каталогу |
| PHP скачивается файлом | нет блока location ~ \.php$ |
добавьте обработку FPM |
| Открывается чужой сайт | не отключён default |
удалите дефолтный конфиг |
Шаг 6. Логи для диагностики
Если что-то не работает, смотрите лог ошибок конкретного сайта:
sudo tail -f /var/log/nginx/example.com.error.log
Частые вопросы
Чем server block отличается от virtual host в Apache?
Это то же самое понятие — описание отдельного сайта. В Nginx один блок server { } = один виртуальный хост.
Нужно ли перезапускать Nginx после каждой правки?
Достаточно systemctl reload nginx — он применит конфиг без разрыва активных соединений. Полный restart нужен редко.
Как разместить несколько сайтов на одном сервере?
Создайте отдельный файл в sites-available для каждого домена с уникальным server_name и root, затем включите ссылками в sites-enabled.
Почему браузер показывает старую версию страницы?
Сработал кэш из блока expires. Сбросьте кэш браузера или временно уменьшите срок кэширования при разработке.
После развёртывания добавьте HTTPS — Nginx отлично работает с сертификатами Let’s Encrypt. Под боевые сайты подойдут тарифы на странице аренда VPS, а для CMS — VPS для WordPress.
