Введение
При работе с VPS большая часть проблем возникает не из-за кода, а из-за неправильной базовой настройки сервера: путей, прав, конфигурации Nginx и SSL.
Если сразу выстроить понятную схему, добавление новых сайтов в будущем будет занимать 15–20 минут.
В этой статье показан базовый и предсказуемый процесс создания нового сайта на VPS.
Базовые требования
Перед началом предполагаем, что:
- VPS с Ubuntu уже настроен
- установлен Nginx
- установлен PHP-FPM
- домен куплен и доступен
- A-запись домена указывает на IP сервера
Проверка DNS, в терминале на вашем компьютере:
1ping example.com
IP должен совпадать с IP сервера.
Обратите внимание
В примерах используется example и example.com. Перед применением команд и конфигураций замените их на имя вашей папки и ваш домен во всех местах.
0. Подготовка пользователя
Перед созданием сайтов имеет смысл один раз настроить отдельного пользователя, который будет:
- отвечать за автодеплой из GitHub;
- иметь доступ к директориям сайтов;
- не иметь прав администратора.
В этой статье для этого используется пользователь deploy.
Это позволяет:
- не работать с кодом под root или admin;
- дальше создавать новые сайты без ручной настройки доступа.
Создание пользователя
Выполняем под admin с sudo:
1sudo adduser --disabled-password deploy
Информацию о пользователе можно пропустить (Enter).
После этого пользователь существует, но войти по паролю нельзя.
Настраиваем вход по SSH ключу
Создаём каталог для ключей:
1sudo -u deploy mkdir -p /home/deploy/.ssh
2sudo -u deploy chmod 700 /home/deploy/.ssh
Добавляем публичный ключ:
1sudo -u deploy nano /home/deploy/.ssh/authorized_keys
Вставь туда свой public key.
Настраиваем права:
1sudo chmod 600 /home/deploy/.ssh/authorized_keys
2sudo chown -R deploy:deploy /home/deploy/.ssh
После этого вход возможен только по ключу.
Добавляем deploy в группу
Группа www-data используется веб-сервером (nginx + PHP-FPM).
Через неё мы будем управлять доступом к файлам сайтов.
1sudo usermod -aG www-data deploy
Настраиваем директорию для наследования прав
Теперь настраиваем /var/www так, чтобы все новые папки внутри автоматически получали группу www-data.
1sudo chown root:www-data /var/www
2sudo chmod 2775 /var/www
Что здесь происходит:
- владельцем остаётся
root(инфраструктура); - группа —
www-data; 2(setgid) включает наследование группы;775даёт группе право на создание новых сайтов.
Дальнейшие каталоги сайтов будут дополнительно ограничены.
Настраиваем umask
Чтобы файлы, создаваемые пользователем deploy во время деплоя, корректно работали в runtime-директориях (логи, кеш, сессии) и не вызывали проблем с правами, задаём umask.
Открываем профиль пользователя:
1nano /home/deploy/.profile
Добавляем в конец:
1umask 0002
Это обеспечит:
- новые файлы:
664 - новые директории:
775
Такие права позволяют веб-серверу работать с файлами в каталогах, где запись разрешена (storage, cache, uploads), и не влияют на безопасность сервера.
Даже при корректно настроенных правах одна команда во время деплоя может создать файл с ограниченным доступом.
В этом случае веб-сервер не сможет его прочитать, и сайт начнёт отдавать ошибки.
umask выполняет роль дополнительной страховки, предотвращая подобные ситуации и делая деплой предсказуемым.
Настройка пользователя выполняется один раз
После этого пользователь deploy полностью готов для работы с сайтами.
1. Создание папки сайта
После подготовки пользователя новые сайты можно создавать без ручной настройки владельцев и групп.
Создаём директорию проекта от имени deploy:
1sudo -u deploy mkdir -p /var/www/example
По умолчанию каталог создаётся с правами 2775, так как наследует группу и umask пользователя.
Для продакшн-проекта доступ на запись для группы в корне сайта не требуется, поэтому ограничиваем права:
1sudo chmod 2755 /var/www/example
Создаем для проверки файл index.html:
1sudo -u deploy sh -c 'echo "OK" > /var/www/example/index.html'
Позже этот файл можно удалить — он используется только для проверки базовой работы Nginx.
2. Создание HTTP конфига Nginx
Создаём файл:
1sudo nano /etc/nginx/sites-available/example
Минимальный шаблон:
1server {
2 listen 80;
3 server_name example.com www.example.com;
4
5 root /var/www/example;
6 index index.php index.html index.htm;
7
8 location / {
9 try_files $uri $uri/ /index.php?$query_string;
10 }
11
12 location ~ \.php$ {
13 include snippets/fastcgi-php.conf;
14 fastcgi_pass unix:/run/php/php8.4-fpm.sock;
15 }
16
17 location ~ /\.(?!well-known).* {
18 deny all;
19 }
20}
Примечание:
include snippets/fastcgi-php.conf;
Файл snippets/fastcgi-php.conf присутствует в стандартных установках Ubuntu/Debian.
В других дистрибутивах он может отсутствовать или находиться в другом месте.
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
Версия PHP и путь к сокету могут отличаться в зависимости от сервера.
Перед использованием проверьте доступные сокеты командой: ls /run/php/
3. Активация сайта
Включаем конфиг:
1sudo ln -s /etc/nginx/sites-available/example /etc/nginx/sites-enabled/
Сначала проверяем конфигурацию на ошибки:
1sudo nginx -t
Если ошибок нет и вывод содержит сообщение ... syntax is ok и ... test is successful, применяем изменения:
1sudo systemctl reload nginx
4. Проверка HTTP
В браузере переходим на свой сайт: http://example.com
Должно показаться OK.
Если нет — сначала исправляем это, и только потом переходим к SSL.
5. Получение SSL сертификата
Устанавливаем сертификат через Certbot:
1sudo certbot --nginx -d example.com -d www.example.com
Certbot автоматически:
- получит сертификат
- подключит его
- добавит редиректы
- создаст HTTPS-конфиг
6. Приведение конфигурации в порядок
После Certbot файл конфига нужно привести в чистый вид.
Открываем:
1sudo nano /etc/nginx/sites-available/example
Финальный шаблон:
1server {
2 listen 443 ssl http2;
3 server_name example.com;
4
5 root /var/www/example;
6 index index.php index.html index.htm;
7
8 location / {
9 try_files $uri $uri/ /index.php?$query_string;
10 }
11
12 location ~ \.php$ {
13 include snippets/fastcgi-php.conf;
14 fastcgi_pass unix:/run/php/php8.4-fpm.sock;
15 }
16
17 location ~ /\.(?!well-known).* {
18 deny all;
19 }
20
21 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
22 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
23 include /etc/letsencrypt/options-ssl-nginx.conf;
24 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
25}
26
27server {
28 listen 443 ssl http2;
29 server_name www.example.com;
30
31 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
32 ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
33 include /etc/letsencrypt/options-ssl-nginx.conf;
34 ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
35
36 return 301 https://example.com$request_uri;
37}
38
39server {
40 listen 80;
41 server_name example.com www.example.com;
42 return 301 https://example.com$request_uri;
43}
Если сайт использует роутинг через
index.php
(например WordPress, фреймворк или самописный роутер), необходимо использовать:
try_files $uri $uri/ /index.php?$query_string;
Если же сайт работает по принципу “файл = страница”
(без маршрутизации), лучше использовать:
try_files $uri $uri/ =404;
Применяем:
1sudo nginx -t
2sudo systemctl reload nginx
7. Финальная проверка
В браузере переходим на свой сайт: https://example.com.
Должен открываться без ошибок и редиректов.
Итог
Этот процесс позволяет:
- быстро создавать новые сайты
- не ломать существующие
- поддерживать порядок в /var/www
- легко масштабироваться
При такой структуре добавление нового проекта сводится к копированию шаблона и замене имён и путей — без ручной магии и неожиданных багов.
Смотрите также
- Настройка Nginx для Laravel — подробный разбор конфигурации Nginx для PHP-фреймворка