Закончив чтение данного руководства, вы научитесь самостоятельно настраивать минималистичный сервер LEMP (Linux, Nginx, MySQL, PHP 7) для сайта без лишних компонентов. Ваш сайт будет доступен по защищенному протоколу HTTPS с поддержкой бесплатного сертификата Let’s Encrypt.
CentOS 7. Мы рекомендуем использовать данный дистрибутив CentOS, так как он будет поддерживаться до 2024 года, что позволит иметь сервер в актуальном состоянии и устанавливать на него обновления безопасности из стандартных источников. CentOS 7 — выбор для администраторов, которые приверженны дистрибутивам, основанным на RedHat Enterprise Linux, ценят непрерывность сервиса и ультрадолгий режим поддержки релизов.
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. Установка выполняется стандартным для CentOS способом:
sudo yum install -y epel-release && sudo yum install -y nginx sudo systemctl stop nginx sudo systemctl enable nginx
Получение сертификата Let’s Encrypt. Для установки сертификата Let’s Encrypt установим требуемое программное обеспечение:
sudo yum install -y python2-certbot-nginx nano unzip
Теперь вы можете сгенерировать сертификат Let’s Encrypt для сервера. Для этого в Nginx необходимо добавить секцию для виртуального хоста, который будет описывать ваш сайт.
Создайте файл /etc/nginx/conf.d/${WEBSITE_NAME}.conf со следующей конфигурацией, которая будет основой нашей будущей конфигурации сайта:
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/conf.d/${WEBSITE_NAME}.conf
Проверьте корректность конфигурации Nginx:
sudo nginx -t
Теперь закажем сертификат для этого виртуального хоста с помощью certbot. После запуска скрипт попросит вас указать ряд параметров:
- адрес электронной почты, с которой будет ассоциирован сертификат;
- домен из списка найденных в настройках Nginx доменов для которого сертификат будет получаться;
- необходимо ли настроить автоматическое перенаправление пользователей с HTTP на HTTPS (здесь надо указать Yes).
sudo certbot --nginx sudo pkill -9 nginx
В итоге в файле /etc/nginx/conf.d/${WEBSITE_NAME}.conf должна появиться дополнительная конфигурация, сгенерированная 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 systemctl start nginx && sudo systemctl enable nginx
Для проверки работы 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, рекомендованную поставщиком для CentOS 7. Сначала необходимо добавить репозиторий пакетов MariaDB 10.3 в Yum:
sudo nano /etc/yum.repos.d/mariadb.repo
со следующим содержимым:
# MariaDB 10.3 CentOS repository list - created 2019-03-28 19:13 UTC # http://downloads.mariadb.org/mariadb/repositories/ [mariadb] name = MariaDB baseurl = http://yum.mariadb.org/10.3/centos7-amd64 gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck=1
Теперь можно выполнить установку пакетов:
sudo yum install -y MariaDB-server MariaDB-client apg && sudo systemctl enable mariadb && sudo systemctl start mariadb
Проверьте корректность установки, соединившись с MariaDB с помощью клиента командной строки:
mysql -uroot -e 'SELECT version();' +-----------------+ | version() | +-----------------+ | 10.3.13-MariaDB | +-----------------+
Соединение работает, если вы получили вывод похожий на приведенный выше.
Если ваш сервер располагает внушительным запасом 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 | +-----------------+
Запишите выбранные имя пользователя, пароль и название базы данных, чтобы не забыть. На этом настройка MariaDB завершена.
Установка и настройка PHP7
PHP версии 7.2 отсутствует в стандартной поставке CentOS 7. Установим нужные пакеты из репозитория remirepo:
sudo yum -y install http://rpms.remirepo.net/enterprise/remi-release-7.rpm sudo yum-config-manager -y --enable remi-php72 sudo yum install -y php72 php72-php-fpm php72-php-mysqlnd php72-php-opcache php72-php-xml php72-php-xmlrpc php72-php-gd php72-php-mbstring php72-php-json php72-php-zip php72-php-xml sudo ln -s /usr/bin/php72 /usr/bin/php sudo systemctl start php72-php-fpm sudo systemctl enable php72-php-fpm # поправим настройки PHP для режима FPM sudo sed -i "s/memory_limit = .*/memory_limit = 256M/" /etc/opt/remi/php72/php.ini sudo sed -i "s/upload_max_filesize = .*/upload_max_filesize = 128M/" /etc/opt/remi/php72/php.ini sudo sed -i "s/zlib.output_compression = .*/zlib.output_compression = on/" /etc/opt/remi/php72/php.ini sudo sed -i "s/max_execution_time = .*/max_execution_time = 18000/" /etc/opt/remi/php72/php.ini
Менеджер процессов PHP-FPM может работать в трех режимах — статическом, динамическом и «по требованию». По умолчанию, используется динамический режим. Мы изменим режим на режим «по требованию». Для этого мы перенесем базовую конфигурацию в файл www.conf.orig, а новую конфигурацию заполним данными из листинга ниже:
sudo mv /etc/opt/remi/php72/php-fpm.d/www.{conf,conf.orig} sudo nano /etc/opt/remi/php72/php-fpm.d/www.conf
[www] user = nginx group = nginx listen = /var/run/php72-fpm.sock listen.owner = nginx listen.group = nginx listen.mode = 0666 pm = ondemand pm.max_children = 5 pm.process_idle_timeout = 10s pm.max_requests = 200 chdir = /
Теперь перезапустим PHP-FPM для активации изменений:
sudo systemctl restart php72-php-fpm
Настройка сайта
Настройку начнем с того, что завершим конфигурацию Nginx для работы с PHP-FPM. Для этого изменим конфигурационный файл сайта /etc/nginx/conf.d/${WEBSITE_NAME}.conf.
Добавим перед секцией server следующий фрагмент конфигурации, который задает способ связи с PHP-FPM:
upstream php { server unix:/var/run/php72-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:/var/run/php72-fpm.sock; } server { listen 443 ssl; listen [::]:443 ssl; server_name website.com; root /var/www/website.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 systemctl restart nginx
Убедимся, что 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 хранятся под пользователем nginx. Если мы создадим нового уникального пользователя, то придется для установить на файлы и каталоги широкие права для того, чтобы он мог манипулировать файлами Nginx, кроме того, вероятно, будет возникать путаница с правами и периодическая недоступность ресурсов, связанная с этим.
Вместо этого, мы создадим пользователя developer с таким же UID как и у www-data, соответственно, он сможет получить нормальный доступ к файлам и права будут корректными.
Сначала узнаем UID nginx:
id nginx uid=996(nginx) gid=993(nginx) группы=993(nginx)
Теперь добавим нового пользователя с повторяющимся UID:
sudo useradd -o -u 996 -d /var/www/$WEBSITE_NAME -g nginx developer sudo passwd developer
Проверим, что пользователь может нормально войти в систему по ssh с локальной машины:
ssh developer@$WEBSITE_NAME
Если вход получилось осуществить, то пользователь успешно добавлен, а базовая настройка сервера завершена. Для большей безопасности рекомендуем настроить вход в SSH с использованием ключа SSH, а не пароля.
Резервное копирование данных
Важно настроить резервное копирование сразу же, как только вы настроили сервер, не откладывая это действие на потом. Воспользуйтесь нашим пошаговым руководством по настройке инкрементного резервного копирования файлов и баз данных для MySQL и PostgreSQL с помощью Duplicity.