Введение
При работе с VPS большая часть проблем возникает не из-за кода приложения, а из-за некорректной базовой настройки сервера: путаницы с владельцами файлов, небезопасных прав доступа, разрозненных конфигураций веб-сервера и ошибок при выпуске SSL.
- Проблема: запуск проектов под
root, ручное переопределение прав после каждого деплоя и хаотичные конфигурации Nginx приводят к отказам в доступе, сбоям автодеплоя и уязвимостям. - Решение: настроить выделенного пользователя
deployс наследованием группы веб-сервера, зафиксировать безопасные umask и права каталогов, а также использовать чистый стандартизированный шаблон конфигурации Nginx. - Результат: предсказуемая инфраструктура, в которой развертывание каждого нового сайта занимает не более 15 минут без вмешательства в работу соседних проектов.
Требования
Перед началом убедитесь, что:
- VPS под управлением Ubuntu/Debian настроен и доступен по SSH;
- установлены Nginx и PHP-FPM;
- домен делегирован, а его A-запись указывает на публичный IP сервера.
Проверить доступность DNS-записи можно командой в локальном терминале:
ping example.com
IP-адрес в ответе должен строго совпадать с адресом вашего сервера.
Обратите внимание
1. Подготовка пользователя deploy
Для изоляции процессов деплоя от административных прав заводится системный пользователь deploy. Он отвечает за работу с файлами проекта и автоматизацию деплоя, но лишен привилегий root.
1.1. Создание пользователя и SSH-доступа
Выполняем команды под пользователем с правами sudo:
sudo adduser --disabled-password deploy
Запрос персональных данных можно пропустить клавишей Enter. Вход по паролю для пользователя будет отключен.
Настраиваем авторизацию по публичному SSH-ключу:
sudo -u deploy mkdir -p /home/deploy/.ssh
sudo -u deploy chmod 700 /home/deploy/.ssh
sudo -u deploy nano /home/deploy/.ssh/authorized_keys
Вставьте ваш публичный ключ в файл authorized_keys, сохраните изменения и задайте корректные права:
sudo chmod 600 /home/deploy/.ssh/authorized_keys
sudo chown -R deploy:deploy /home/deploy/.ssh
1.2. Настройка прав и umask
Добавляем пользователя в группу веб-сервера www-data:
sudo usermod -aG www-data deploy
Настраиваем каталог /var/www так, чтобы все новые вложенные директории автоматически наследовали группу www-data:
sudo chown root:www-data /var/www
sudo chmod 2775 /var/www
Для предотвращения конфликтов прав при деплое фиксируем umask пользователя deploy. Открываем профиль:
nano /home/deploy/.profile
Добавляем в конец файла:
umask 0002
Это обеспечит создание файлов с правами 664 и директорий с 775, позволяя PHP-FPM без проблем перезаписывать кэш и загружаемые файлы в разрешенных папках.
Разовая операция
2. Создание директории проекта
Новые сайты создаются от имени пользователя deploy:
sudo -u deploy mkdir -p /var/www/example
Каталог создается с наследованием группы www-data. Для безопасности в продакшене убираем лишнее право на запись группы в корне проекта:
sudo chmod 2755 /var/www/example
Создаем тестовый файл для проверки отдачи статики:
sudo -u deploy sh -c 'echo "OK" > /var/www/example/index.html'
3. Настройка HTTP-конфигурации Nginx
Создаем конфигурационный файл виртуального хоста в каталоге доступных сайтов:
sudo nano /etc/nginx/sites-available/example
Вставляем базовую конфигурацию для работы по протоколу HTTP:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
}
location ~ /\.(?!well-known).* {
deny all;
}
}
Путь к сокету PHP-FPM зависит от установленной версии PHP на сервере. Проверить активные сокеты можно командой
ls /run/php/.
4. Активация виртуального хоста
Активируем конфигурацию через символическую ссылку в каталог активных сайтов:
sudo ln -s /etc/nginx/sites-available/example /etc/nginx/sites-enabled/
Проверяем синтаксис конфигурационных файлов:
sudo nginx -t
После вывода строк syntax is ok и test is successful перезагружаем веб-сервер:
sudo systemctl reload nginx
Открываем сайт в браузере: http://example.com. Должно отобразиться сообщение OK. Переходить к настройке SSL следует только после успешного HTTP-ответа.
5. Выпуск SSL-сертификата
Для автоматического выпуска и установки бесплатного сертификата Let’s Encrypt запускаем Certbot:
sudo certbot --nginx -d example.com -d www.example.com
Утилита запросит email для уведомлений об окончании срока действия, проверит доступность доменов и скорректирует файл конфигурации Nginx.
6. Приведение конфигурации Nginx к стандарту
После работы Certbot конфигурацию стоит привести к аккуратному, легко читаемому виду:
sudo nano /etc/nginx/sites-available/example
Итоговый оптимизированный шаблон:
server {
listen 443 ssl http2;
server_name example.com;
root /var/www/example;
index index.php index.html index.htm;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
}
location ~ /\.(?!well-known).* {
deny all;
}
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
listen 443 ssl http2;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
return 301 https://example.com$request_uri;
}
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
Тестируем и применяем обновленную конфигурацию:
sudo nginx -t
sudo systemctl reload nginx
7. Финальная проверка работы
Откройте сайт в браузере по защищенному адресу: https://example.com.
Убедитесь, что:
- Запрос
http://example.comперенаправляется кодом 301 наhttps://example.com. - Запрос
https://www.example.comперенаправляется на основной домен без www. - Сертификат безопасности действителен и подписан Let’s Encrypt.
- Тестовый файл
index.htmlможно удалить, заменив его файлами реального проекта.
Вывод
Стандартизированная схема развертывания обеспечивает безопасность и скорость масштабирования:
- Безопасность: отсутствие работы под
root, жесткие права2755на корень сайта и скрытие служебных файлов.envи.git. - Предсказуемость прав: благодаря
umask 0002и группеwww-dataскрипты бэкенда и пользователь деплоя бесконфликтно работают с файлами кэша и медиа. - Чистый Nginx: канонические 301-редиректы и раздельные блоки хостов исключают дубли страниц в поисковой выдаче.
Рекомендуемые материалы
- Настройка Nginx для Laravel — разбор тонкостей конфигурации веб-сервера для современных PHP-фреймворков.
- Автодеплой из GitHub на VPS через SSH — организация автоматической доставки кода через GitHub Actions.