Добрый день, уважаемый Хабр! В данном посте я приведу конкретные шаги по установке и настройке связки Nginx + MySQL + PHP7 на CentOS 7. Стоит отметить, что в данной статье будет рассказано про настройку системы для одного домена. В качестве площадки будет использоваться инстанс на Google Cloud Platform, с создания которого и начну:
Предлагаемый образ загрузочного диска изменяем на CentOS 7, минимальный объем диска в 10Гб вполне подойдет для развертывания системы, всех необходимых библиотек и зависимостей.
Для доступа к создаваемому серверу по SSH необходимо сгенерировать соответствующий ключ, у пользователей MacOS X или Linux для этого существует команда
ssh-keygen -t rsa -f __FILE__ -C __USER__
где __FILE__ — путь к сохраняемому ключу с именем файла, а __USER__ — имя пользователя под которым вы будете логинититься в систему. При выполнения данной команды система запросит вас указать ключевую фразу, которая будет служить паролем при использовании данного ключа, ее ввод необязателен, для пропуска ничего не вводите и нажмите Enter, далее подтвердите предыдущее действие. После выполнения данной команды система создаст указанный в __FILE__ приватный ключ, а рядом с ним — открытый с именем __FILE__.pub
Последнее, что остается сделать с ключом пользователям MacOS X и Linux — это запретить доступ на запись для всех, кроме владельца ключа, делается это командой
chmod 400 __FILE__
Пользователи Windows могут вопользоваться программой PuTTYgen. Откройте программу, нажмите Generate и следуйте инструкциям, установленные по-умолчанию параметры подходит для большинства случаев, однако Google настаивает на 2048-битных ключах, не забудьте установить данный параметр. Поле «Key comment» служит для задания имени пользователя, а для задания ключевой фразы — «Key passphrase». После завершения генерации программа отобразит публичный ключ. Чтобы сохранить приватный ключ с расширением .ppk нажмите «Save private key».
Скопируйте содержимое открытого ключа (из файла __FILE__.pub для MacOS X / Linux или из окна PuTTYgen для Windows) и вставьте его в соответствующее поле на вкладке «Безопасность»:
Не забываем разрешить трафик HTTP и HTTPS, поставив галочки в соответствующих полях. На данном этапе все готово, нажимаем «Создать».
После создания система отобразит присвоенный экземпляру внешний IP-адрес, подключимся к нему по SSH используя приватный ключ:
ssh -i __FILE__ __USER__@__IP__
Приступим непосредственно к установке LEMP. Все приведенные действия выполняются от суперпользователя (#), если явно не указано иное ($).
Обновляем систему и удаляем «осиротевшие» пакеты:
# yum clean all
# yum update
# yum autoremove
Добавляем поддержку репозиториев Fedora:
# yum install epel-release
Устанавливаем текстовый редактор nano:
# yum install nano
Устанавливаем утилиту wget для возможности получения файлов с удаленных серверов:
# yum install wget
Для развертывания приложений на Symfony (и не только), я использую клонирование git-репозитория, для реализации данного метода установим поддержку git:
# yum install git-core
Также Symfony необходима поддержка zip:
# yum install zip unzip
Нужно указать корректное имя хоста, для этого отредактируем конфигурационный файл сети:
# nano /etc/sysconfig/network
Добавьте в содержимое строку
HOSTNAME=<domain.name>
где <domain.name>, здесь и далее, необходимо заменить на корректное имя хоста.
Сохраняем файл и устанавливаем его же с помощью утилиты hostname:
# hostname <domain.name>
и перезапускаем сетевую службу:
# /etc/init.d/network restart
Устанавливаем nginx:
# yum install nginx
Запускаем nginx:
# systemctl start nginx
Добавляем nginx в автозагрузку:
# systemctl enable nginx
Устанавливаем MySQL, запускаем и добавляем в автозагрузку:
# yum install mariadb mariadb-server
# systemctl start mariadb
# systemctl enable mariadb
Проведем начальную настройку MySQL, на все вопросы скрипта ответьте «Y» и укажите пароль суперпользователя:
# mysql_secure_installation
Добавим поддержку Let's Encrypt:
# yum install certbot
Так как к моменту написания данной статьи PHP 7 нет ни в репозиториях CentOS, ни в Fedora, его мы установим из репозитория REMI:
# wget http://rpms.remirepo.net/enterprise/remi-release-7.rpm
# rpm -Uvh remi-release-7.rpm
# yum install yum-utils
# yum-config-manager --enable remi-php72
# yum --enablerepo=remi,remi-php72 install php-fpm
# yum --enablerepo=remi,remi-php72 install php-common php-opcache php-cli php-pear php-pdo php-mysqlnd php-gd php-mcrypt php-xml php-zip
Весь необходимый софт установлен, перейдем к его настройке, первоначально отредактируем конфигурационный файл php-fpm:
# nano /etc/php-fpm.d/www.conf
В данном файле необходимо указать имя пользователя и группу, под которым вы будете запускать приложение, в нашей минимальной конфигурации это пользователь, под кем вы изначально логинились в систему, одноименная группа для него создается системой автоматически.
user = __USER__
group = __USER__
listen.owner = __USER__
listen.group = __USER__
Далее, укажем сокет — необходимо под строкой ;listen = 127.0.0.1:9000 добавить следующее:
listen = /var/run/php-fpm/php-fpm.sock
Сохраните изменения, затем запустите и добавьте php-fpm в автозагрузку:
# systemctl start php-fpm
# systemctl enable php-fpm
Отключим SELINUX:
# setenforce 0
Данной командой вы отключаете SELINUX только в текущем сеансе пользователя, чтобы после перезагруки настройки сохранились необходимо отредактировать его конфигурационный файл:
# nano /etc/selinux/config
где указать SELINUX=disabled
Сохраните изменения и выйдете из режима суперпользователя. Далее мы создадим директорию для проекта в домашней директории и поместим туда индексный файл — заглушку для проверки работоспособности создаваемого стека:
$ cd ~
$ mkdir -p <domain.name>/public
$ cd <domain.name>/public
$ nano index.php
Пусть содержимое файла будет следующим (замените __YOUR_ROOT_PASSWORD__ на пароль суперпользователя MySQL, указанный при его настройке):
<html>
<head>
<h2>LEMP test</h2>
</head>
<body>
<?php echo '<p>Hello!</p>';
$host = "localhost";
$username = "root";
$password = "__YOUR_ROOT_PASSWORD__";
$connection = mysqli_connect($host, $username, $password);
if (!$connection)
print '<p>DB connect failed with error: ' . mysqli_connect_error() . '</p>';
else
print '<p>DB connection established</p>';
?>
</body>
</html>
Снова авторизуемся под правами суперпользователя и откроем на редактирование конфигурационный файл nginx:
# nano /etc/nginx/nginx.conf
Изменим имя пользователя подобно конфигурации php-fpm:
user __USER__;
Конфигурацию директивы server, созданную по-уполчанию, измените следующим образом:
server {
server_name <domain.name> www.<domain.name>;
root /home/__USER__/<domain.name>/public;
location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}
location ~ ^/index.php(/|$) {
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_split_path_info ^(.+.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
location ~ .php$ {
return 404;
}
error_log /var/log/nginx/<domain.name>.error.log;
access_log /var/log/nginx/<domain.name>.access.log;
}
Сохраните изменения и перезапустите nginx:
# systemctl restart nginx
По доменному имени <domain.name> должна открываться созданная нами страница — заглушка.
Приступим к созданию сертификата:
# openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
# certbot certonly --webroot -w /home/__USER__/<domain.name>/public -d <domain.name>
# certbot certonly --webroot -w /home/__USER__/<domain.name>/public -d www.<domain.name>
После генерации ключей, изменим конфигурацию nginx для поддержки HTTPS, в данной конфигурации «главным» идет домен без www и настроено перенаправление на защищенное соединение. И так:
# nano /etc/nginx/nginx.conf
Меняем созданную нами 2 шага назад директиву server на следующие:
server {
listen 443 ssl;
server_name <domain.name>;
ssl_certificate /etc/letsencrypt/live/<domain.name>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<domain.name>/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
root /home/__USER__/<domain.name>/public;
location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$is_args$args;
}
location ~ ^/index.php(/|$) {
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
fastcgi_split_path_info ^(.+.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
location ~ .php$ {
return 404;
}
error_log /var/log/nginx/<domain.name>.error.log;
access_log /var/log/nginx/<domain.name>.access.log;
}
server {
listen 443 ssl;
server_name www.<domain.name>;
ssl_certificate /etc/letsencrypt/live/www.<domain.name>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.<domain.name>/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
return 301 https://<domain.name>$request_uri;
}
server {
server_name <domain.name> www.<domain.name>;
return 301 https://<domain.name>$request_uri;
}
Сохраняем результат и перезапускаем nginx:
# systemctl restart nginx
Так как Let's Encrypt необходимо обновлять раз в три месяца, настроим автоматическое продление в планировщике, к примеру так, в ночь на понедельник
# crontab -e
15 4 * * 1 /usr/bin/certbot renew --quiet
18 4 * * 1 /usr/bin/systemctl reload nginx
Чтобы у разворачиваемого приложения не было проблем с правами, меняем владельца следующих папок:
# chown -R __USER__:__USER__ /var/lib/nginx
# chown -R __USER__:__USER__ /var/lib/php/session/
Все, система готова. Перезагрузитесь, чтобы удостовериться, что весь необходимый софт сконфигурирован правильно и после перезагрузки не будет вести себя иначе, далее можно удалить созданную нами папку проекта в директории пользователя и клонировать в ней необходимый рабочий репозиторий.
Автор: iAmWeb