Локальный LAMP

14.09.2021

Развернем на рабочем ПК (ноутбуке) локальный веб-сервер с поддержкой разных версий php для работы с разными CMS.

Для этого качестве веб-сервера используем apache2, так как некоторые CMS требуют .htaccess.

Естественно установим php, но не простой, а FPM чтобы любой хост (сайт) работал на той версии php, которая ему нужна, при этом не потребуется перезагрузка веб-сервера.

СУБД MySQL8, и конечно же удобный клиент для работы с БД - phpMyAdmin (в качестве первого локального сайта).

Итоговый веб-сервер не требует специфичных или тонких настроек (за исключением хостов), так как он предполагается для тестов, а не для продакшен версии сервера (в моем случае для разработки модулей под разные CMS).

Apache 2

Установим apache2:

•••
bash
$ sudo apt install apache2

Проверим статус:

•••
bash
$ systemctl status apache2 apache2.service - The Apache HTTP Server Loaded: loaded (/lib/systemd/system/apache2.service; enabled; vendor prese> Active: active (running) since Sat 2021-09-04 08:57:23 MSK; 6h ago Docs: https://httpd.apache.org/docs/2.4/ Process: 987 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUC> Main PID: 1094 (apache2) Tasks: 12 (limit: 9280) Memory: 31.2M CGroup: /system.slice/apache2.service ├─1094 /usr/sbin/apache2 -k start ├─1101 /usr/sbin/apache2 -k start ├─1136 /usr/sbin/apache2 -k start ├─1137 /usr/sbin/apache2 -k start ├─1138 /usr/sbin/apache2 -k start ├─1150 /usr/sbin/apache2 -k start ├─1156 /usr/sbin/apache2 -k start ├─8818 /usr/sbin/apache2 -k start ├─8878 /usr/sbin/apache2 -k start ├─8879 /usr/sbin/apache2 -k start ├─8880 /usr/sbin/apache2 -k start └─8881 /usr/sbin/apache2 -k start

Как видно по выводу - apache2 запущен, если это не так, тогда его надо запустить:

•••
bash
$ sudo systemctl start apache2

Когда apache2 запущен, то в браузере можно просмотреть стандартную страницу по адресу localhost.

Страница дефолтного сайта apache2
Страница дефолтного сайта apache2

Директория дефолтного сайта расположена по пути /var/www/html/, здесь же лежит index.html (то что рендерится по адресу localhost). Этот сайт можно отключить следующим образом:

•••
bash
$ sudo a2dissite 000-default.conf

PHP

Установим software-properties-common для добавления/удаления PPA:

•••
bash
$ sudo apt install software-properties-common

Добавим репозиторий свежих версий php:

•••
bash
$ sudo add-apt-repository ppa:ondrej/php

Обновим списки пакетов, которые требуют обновления, а также для новых пакетов из нового источника (добавленного строкой выше):

•••
bash
$ sudo apt update

Теперь можно перейти к установке php.

php под apache может работать в двух режимах:

  • как модуль apache
  • как отдельно существующий обработчик скриптов
Рассмотрим оба варианта.

PHP как модуль apache

В это случае хост (сайт) будет работать с использованием дефолтной версии php по CGI, а дефолтной может быть только одна версия.

Когда пользователь открывает страницу сайта (php скрипт) apache2 вызывает интепретатор php /usr/bin/php и передает ему данные для исполнения. Каждый запуск скрипта - запуск интепретатора, что естественно малоэффективно и не гибко в плане используемых версий.

Для этого надо установить php нужной версии и соответсвующий модуль apache (например для php7.3):

•••
bash
$ sudo apt install php7.3 libapache2-mod-php7.3

Смена дефолтной версии php

Так бывает что нужно сменить дефолтную версию php. Для этого воспользуемся update-alternatives:

•••
bash
$ sudo update-alternatives --config php Есть 6 вариантов для альтернативы php (предоставляет /usr/bin/php). Выбор Путь Приор Состояние ------------------------------------------------------------ 0 /usr/bin/php8.0 80 автоматический режим 1 /usr/bin/php5.6 56 ручной режим 2 /usr/bin/php7.1 71 ручной режим 3 /usr/bin/php7.2 72 ручной режим * 4 /usr/bin/php7.3 73 ручной режим 5 /usr/bin/php7.4 74 ручной режим 6 /usr/bin/php8.0 80 ручной режим Press <enter> to keep the current choice[*], or type selection number:

Получаем список доступных версий, где звездочкой помечена текущая версия. Введя номер строки с нужной версией можно изменить дефолтную версию.

PHP-FPM

Чтобы любому хосту можно было назначить версию php отличную от дефолтной, необходимо чтобы apache использовал php по FastCGI.

Для этого необходимо использовать PHP-FPM и установить соответсвующий модуль для apache2:

•••
bash
$ sudo apt install php5.6 php5.6-fpm php7.3 php7.3-fpm libapache2-mod-fcgid

PHP-FPM будет держать пулл запущенных процессов интепретаторов php. Когда пользователь запустит php скрипт, apache передаст в PHP-FPM информацию для исполнения, а PHP-FPM сам отдаст эту информацию свободному процессу. Таким образом устраняется процесс запуска и уничтожения процессов.

Управлять PHP-FPM можно через systemctl:

•••
bash
$ systemctl status php7.3-fpm php7.3-fpm.service - The PHP 7.3 FastCGI Process Manager Loaded: loaded (/lib/systemd/system/php7.3-fpm.service; enabled; vendor pr> Active: active (running) since Sat 2021-09-04 08:57:23 MSK; 7h ago Docs: man:php-fpm7.3(8) Process: 1165 ExecStartPost=/usr/lib/php/php-fpm-socket-helper install /run> Main PID: 1023 (php-fpm7.3) Status: "Processes active: 0, idle: 3, Requests: 66, slow: 0, Traffic: 0re> Tasks: 4 (limit: 9280) Memory: 144.9M CGroup: /system.slice/php7.3-fpm.service ├─1023 php-fpm: master process (/etc/php/7.3/fpm/php-fpm.conf) ├─1164 php-fpm: pool www ├─8838 php-fpm: pool www └─8874 php-fpm: pool www

При работе PHP-FPM в лог ошибок может записываться обрезанное сообщение.

Чтобы получать полный текст ошибок необходимо в ключ error_log указать путь до файла куда будут записываться ошибки в конфиге php-fpm (/etc/php/php7.3/fpm/php.ini).

Например, при конфигурации ниже, файл php_error.log будет появляться в той же директории с php скриптом, в котором будет ошибка:

•••
plaintext
error_log = php_errors.log

Также при использовании PHP-FPM можно для каждого сайта указать свой php.ini, для этого все в том же /etc/php/php7.3/fpm/php.ini нужно указать ключ:

•••
plaintext
user_ini.filename = "php.ini"

MySQL

MySQL 5.7 до сих пор поддерживается. Есть аналог MariaDB. Но только MySQL 8 поддерживает не ожидающие экслюзивные блокировки строк, что мне и требовалось для некоторых проектов. Поэтому в этом разделе будем говорить про MySQL 8

В Ubuntu 18 и младше, в репозитории нет MySQL8:

•••
bash
$ apt-cache show mysql-server | grep -i version Version: 5.7.35-0ubuntu0.18.04.1 ...

Поэтому идем на dev.mysql.com > MySQL APT Repository > Download > No thanks, just start my download качаем и запускаем:

•••
bash
$ wget https://dev.mysql.com/get/mysql-apt-config_0.8.19-1_all.deb $ dpkg -i mysql-apt-config_0.8.19-1_all.deb

Откроется окно настройки версий пакетов MySQL, где надо будет выбрать нужную версию, которую дальше можно будет установить через apt. По умолачнию (Currently selected: mysql-8.0) то что нужно, выбераем OK

Настройка версий пакетов MySQL
Настройка версий пакетов MySQL

Обновляем дерево пакетов и проверяем доступную версию пакета MySQL:

•••
bash
$ sudo apt update $ apt-cache show mysql-server | grep -i version Version: 8.0.26-1ubuntu18.04 ...

Теперь MySQL 8 доступна, устанавливаем:

•••
bash
$ sudo apt install mysql-server

Во время установки будет показано окно, где будет вежливо предложено ввести пароль администратора БД (по умолачнию логин root, это не тот root что в системе, это другой root), а затем подтвердить его. Затем необходимо выбрать метод аутентификации, лучше RECOMMENDED.

Конфигурирование MySQL, выбор метода аутентификации
Конфигурирование MySQL, выбор метода аутентификации

Теперь в БД можно зайти от имени root.

Пользователи и привелегии

Для входа в БД можно использовать не только root, но и любого другого пользователя. Заходим через терминал в БД (потребуется ввести пароль, который был дважды введен на этапе установки MySQL):

•••
bash
$ sudo mysql -u root -p

Дальеш в статье мы будем устанавливать phpMyAdmin, поэтому сделаем для этого дела отдельного пользователя.

Создадим нового пользователя и дадим ему полные привелегии:

•••
sql
CREATE USER 'pma'@'localhost' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON *.* TO 'pma'@'localhost'; FLUSH PRIVILEGES;

Теперь можно от имени pma зайти в БД.

Хосты/сайты

Рассмотрим хосты на примере удобного клиента БД phpMyAdmin, создадим хост с именем pma.local

Файловая структура

Для начала определимся с директорией хранения хостов. Пусть это будет /var/www/.

Файловая структура хоста будет следующей:

  • namehost.local - директория хоста (.local чтобы отличать локальные домены от глобальных)
    • htdocs - корневая директория сайта
    • logs - директория с логами
Директория хоста и все ее содержимое должны принадлежать группе и пользователю www-data и иметь права 775, а пользователь, от которого осуществляется редактирование файлов хоста, должен быть в группе www-data - скрипты будут иметь полные права на файлы и директории, а редактирующий пользователь будет иметь права на редактирование.

Назначаем владельца и права директории (и всему тому что внутри) хоста:

•••
bash
$ sudo chown -R www-data:www-data /var/www/pma.local/ $ sudo chmod -R 775 /var/www/pma.local/

В моем случае, пользователь, который редактирует файлы хоста byurrer, его надо поместить в группу www-data.

Просмотр списка групп, в которых состоит пользователь (команда запускается от имени byurrer):

•••
bash
$ groups byurrer adm cdrom sudo dip plugdev lpadmin lxd sambashare

Добавим пользователя byurrer в группу www-data:

•••
bash
$ sudo usermod -a -G www-data byurrer

Теперь просмотрим список групп:

•••
bash
$ groups byurrer adm cdrom sudo dip www-data plugdev lpadmin lxd sambashare

Теперь byurrer в группе www-data.

Конфигурация хоста

  • /etc/apache2/site-available/ хранит файлы конфиги хостов
  • /etc/apache2/site-enabled/ содержит символические ссылки на подключенные хосты

Добавляем конфиг хоста pma.local.conf в директорию подключаемых сайтов apache /etc/apache2/site-available/ со следующим содержимым (вместо php7.3-fpm можно указать любую другую установленную версию php):

•••
plaintext
<VirtualHost *:80> # название сайта ServerName pma.local ServerAdmin byurrer@mail.ru # корневая директория сайта DocumentRoot /var/www/pma.local/htdocs # используем php-fpm с указанием нужной версии php # если достаточно версии php по умолачнию, то это указывать не надо <FilesMatch \.php$> SetHandler "proxy:unix:/run/php/php7.3-fpm.sock|fcgi://localhost" </FilesMatch> # пути до файлов логов ErrorLog /var/www/pma.local/logs/error.log CustomLog /var/www/pma.local/logs/access.log combined </VirtualHost>

Теперь необходимо в файл /etc/hosts добавить информацию о нашем сайте, чтобы наш локальный сервер при обращении к этому сайту обращался сам к себе:

•••
bash
$ sudo echo "127.0.0.1 pma.local" >> /etc/hosts

Включение/выключение хостов

Теперь можно активировать новые хосты используя утилиту apache2 a2ensite:

•••
bash
$ sudo a2ensite pma.local Enabling site pma.local. To activate the new configuration, you need to run: systemctl reload apache2

Для отключения хоста используется другая утилита a2dissite:

•••
bash
$ sudo a2dissite pma.local Site pma.local disabled. To activate the new configuration, you need to run: systemctl reload apache2

После включения/выключения хоста необходимо перезагружать apache2:

•••
bash
$ sudo systemctl reload apache2

phpMyAdmin

Качаем архив с последней версией phpMyAdmin (на момент написания статьи это 5.1.1), распаковываем архив и переименовываем:

•••
bash
$ cd /var/www/pma.local/ $ wget https://files.phpmyadmin.net/phpMyAdmin/5.1.1/phpMyAdmin-5.1.1-all-languages.zip $ unzip phpMyAdmin-5.1.1-all-languages.zip -d ./ $ mv phpMyAdmin-5.1.1-all-languages htdocs

Теперь меняем группу и права на директорию и все что в ней находится, как в разделе выше.

Заходим в htdocs и переименовываем конфиг:

•••
bash
$ mv config.sample.inc.php config.inc.php

В самом минимальном варианте для phpMyAdmin этого достаточно.

Однако, при обращении к хосту pma.local через браузер получим следующее:

Composer detected issues in your platform: Your Composer dependencies require the following PHP extensions to be installed: xml

В php не хватает библиотеки для работы с xml, устанавливаем:

•••
bash
$ sudo apt install php7.3-xml

Теперь все норм, но при попытке авторизации получаем ошибку:

Неизвестный для phpMyAdmin метод аутентификации
Неизвестный для phpMyAdmin метод аутентификации

Проблема в том, что начиная с MySQL 8.0.4 был изменен плагин аутентификации по умолчанию с mysql_native_password на caching_sha2_password. Вернуть mysql_native_password для конкретного пользователя можно так:

•••
sql
ALTER USER 'pma'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';

Теперь можно администрировать БД через phpMyAdmin на свои локальном сервере. Кстати, через phpMyAdmin на локальном сервере можно администрировать и удаленные БД.

Резюме

Выше я описал установку конфигурации локального веб-серера, которым сам пользуюсь уже около года при разработки разных проектов, начиная от модулей для CMS и заказнчвая отдельными сервисами (php + react). Конфигурация не сложна в развертывании (уже было несколько установок на разные локальные машины и vps).

Несмотря на детальность установки, в процессе могут возникнуть проблемы, решение которых можно найти в интернетах.