Закончив чтение данного руководства, вы научитесь самостоятельно настраивать минималистичный LEMP (Linux, Nginx, MySQL, PHP 7) сервер для сайта без лишних компонентов. Ваш сайт будет доступен по защищенному протоколу HTTPS с поддержкой бесплатного сертификата Let’s Encrypt.
Ubuntu версии 18.04 LTS. Мы рекомендуем использовать данный дистрибутив Ubuntu, так как он будет поддерживаться до 2023 года, что позволит поддерживать сервер в актуальном состоянии и устанавливать на него обновления безопасности из стандартных источников.
MariaDB. Альтернативная реализация сервера MySQL, которая обладает лучшей производительностью и при этом полностью с ним совместима.
Требования к серверу
Для нормальной работы сайта с более-менее приличной нагрузкой вам понадобится сервер с одним или двумя ядрами, 1 GB RAM и 10 GB хранилища. Мы предполагаем, что вы уже располагаете такими или большими ресурсами и готовы приступить к установке.
Требования к DNS
Мы предполагаем, что вы уже имеете доменное имя, которое указывает на IP-сервера. Далее, будем считать, что сайт будет использовать доменное имя website.com. Везде, где фигурирует website.com вы должны сделать замену на имя своего домена. Мы будем использовать переменную WEBSITE_NAME для упрощения настройки:
# если hostname --fqdn отдает правильное доменное имя, то используйте # export WEBSITE_NAME=$(hostname --fqdn) # в противном случае export WEBSITE_NAME=mycooldomain.com
Базовая настройка компонентов Nginx и получение сертификата
Nginx. Установка выполняется стандартным для Ubuntu способом:
sudo apt update && sudo apt install -y nginx
Получение сертификата Let’s Encrypt. Для установки сертификата Let’s Encrypt установим требуемое программное обеспечение:
sudo add-apt-repository -y ppa:certbot/certbot && sudo apt install -y python3-certbot-nginx
Теперь вы можете сгенерировать сертификат Let’s Encrypt для сервера. Для этого в Nginx необходимо добавить секцию для виртуального хоста, который будет описывать ваш сайт.
Создайте файл /etc/nginx/sites-available/$WEBSITE_NAME со следующей конфигурацией, которая будет основой нашей будущей конфигурации сайта:
server { listen 80; listen [::]:80; server_name website.com; } server { listen 443 ssl; listen [::]:443 ssl; server_name website.com; root /var/www/website.com; index index.html; location / { try_files $uri $uri/ =404; } }
Заменим website.com на имя вашего домена:
sudo sed -i "s/website.com/$WEBSITE_NAME/g" /etc/nginx/sites-available/$WEBSITE_NAME
Создайте символическую ссылку для активации виртуального хоста:
sudo ln -s /etc/nginx/sites-{available,enabled}/$WEBSITE_NAME # проверьте корректность конфигурации Nginx sudo nginx -t
Теперь закажем сертификат для этого виртуального хоста с помощью certbot. После запуска скрипт попросит вас указать ряд параметров:
- адрес электронной почты, с которой будет ассоциирован сертификат;
- домен из списка найденных в настройках Nginx доменов для которого сертификат будет получаться;
- необходимо ли настроить автоматическое перенаправление пользователей с HTTP на HTTPS (здесь надо указать Yes).
sudo certbot --nginx
В итоге в файле /etc/nginx/sites-enabled/$WEBSITE_NAME должна появиться дополнительная конфигурация, сгенерированная certbot:
server { if ($host = website.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; server_name website.com; } server { listen 443 ssl; listen [::]:443 ssl; server_name website.com; root /var/www/website.com; index index.html; location / { try_files $uri $uri/ =404; } ssl_certificate /etc/letsencrypt/live/website.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/website.com/privkey.pem; # managed by Certbot }
Перезапустите nginx для активации изменений:
sudo nginx -t && sudo service nginx restart
Для проверки работы SSL проведем эксперимент. Создадим файл index.html и проверим работу сертификата:
sudo mkdir -p /var/www/$WEBSITE_NAME sudo sh -c "echo 'Hello, world' > /var/www/$WEBSITE_NAME/index.html" curl https://$WEBSITE_NAME/ Hello, world
Теперь, если вы откроете в браузере http://website.com, то Nginx должен вас перебросить на https://website.com и отобразить текст Hello, world.
Настройка автопродления сертификата. Сертификаты Let’s Encrypt надо продлевать раз в 90 дней, иначе они устаревают. Добавим в CRON задачу вызова автопродления. Для этого в каталоге /etc/cron.monthly создайте скрипт по имени le-renew следующего содержания:
#/bin/bash certbot renew
Выдайте ему права на исполнение и протестируйте:
sudo chmod 755 /etc/cron.monthly/le-renew sudo /etc/cron.monthly/le-renew
На этом пока что настройку Nginx закончим и установим оставшиеся компоненты.
Установка и настройка MariaDB
Произведем базовую установку MariaDB 10.3, рекомендованную поставщиком для Ubuntu Linux 18.04:
sudo apt-get install software-properties-common sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8 sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el] http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu bionic main' sudo apt update sudo apt install -y mariadb-server apg
Проверьте корректность установки, соединившись с MariaDB с помощью клиента командной строки:
mysql -uroot -e 'SELECT version();' +--------------------------------------------+ | version() | +--------------------------------------------+ | 10.3.13-MariaDB-1:10.3.13+maria~bionic-log | +--------------------------------------------+
Соединение работает, если вы получили вывод похожий на приведенный выше.
Если ваш сервер располагает внушительным запасом RAM и ядрами, а сайт будет работать под существенной нагрузкой, вы должны выполнить дополнительные настройки MySQL, чтобы оптимизировать его призводительность, однако, в рамках данной статьи эти настройки не рассматриваются.
Создадим базу данных для сайта и настроим доступ пользователя к ней. В настройке используется пользователь siteuser с паролем secret. Вы должны задать безопасный пароль, который можете сгенерировать с помощью команды apg.
export DB_NAME=website export DB_USER=siteuser export DB_PASSWORD=secret mysql -uroot -e "CREATE DATABASE IF NOT EXISTS $DB_NAME;" mysql -uroot -e "GRANT ALL PRIVILEGES ON $DB_NAME.* TO '$DB_USER'@'localhost' IDENTIFIED BY '$DB_PASSWORD'"; mysql -uroot -e "FLUSH PRIVILEGES;" mysql -u$DB_USER -p$DB_PASSWORD $DB_NAME -e 'select version();' +--------------------------------------------+ | version() | +--------------------------------------------+ | 10.3.14-MariaDB-1:10.3.14+maria~bionic-log | +--------------------------------------------+
Запомните выбранные имя пользователя, пароль и название базы данных, чтобы не забыть. На этом настройка MariaDB завершена.
Установка и настройка PHP7
PHP версии 7.2 присутствует в стандартной поставке Ubuntu Linux 18.04. Установим пакеты из репозитория:
sudo apt install -y php7.2-common php7.2-readline php7.2-fpm php7.2-cli php7.2-gd php7.2-mysql php7.2-curl php7.2-mbstring php7.2-opcache php7.2-json php7.2-xml php7.2-zip # поправим настройки PHP для режима FPM sudo sed -i "s/memory_limit = .*/memory_limit = 256M/" /etc/php/7.2/fpm/php.ini sudo sed -i "s/upload_max_filesize = .*/upload_max_filesize = 128M/" /etc/php/7.2/fpm/php.ini sudo sed -i "s/zlib.output_compression = .*/zlib.output_compression = on/" /etc/php/7.2/fpm/php.ini sudo sed -i "s/max_execution_time = .*/max_execution_time = 18000/" /etc/php/7.2/fpm/php.ini
Менеджер процессов PHP-FPM может работать в трех режимах — статическом, динамическом и «по требованию». По умолчанию, используется динамический режим. Мы изменим режим на режим «по требованию». Для этого мы перенесем базовую конфигурацию в файл www.conf.orig, а новую конфигурацию заполним данными из листинга ниже:
sudo mv /etc/php/7.2/fpm/pool.d/www.{conf,conf.orig} sudo nano /etc/php/7.2/fpm/pool.d/www.conf
[www] user = www-data group = www-data listen = /run/php/php7.2-fpm.sock listen.owner = www-data listen.group = www-data listen.mode = 0666 pm = ondemand pm.max_children = 5 pm.process_idle_timeout = 10s pm.max_requests = 200 chdir = /
Теперь перезапустим PHP-FPM для активации изменений:
sudo service php7.2-fpm restart
Настройка виртуального хоста сайта
Настройку начнем с того, что завершим конфигурацию Nginx для работы с PHP-FPM. Для этого изменим конфигурационный файл сайта /etc/nginx/sites-available/$WEBSITE_NAME.
Добавим перед секцией server следующий фрагмент конфигурации, который задает способ связи с PHP-FPM:
upstream php { server unix:/run/php/php7.2-fpm.sock; } # то, что ниже не добавлять в настройку, # приведено для примера куда вставить секцию # upstream # server { listen 443 ssl; listen [::]:443 ssl; ...
Удалим следующие строки конфигурации:
index index.html; location / { try_files $uri $uri/ =404; }
Добавим следующие строки конфигурации вместо них:
access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; index index.php; location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } location / { try_files $uri $uri/ /index.php?$args; } location ~ .php$ { include fastcgi.conf; fastcgi_intercept_errors on; fastcgi_pass php; } location ~* .(js|css|png|jpg|jpeg|gif|ico)$ { expires max; log_not_found off; }
Пример полной конфигурации:
server { if ($host = website.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; server_name website.com; } upstream php { server unix:/run/php/php7.2-fpm.sock; } server { listen 443 ssl; listen [::]:443 ssl; server_name website.com; root /var/www/example.com; ssl_certificate /etc/letsencrypt/live/website.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/website.com/privkey.pem; # managed by Certbot access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; index index.php; location = /favicon.ico { log_not_found off; access_log off; } location = /robots.txt { allow all; log_not_found off; access_log off; } location / { try_files $uri $uri/ /index.php?$args; } location ~ .php$ { include fastcgi.conf; fastcgi_intercept_errors on; fastcgi_pass php; } location ~* .(js|css|png|jpg|jpeg|gif|ico)$ { expires max; log_not_found off; } }
Проверим корректность настроек Nginx и перезапустим его:
sudo nginx -t && sudo service nginx restart
Убедимся, что PHP-скрипты работают корректно. Для этого создадим файл index.php в пути /var/www/$WEBSITE_NAME/index.php со следующим содержимым:
<?php echo "Hello\n";
Проверим работоспособность скрипта:
# локально php /var/www/$WEBSITE_NAME/index.php Hello # через web curl https://$WEBSITE_NAME/index.php Hello # удалим скрипт sudo rm /var/www/$WEBSITE_NAME/index.{php,html}
Настройка сервера LEMP завершена. Теперь вы можете выполнить развертывание сайта в каталоге /var/www/$WEBSITE_NAME и начать его использование, открыв в браузере https://$WEBSITE_NAME/.
Организация доступа к серверу для разработчика
Если настраиваемый сервер планируется для разработки, возможно, требуется настроить FTP-сервер для работы с файлами сайта.
Для настройки мы воспользуемся возможностью Linux создавать нескольких пользователей с одним и тем же UID. В этом случае все учетные записи являются синонимами, но им можно назначать разные пароли и оболочки.
Дело в том, что файлы, которые обслуживаются Nginx хранятся под пользователем www-data. Если мы создадим нового уникального пользователя, то придется для установить на файлы и каталоги широкие права для того, чтобы он мог манипулировать файлами Nginx, кроме того, вероятно, будет возникать путаница с правами и периодическая недоступность ресурсов, связанная с этим.
Вместо этого, мы создадим пользователя developer с таким же UID как и у www-data, соответственно, он сможет получить нормальный доступ к файлам и права будут корректными.
Сначала узнаем UID www-data:
id www-data uid=33(www-data) gid=33(www-data) группы=33(www-data)
Теперь добавим нового пользователя с повторяющимся UID:
sudo useradd -o -u 33 -d /var/www/$WEBSITE_NAME -g www-data developer sudo passwd developer
Проверим, что пользователь может нормально войти в систему по ssh с локальной машины:
ssh developer@$WEBSITE_NAME
Если вход получилось осуществить, то пользователь успешно добавлен, а базовая настройка сервера завершена. Для большей безопасности рекомендуем настроить вход в SSH с использованием ключа SSH, а не пароля.
Резервное копирование данных
Важно настроить резервное копирование сразу же, как только вы настроили сервер, не откладывая это действие на потом. Воспользуйтесь нашим пошаговым руководством по настройке инкрементного резервного копирования файлов и баз данных для MySQL и PostgreSQL с помощью Duplicity.