Локальный LAMP

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

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

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

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

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

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

Apache 2

Установим apache2:

$ sudo apt install apache2

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

$ 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 запущен, если это не так, тогда его надо запустить:

$ sudo systemctl start apache2

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

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

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

$ sudo a2dissite 000-default.conf

PHP

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

$ sudo apt install software-properties-common

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

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

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

$ sudo apt update

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

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

Рассмотрим оба варианта.

PHP как модуль apache

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

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

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

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

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

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

$ 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:

$ 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:

$ 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 скриптом, в котором будет ошибка:

error_log = php_errors.log

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

user_ini.filename = "php.ini"

MySQL

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

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

$ 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 качаем и запускаем:

$ 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:

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

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

$ sudo apt install mysql-server

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

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

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

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

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

$ sudo mysql -u root -p

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

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

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

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

Хосты/сайты

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

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

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

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

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

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

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

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

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

$ groups
byurrer adm cdrom sudo dip plugdev lpadmin lxd sambashare

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

$ sudo usermod -a -G www-data byurrer

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

$ 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):

<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 добавить информацию о нашем сайте, чтобы наш локальный сервер при обращении к этому сайту обращался сам к себе:

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

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

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

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

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

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

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

$ sudo systemctl reload apache2

phpMyAdmin

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

$ 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 и переименовываем конфиг:

$ 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, устанавливаем:

$ sudo apt install php7.3-xml

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

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

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

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

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

Резюме

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

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

В телеграм канале DevOps от первого лица можно оставить комментарий или почитать интересные истории из практики DevOps