Ссылка скопирована

Создание сайта на VPS - пошаговая инструкция

DonVardix DonVardix

Введение

При работе с VPS большая часть проблем возникает не из-за кода приложения, а из-за некорректной базовой настройки сервера: путаницы с владельцами файлов, небезопасных прав доступа, разрозненных конфигураций веб-сервера и ошибок при выпуске SSL.

  • Проблема: запуск проектов под root, ручное переопределение прав после каждого деплоя и хаотичные конфигурации Nginx приводят к отказам в доступе, сбоям автодеплоя и уязвимостям.
  • Решение: настроить выделенного пользователя deploy с наследованием группы веб-сервера, зафиксировать безопасные umask и права каталогов, а также использовать чистый стандартизированный шаблон конфигурации Nginx.
  • Результат: предсказуемая инфраструктура, в которой развертывание каждого нового сайта занимает не более 15 минут без вмешательства в работу соседних проектов.

Требования

Перед началом убедитесь, что:

  • VPS под управлением Ubuntu/Debian настроен и доступен по SSH;
  • установлены Nginx и PHP-FPM;
  • домен делегирован, а его A-запись указывает на публичный IP сервера.

Проверить доступность DNS-записи можно командой в локальном терминале:

ping example.com

IP-адрес в ответе должен строго совпадать с адресом вашего сервера.

Обратите внимание

В примерах используется домен example.com и директория example. Замените их на реальные значения вашего проекта во всех командах и конфигурационных файлах.

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 без проблем перезаписывать кэш и загружаемые файлы в разрешенных папках.

Разовая операция

Подготовка пользователя deploy и базовой структуры /var/www выполняется на сервере один раз.

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. Убедитесь, что:

  1. Запрос http://example.com перенаправляется кодом 301 на https://example.com.
  2. Запрос https://www.example.com перенаправляется на основной домен без www.
  3. Сертификат безопасности действителен и подписан Let’s Encrypt.
  4. Тестовый файл index.html можно удалить, заменив его файлами реального проекта.

Вывод

Стандартизированная схема развертывания обеспечивает безопасность и скорость масштабирования:

  1. Безопасность: отсутствие работы под root, жесткие права 2755 на корень сайта и скрытие служебных файлов .env и .git.
  2. Предсказуемость прав: благодаря umask 0002 и группе www-data скрипты бэкенда и пользователь деплоя бесконфликтно работают с файлами кэша и медиа.
  3. Чистый Nginx: канонические 301-редиректы и раздельные блоки хостов исключают дубли страниц в поисковой выдаче.

Рекомендуемые материалы