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

    Введение

    При работе с 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}
    

    Примечание:

    1. include snippets/fastcgi-php.conf;

    Файл snippets/fastcgi-php.conf присутствует в стандартных установках Ubuntu/Debian. В других дистрибутивах он может отсутствовать или находиться в другом месте.

    1. 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
    • легко масштабироваться

    При такой структуре добавление нового проекта сводится к копированию шаблона и замене имён и путей — без ручной магии и неожиданных багов.

    Смотрите также