Как разместить сайт на VPS: nginx с нуля
Сайт на своём сервере — это папка с файлами и короткий файл настроек nginx. Ниже — весь путь от чистого сервера до работающего сайта с HTTPS: направить домен, поставить nginx, описать сайт, проверить настройки, выпустить сертификат и оставить один главный адрес. Команды — для Ubuntu 24.04 и 26.04.
Содержание 16
- Что понадобится
- 1. Направьте домен на сервер
- 2. Поставьте nginx
- 3. Создайте папку для сайта
- 4. Опишите сайт в настройках nginx
- 5. Проверьте и примените настройки
- 6. Загрузите файлы сайта
- 7. Включите HTTPS
- 8. Оставьте один адрес: с www или без
- Несколько сайтов на одном сервере
- Если сайт — приложение на Node.js или Python
- Если сайт на PHP
- Где смотреть ошибки
- Кому что
- Частые ошибки
- Что почитать дальше
Что понадобится
- Сервер на Ubuntu 24.04 или 26.04, на который вы заходите по SSH под своим пользователем с правами sudo. Если сервер только что куплен, сначала сделайте первые шаги настройки: пользователь, вход по ключу, фаервол.
- Домен. Пока его нет, сайт можно проверить по IP-адресу сервера.
- Файлы сайта — HTML-страницы, картинки, стили. Если сайт — это приложение на Node.js или Python либо он написан на PHP, для него ниже есть отдельные разделы.
Если нужен сайт на WordPress и следить за сервером не хочется, проще взять обычный хостинг: веб-сервер и PHP там уже настроены. Подробнее — в статье Чем VPS отличается от обычного хостинга.
Если сайтов несколько и настраивать каждый командами не хочется, поставьте на сервер панель управления: сайты, базы данных и сертификаты в ней добавляют через браузер. Ставят её только на чистую систему, поэтому решите до начала: панель или эта инструкция. Какие панели бывают и сколько они стоят, разобрано в статье Панель управления хостингом и VPS.
Во всех командах ниже вместо example.ru подставьте свой домен, а вместо ВАШ_IP — IP-адрес сервера.
1. Направьте домен на сервер
Начните с DNS: пока записи расходятся, вы успеете настроить сервер. В редакторе DNS — у хостера, регистратора или в DNS-сервисе, смотря чьи DNS-серверы указаны у домена, — добавьте две записи:
| Имя | Тип | Значение |
|---|---|---|
| @ (сам домен) | A | IP-адрес сервера |
| www | A | тот же IP-адрес |
Для www вместо A-записи можно поставить CNAME на сам домен. Если у сервера есть IPv6-адрес, добавьте для обоих имён и записи AAAA: настройки nginx ниже принимают запросы по обоим протоколам. Что это за записи и где их меняют у Timeweb и Beget, разобрано в статье Что такое домен.
Если у домена уже была A-запись с другим адресом, часть посетителей ещё какое-то время будет попадать на старый — пока не истечёт TTL старой записи. Проверить можно со своего компьютера: команда nslookup example.ru должна показать IP вашего сервера.
2. Поставьте nginx
sudo apt update
sudo apt install nginxЕсли apt спросит, продолжать ли, ответьте Y. nginx запустится сразу после установки и дальше будет стартовать сам при каждой загрузке сервера. Проверьте, что он работает:
sudo systemctl status nginxВ ответе должно быть active (running). Если ответ не поместился на экран, выйти из него можно клавишей Q. Теперь откройте в браузере http://ВАШ_IP — появится страница «Welcome to nginx!». Это сайт по умолчанию: его файлы лежат в папке /var/www/html.
Из репозитория Ubuntu 24.04 ставится nginx 1.24, в Ubuntu 26.04 — nginx 1.28. Узнать версию можно командой nginx -v.
Если страница не открывается, проверьте фаервол командой sudo ufw status. Ответ Status: inactive значит, что ufw выключен и дело не в нём. Если вы включали его по нашей инструкции, порты 80 и 443 уже открыты. Если их нет в списке, откройте оба сразу — вместе с nginx в ufw появляется готовый профиль:
sudo ufw allow 'Nginx Full'3. Создайте папку для сайта
Файлы каждого сайта удобно держать в своей папке внутри /var/www. Сама /var/www принадлежит root, поэтому папку создаём через sudo и сразу отдаём своему пользователю — тогда загружать файлы можно будет без sudo:
sudo mkdir -p /var/www/example.ru
sudo chown -R $USER:$USER /var/www/example.ruВместо $USER оболочка сама подставит имя пользователя, под которым вы зашли. Положите в папку пробную страницу — по ней будет видно, что nginx отдаёт именно ваш сайт:
echo '<!doctype html><meta charset="utf-8"><h1>Сайт работает</h1>' > /var/www/example.ru/index.htmlnginx работает от имени системного пользователя www-data, и ему нужно право читать файлы сайта и заходить в его папки. В /var/www оно обычно есть. А домашняя папка для сайта не подходит: в Ubuntu 24.04 новые домашние папки создаются с правами 750, чужие пользователи, в том числе www-data, внутрь не попадают, и сайт не откроется.
4. Опишите сайт в настройках nginx
Каждый сайт описывается своим блоком server, и в Ubuntu его принято держать в отдельном файле. Такие файлы лежат в папке /etc/nginx/sites-available, а работают только те, на которые есть ссылка в /etc/nginx/sites-enabled. Создайте файл сайта:
sudo nano /etc/nginx/sites-available/example.ruВставьте в него:
server {
listen 80;
listen [::]:80;
server_name example.ru www.example.ru;
root /var/www/example.ru;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}Сохраните: Ctrl+O, Enter, Ctrl+X. Что значат строки:
| Строка | Что делает |
|---|---|
listen 80; и listen [::]:80; | принимать запросы на порту 80 по IPv4 и по IPv6 |
server_name | имена, на которые отвечает сайт; первое считается основным |
root | папка с файлами. nginx прибавляет к ней адрес из запроса: /css/style.css превратится в /var/www/example.ru/css/style.css |
index | какой файл отдать, если запрошена папка — например, главная страница / |
location / | настройки для всех адресов сайта, у которых нет своего, более точного блока location |
try_files $uri $uri/ =404; | искать файл, потом папку с таким именем, а если нет ни того, ни другого — ответить 404 |
Включите сайт ссылкой и уберите ссылку на сайт по умолчанию:
sudo ln -s /etc/nginx/sites-available/example.ru /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/defaultУдаляется только ссылка: сам файл default остаётся в sites-available как образец — в комментарии к нему сказано, что обычно так и делают. Если ссылку оставить, на запросы по IP и по чужим именам будет отвечать приветственная страница nginx.
5. Проверьте и примените настройки
Перед каждым применением проверяйте настройки:
sudo nginx -tЕсли всё в порядке, ответ будет таким:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulЕсли есть ошибка, nginx опишет её, назовёт файл и номер строки, а в конце напишет test failed. Например, если забыть точку с запятой в конце строки, в описании будет invalid number of arguments или is not terminated by ";", а при лишней фигурной скобке — unexpected "}". Когда проверка прошла, примените настройки:
sudo systemctl reload nginxОткройте http://example.ru или, пока записи DNS не разошлись, http://ВАШ_IP — должна появиться пробная страница «Сайт работает».
Команда reload применяет новые настройки, не останавливая nginx: начатые запросы дообслуживаются, а если новые настройки не примутся, nginx продолжит работать на старых. А restart сначала останавливает nginx, и при ошибке в настройках сайт не поднимется. Поэтому после каждой правки — пара команд: sudo nginx -t, затем sudo systemctl reload nginx.
6. Загрузите файлы сайта
Теперь замените пробную страницу своими файлами. Главная страница должна лежать прямо в папке сайта, то есть по адресу /var/www/example.ru/index.html, а не во вложенной папке. С Mac и Linux содержимое папки site с вашего компьютера копируется так — команду запускайте в Терминале из папки, в которой лежит site:
scp -r site/* ivan@ВАШ_IP:/var/www/example.ru/Вместо ivan — ваш пользователь на сервере. Звёздочка после site/ означает «всё, что внутри», кроме скрытых файлов, имена которых начинаются с точки. Без неё на сервере появится лишняя вложенная папка site. В Windows удобнее программы WinSCP или FileZilla: подключитесь по SFTP и перетащите файлы в /var/www/example.ru. Как работать с scp и этими программами — в статье Как подключиться к VPS по SSH.
7. Включите HTTPS
Когда сайт открывается по домену через http://, выпустите для него бесплатный сертификат Let's Encrypt программой Certbot. Порт 80 должен быть открыт: через него Certbot подтверждает домен. Разработчики Certbot советуют ставить его через snap:
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/local/bin/certbot
sudo certbot --nginx -d example.ru -d www.example.ruCertbot получит сертификат сразу на оба имени и сам пропишет его в настройки nginx. По умолчанию он включает и переадресацию с http:// на https://. Файлы сертификата лягут в папку /etc/letsencrypt/live/example.ru/ — она названа по первому домену из команды. Сертификат продлевается сам; проверить, что продление работает, можно командой sudo certbot renew --dry-run. Подробности и что делать, если замка в браузере нет, — в статье Бесплатный SSL-сертификат.
8. Оставьте один адрес: с www или без
Для Яндекса example.ru и www.example.ru — разные сайты, и пока робот не объединит их, они могут конкурировать в поиске. Какой из двух адресов главный, Яндексу всё равно. Чтобы объединение прошло быстрее, выберите главный и настройте переадресацию с каждой страницы второго адреса на такую же страницу главного (справка Яндекса).
Допустим, главный — адрес без www. Откройте файл сайта командой sudo nano /etc/nginx/sites-available/example.ru и найдите блок server со строками ssl_certificate — в нём Certbot подключил сертификат. В строке server_name этого блока оставьте только основное имя:
server_name example.ru;А в конец файла добавьте отдельный блок для www:
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name www.example.ru;
ssl_certificate /etc/letsencrypt/live/example.ru/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.ru/privkey.pem;
return 301 https://example.ru$request_uri;
}Код 301 означает, что адрес сменился насовсем. $request_uri — это путь к странице вместе с параметрами, поэтому www.example.ru/kontakty/ откроется как example.ru/kontakty/, а не как главная. Проверьте и примените настройки: sudo nginx -t, затем sudo systemctl reload nginx.
Если главным хотите адрес с www, поменяйте имена местами: в основном блоке оставьте www.example.ru, а в блоке для переадресации — example.ru и return 301 https://www.example.ru$request_uri;.
Проверьте все четыре варианта: http:// и https://, с www и без. Каждый должен в итоге привести на главный адрес. С Mac или Linux удобно проверять командой curl -I https://www.example.ru: в ответе будет код 301 и новый адрес в строке Location. Ответ 301 браузер может запомнить, поэтому, если ошиблись и исправили, проверяйте в новом окне инкогнито.
Затем сообщите главный адрес Яндексу. Добавьте оба адреса — с www и без — в Вебмастер и подтвердите права. Выберите адрес, с которого переезжаете, и откройте «Индексирование» → «Переезд сайта». Если главный адрес без www, опцию «Добавить WWW» выключите, если с www — включите, и нажмите «Сохранить». Смена главного адреса в поиске занимает несколько недель.
Несколько сайтов на одном сервере
Для второго сайта повторите шаги 1 и 3–8: свои записи DNS, своя папка в /var/www, свой файл в sites-available со ссылкой в sites-enabled и свой сертификат. Ссылку default второй раз удалять не нужно. Все сайты принимают запросы на одних и тех же портах 80 и 443 — разные порты не нужны. nginx выбирает сайт по имени, которое браузер передаёт в запросе, в заголовке Host.
Если имя не совпало ни с одним server_name или запрос пришёл просто по IP, ответит сайт по умолчанию: тот, у которого в строке listen стоит default_server, а если такого нет — первый в настройках (документация nginx). Одно и то же имя не должно стоять в двух блоках на одном порту: запросы с ним пойдут в первый блок, а nginx предупредит conflicting server name.
Если сайт — приложение на Node.js или Python
Такое приложение обычно само принимает запросы на своём порту, например 3000. nginx ставят перед ним: он принимает посетителей на портах 80 и 443 и передаёт запросы приложению. В основном блоке server замените location / таким:
location / {
proxy_pass http://127.0.0.1:3000;
include proxy_params;
}Вместо 3000 — порт вашего приложения. Файл proxy_params ставится вместе с nginx в Ubuntu: с ним приложение получает исходное имя сайта, IP-адрес посетителя и протокол — http или https. Открывать порт 3000 в фаерволе не нужно: nginx обращается к приложению изнутри сервера, а само приложение лучше настроить на адрес 127.0.0.1, чтобы снаружи до него нельзя было достучаться в обход nginx.
Если приложение не запущено, посетители увидят ошибку 502. Чтобы оно работало постоянно и поднималось после перезагрузки сервера, его обычно запускают как службу systemd.
Если сайт на PHP
nginx сам PHP не выполняет: он передаёт такие запросы отдельной программе — PHP-FPM. Её и ставим:
sudo apt install php-fpmПакет php без уточнений лучше не ставить. В Ubuntu 24.04 он через пакет php8.3 требует одно из трёх: модуль PHP для Apache, PHP-FPM или CGI. Модуль Apache в этом списке первый, а сам он зависит от Apache и рекомендует поставить его целиком. Так на сервер может попасть второй веб-сервер, который будет спорить с nginx за порт 80.
PHP-FPM принимает запросы через файл-сокет, и его имя зависит от версии PHP. Посмотрите его:
ls /run/php/В Ubuntu 24.04 это php8.3-fpm.sock, в 26.04 — php8.5-fpm.sock. Теперь откройте файл сайта и в основном блоке server замените строку index и добавьте блок для PHP:
index index.php index.html;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}В Ubuntu 26.04 в строке fastcgi_pass укажите php8.5-fpm.sock. Файл snippets/fastcgi-php.conf тоже ставится вместе с nginx. В нём уже собраны настройки, которые нужны PHP, в том числе проверка, что запрошенный файл .php существует, — если его нет, nginx ответит 404, не обращаясь к PHP. Проверьте и примените настройки: sudo nginx -t, затем sudo systemctl reload nginx. Если сервер потом перейдёт с Ubuntu 24.04 на 26.04, строку fastcgi_pass придётся поменять (что проверить после перехода).
Создайте пробный файл и откройте в браузере адрес example.ru/test.php:
echo '<?php echo "PHP работает";' > /var/www/example.ru/test.phpЕсли видите «PHP работает», всё настроено. Если браузер вместо этого скачивает файл, запрос не дошёл до PHP и nginx отдал файл как есть: проверьте блок location и не забыли ли вы reload. Пробный файл после проверки удалите:
rm /var/www/example.ru/test.phpДля WordPress на VPS понадобятся ещё база данных MySQL или MariaDB и модули PHP. Если не хочется настраивать всё это самому, посмотрите хостинг для WordPress.
Где смотреть ошибки
Если что-то не работает, первым делом загляните в журнал ошибок nginx:
sudo tail -n 20 /var/log/nginx/error.logКоманда покажет 20 последних строк. В каждой — время и суть ошибки, а если ошибка случилась при обработке запроса, то и сам запрос. Рядом лежит журнал всех запросов — /var/log/nginx/access.log: в нём видно каждый запрошенный адрес и код ответа. Оба журнала закрыты от посторонних пользователей, поэтому смотрите их через sudo. Если nginx не запускается совсем, причину покажет sudo systemctl status nginx. Что значат самые частые записи — в разделе «Частые ошибки» ниже.
Если сайт работал и вдруг перестал открываться, проверьте ещё место на диске, память и упавшие службы — команды для этого собраны в статье Что делать, если хостинг лежит.
Кому что
- Статичный сайт, лендинг, документация — подойдёт и недорогой VPS: nginx просто отдаёт готовые файлы.
- Приложение на Node.js или Python — nginx перед приложением, как в разделе выше.
- WordPress или интернет-магазин на CMS — если администрировать сервер не хочется, проще хостинг для WordPress или хостинг для интернет-магазина.
- Сервер ещё не выбран — посмотрите цены в рейтинге VPS. У VPS в Timeweb Cloud есть консоль, которая работает, даже если SSH сломан. У VPS от Beget в панели есть терминал и файловый менеджер.
Частые ошибки
| Что случилось | В чём обычно дело |
|---|---|
| Вместо сайта — «Welcome to nginx!» | Запрос попал на сайт по умолчанию: вы открываете сайт по IP, а ссылка default не убрана; имя в server_name не совпадает с адресом в браузере; нет ссылки в sites-enabled или не выполнен sudo systemctl reload nginx |
| Открывается старый сайт или ничего | Записи DNS ещё не разошлись или указывают не туда. Проверьте командой nslookup example.ru |
Ошибка 403, в журнале directory index of "…" is forbidden | В папке нет файла из строки index — например, index.html лежит во вложенной папке |
Ошибка 403 или 404, в журнале Permission denied | nginx не может прочитать файл или зайти в папку. Если сайт лежит в домашней папке, перенесите его в /var/www. Если в /var/www — откройте файлы на чтение: sudo chmod -R a+rX /var/www/example.ru |
| Ошибка 404 | Файла по этому пути нет. Проверьте строку root и регистр букв: Index.html и index.html для сервера — разные файлы. С настройками из этой статьи такие запросы в журнал ошибок не попадают — ищите их в /var/log/nginx/access.log |
| Ошибка 502 Bad Gateway | nginx не достучался до приложения или PHP-FPM: в журнале connect() и while connecting to upstream. Приложение не запущено, слушает другой порт или в fastcgi_pass не тот сокет |
| Ошибка 504 | Приложение или PHP не ответили вовремя: в журнале upstream timed out |
| Ошибка 413 при загрузке файла | Файл больше, чем разрешает nginx, — по умолчанию 1 МБ. Добавьте в блок server строку client_max_body_size 20m;, указав нужный размер |
| Скачивается файл .php вместо страницы | Нет блока location для PHP или не выполнен reload |
could not build server_names_hash | Слишком длинное имя сайта. В блоке http файла /etc/nginx/nginx.conf задайте server_names_hash_bucket_size вдвое больше числа в конце сообщения: если там 64 — 128. Строка там уже есть, только закомментирована решёткой |
conflicting server name, ignored | Одно имя стоит в двух блоках на одном порту, и запросы с ним идут в первый. Так бывает, если на шаге 8 не убрать www из основного блока. Оставьте имя в одном блоке |
a duplicate default server | default_server указан у двух сайтов на одном порту, и nginx не примет настройки. Оставьте один |
bind() to 0.0.0.0:80 failed (98: Address already in use) | Порт 80 занят другой программой, например Apache, а nginx -t этого не замечает. Кто держит порт, покажет sudo ss -ltnp. Если это Apache: sudo systemctl stop apache2, sudo systemctl disable apache2, затем sudo systemctl start nginx |
| Домен .рф открывает не тот сайт | В server_name имя записано кириллицей, а nginx ждёт Punycode — вида xn--. Как перевести имя, разобрано в статье Что такое домен |
Что почитать дальше
- Как настроить VPS с нуля — что сделать до сайта: пользователь, вход по ключу, фаервол.
- Как подключиться к VPS по SSH — вход с Windows, Mac и Linux и передача файлов на сервер.
- Резервные копии сайта — ежедневная копия файлов и базы сайта скриптом и cron.
- Бесплатный SSL-сертификат — подробно про Certbot, продление и замок в браузере.
- Что такое домен — записи A и CNAME, TTL и проверка домена командой nslookup.
- Рейтинг VPS 2026 — если сервер ещё не выбран: цены семи провайдеров.
- Хостинг для WordPress — если проще обойтись без своего сервера.
- Хостинг для Python и Node.js — где приложение запустится без своего сервера и когда без VPS не обойтись.
- Как перенести сайт на другой хостинг без простоя — если сайт переезжает со старого хостинга.
- Что делать, если хостинг лежит — если сайт перестал открываться: диск, память, упавшие службы и авария у провайдера.
- Панель управления хостингом и VPS — если сайтов несколько и настраивать их удобнее в браузере: FASTPANEL, HestiaCP и ispmanager.
Проверено и обновлено: 01.10.2026