Различия
Показаны различия между двумя версиями страницы.
| linux:debian:apache_php-fpm [2023/09/08 14:22] – создано dx | linux:debian:apache_php-fpm [2023/09/19 01:35] (текущий) – dx | ||
|---|---|---|---|
| Строка 1: | Строка 1: | ||
| + | ====== Настройка PHP-FPM и Apache в Debian 12 ====== | ||
| + | {{: | ||
| + | |||
| + | Исходные данные | ||
| + | * Debian 12 (Bookworm) | ||
| + | * PHP из репозитория [[https:// | ||
| + | * Apache2 + [[https:// | ||
| + | |||
| + | Задача | ||
| + | * 2 виртуальных хоста с PHP 8.1 и 8.2 с отдельными fpm-pool с отдельными пользователями | ||
| + | * Сайт 1: пользователь batman, директория / | ||
| + | * Сайт 2: пользователь joker, директория / | ||
| + | * Ioncube для PHP 8.1 | ||
| + | * http2 | ||
| + | * SSL Let's Encrypt через модуль mod_md | ||
| + | * realip для Cloudflare | ||
| + | |||
| + | ===== Установка Apache ===== | ||
| + | |||
| + | <code bash>apt -y install apache2</ | ||
| + | |||
| + | Добавить в файл ''/ | ||
| + | |||
| + | <code bash> | ||
| + | |||
| + | У меня в Debian 12 по-умолчанию был **mpm_event**. Для других релизов Debian или для Ubuntu может быть потребуется выключить другие MPM и включить event | ||
| + | |||
| + | <code bash> | ||
| + | a2dismod mpm_prefork | ||
| + | a2dismod mpm_itk | ||
| + | a2enmod mpm_event | ||
| + | </ | ||
| + | |||
| + | ===== SSL/TLS ===== | ||
| + | |||
| + | [[linux: | ||
| + | |||
| + | ===== http2 ===== | ||
| + | |||
| + | Проверка через curl http/1.1 | ||
| + | |||
| + | < | ||
| + | # curl -I https:// | ||
| + | HTTP/1.1 200 OK | ||
| + | Date: Thu, 10 Aug 2023 14:48:56 GMT | ||
| + | Server: Apache/ | ||
| + | Strict-Transport-Security: | ||
| + | Last-Modified: | ||
| + | ETag: " | ||
| + | Accept-Ranges: | ||
| + | Content-Length: | ||
| + | Content-Type: | ||
| + | </ | ||
| + | |||
| + | Включаем модуль http2 | ||
| + | |||
| + | <code bash> | ||
| + | # a2enmod http2 | ||
| + | Enabling module http2. | ||
| + | To activate the new configuration, | ||
| + | systemctl restart apache2 | ||
| + | </ | ||
| + | |||
| + | В VirtualHost добавляем | ||
| + | |||
| + | <code bash> | ||
| + | < | ||
| + | Protocols h2 http/1.1 | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | Проверка через curl http/2 | ||
| + | |||
| + | <code bash> | ||
| + | # curl -I https:// | ||
| + | HTTP/2 200 | ||
| + | strict-transport-security: | ||
| + | last-modified: | ||
| + | etag: " | ||
| + | accept-ranges: | ||
| + | content-length: | ||
| + | content-type: | ||
| + | date: Thu, 10 Aug 2023 14:49:41 GMT | ||
| + | server: Apache/ | ||
| + | </ | ||
| + | |||
| + | ===== Установка PHP ===== | ||
| + | |||
| + | Следуем инструкции из [[https:// | ||
| + | |||
| + | <code bash> | ||
| + | wget -O sury.sh https:// | ||
| + | chmod +x sury.sh | ||
| + | sh sury.sh | ||
| + | </ | ||
| + | |||
| + | Устанавливаем PHP 8.1 | ||
| + | |||
| + | <code bash> | ||
| + | apt install -y php8.1-bcmath php8.2-bz2 php8.1-curl php8.1-fpm php8.1-gd php8.1-intl php8.1-mbstring php8.1-mcrypt php8.1-mysql php8.1-opcache php8.1-xml php8.1-xmlrpc php8.1-zip | ||
| + | </ | ||
| + | |||
| + | В конце установки будет предупреждение | ||
| + | |||
| + | <code bash> | ||
| + | NOTICE: Not enabling PHP 8.1 FPM by default. | ||
| + | NOTICE: To enable PHP 8.1 FPM in Apache2 do: | ||
| + | NOTICE: a2enmod proxy_fcgi setenvif | ||
| + | NOTICE: a2enconf php8.1-fpm | ||
| + | NOTICE: You are seeing this message because you have apache2 package installed. | ||
| + | </ | ||
| + | |||
| + | Устанавливаем PHP 8.2 | ||
| + | |||
| + | <code bash> | ||
| + | apt install -y php8.2-bcmath php8.2-bz2 php8.2-curl php8.2-fpm php8.2-gd php8.2-intl php8.2-mbstring php8.2-mcrypt php8.2-mysql php8.2-opcache php8.2-xml php8.2-xmlrpc php8.2-zip | ||
| + | </ | ||
| + | |||
| + | В конце установки будет предупреждение | ||
| + | |||
| + | <code bash> | ||
| + | NOTICE: Not enabling PHP 8.2 FPM by default. | ||
| + | NOTICE: To enable PHP 8.2 FPM in Apache2 do: | ||
| + | NOTICE: a2enmod proxy_fcgi setenvif | ||
| + | NOTICE: a2enconf php8.2-fpm | ||
| + | NOTICE: You are seeing this message because you have apache2 package installed. | ||
| + | </ | ||
| + | |||
| + | ===== PHP-FPM ===== | ||
| + | |||
| + | Проверяем статус php-fpm | ||
| + | |||
| + | <code bash> | ||
| + | systemctl status php8.1-fpm | ||
| + | systemctl status php8.2-fpm | ||
| + | </ | ||
| + | |||
| + | Для работы php-fpm в Apache нужны 2 модуля | ||
| + | |||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | |||
| + | Включаем модуль **proxy_fcgi** и **setenvif** | ||
| + | |||
| + | <code bash># a2enmod proxy_fcgi setenvif | ||
| + | Considering dependency proxy for proxy_fcgi: | ||
| + | Enabling module proxy. | ||
| + | Enabling module proxy_fcgi. | ||
| + | Module setenvif already enabled | ||
| + | To activate the new configuration, | ||
| + | systemctl restart apache2 | ||
| + | </ | ||
| + | |||
| + | Для обработки PHP кода добавляем в VirtualHost | ||
| + | |||
| + | Для 8.1 | ||
| + | |||
| + | <code bash> | ||
| + | < | ||
| + | # < | ||
| + | # расширенный FilesMatch для .phar, phtml | ||
| + | < | ||
| + | SetHandler " | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | Для 8.2 | ||
| + | |||
| + | <code bash> | ||
| + | < | ||
| + | < | ||
| + | SetHandler " | ||
| + | </ | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | Создаём пользователей и директории для PHP 8.1 и 8.2 | ||
| + | |||
| + | <code bash> | ||
| + | useradd batman | ||
| + | passwd batman | ||
| + | useradd joker | ||
| + | passwd joker | ||
| + | mkdir -p / | ||
| + | mkdir -p / | ||
| + | chown batman: | ||
| + | chown joker:joker / | ||
| + | </ | ||
| + | |||
| + | <WRAP round alert 75% center> | ||
| + | Для дополнительной безопасности при создании пользователя можно добавить '' | ||
| + | </ | ||
| + | |||
| + | Создаём файлы для вывода phpinfo(); | ||
| + | |||
| + | <code bash> | ||
| + | echo '<? | ||
| + | echo '<? | ||
| + | </ | ||
| + | |||
| + | Создаём виртуальные хосты с именами '' | ||
| + | |||
| + | Файл ''/ | ||
| + | |||
| + | <code bash> | ||
| + | < | ||
| + | Protocols h2 http/1.1 | ||
| + | DocumentRoot / | ||
| + | ServerAdmin [email protected] | ||
| + | ServerName batman.foobar.com | ||
| + | ServerAlias bruce.foobar.com | ||
| + | |||
| + | CustomLog | ||
| + | ErrorLog | ||
| + | |||
| + | # php-fpm handler | ||
| + | < | ||
| + | SetHandler " | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | Options -Indexes +FollowSymLinks | ||
| + | AllowOverride All | ||
| + | Require all granted | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | Файл ''/ | ||
| + | |||
| + | <code bash> | ||
| + | < | ||
| + | Protocols h2 http/1.1 | ||
| + | DocumentRoot / | ||
| + | ServerAdmin [email protected] | ||
| + | ServerName joker.foobar.com | ||
| + | ServerAlias harley.foobar.com | ||
| + | |||
| + | CustomLog | ||
| + | ErrorLog | ||
| + | |||
| + | # php-fpm handler | ||
| + | < | ||
| + | SetHandler " | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | Options -Indexes +FollowSymLinks | ||
| + | AllowOverride All | ||
| + | Require all granted | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | Включаем сайты через **a2ensite** | ||
| + | |||
| + | <code bash> | ||
| + | a2ensite batman joker | ||
| + | systemctl restart apache2 | ||
| + | </ | ||
| + | |||
| + | ===== FPM-POOL ===== | ||
| + | |||
| + | Файл ''/ | ||
| + | |||
| + | <code bash> | ||
| + | [batman-pool] | ||
| + | listen = / | ||
| + | listen.owner = batman | ||
| + | listen.group = batman | ||
| + | listen.mode = 0660 | ||
| + | user = batman | ||
| + | group = batman | ||
| + | pm = dynamic | ||
| + | </ | ||
| + | |||
| + | Файл ''/ | ||
| + | |||
| + | <code bash> | ||
| + | [joker-pool] | ||
| + | listen = / | ||
| + | listen.owner = joker | ||
| + | listen.group = joker | ||
| + | listen.mode = 0660 | ||
| + | user = joker | ||
| + | group = joker | ||
| + | pm = dynamic | ||
| + | </ | ||
| + | |||
| + | Это минимальный конфиг для работы. | ||
| + | |||
| + | Добавляем пользователя '' | ||
| + | |||
| + | <code bash> | ||
| + | usermod -a -G batman www-data | ||
| + | usermod -a -G joker www-data | ||
| + | </ | ||
| + | |||
| + | Ещё раз про chown | ||
| + | |||
| + | ❌ Неправильно: | ||
| + | * www-data: | ||
| + | * batman: | ||
| + | * www-data: | ||
| + | |||
| + | ✅ Правильно: | ||
| + | * batman: | ||
| + | * joker:joker | ||
| + | |||
| + | Если не добавить в группу будет нечто подобное | ||
| + | |||
| + | <code bash> | ||
| + | [proxy: | ||
| + | [proxy_fcgi: | ||
| + | </ | ||
| + | |||
| + | На что обратить внимание | ||
| + | * Каждый пул должен использовать отдельный сокет. Если несколько пулов используют один и тот же сокет будут проблемы. | ||
| + | * Директивы '' | ||
| + | * Директивы '' | ||
| + | * Директивы пула '' | ||
| + | * Права к сокету 0660 | ||
| + | |||
| + | Для примера и в качестве заметки для себя приложу свой 💥 боевой конфиг | ||
| + | |||
| + | < | ||
| + | <code bash> | ||
| + | [rtfm-74] | ||
| + | user = rtfm | ||
| + | group = rtfm | ||
| + | listen = / | ||
| + | listen.owner = rtfm | ||
| + | listen.group = rtfm | ||
| + | listen.backlog = 65535 | ||
| + | ;; | ||
| + | |||
| + | pm = dynamic | ||
| + | pm.max_children = 35 | ||
| + | pm.start_servers = 5 | ||
| + | pm.min_spare_servers = 1 | ||
| + | pm.max_spare_servers = 25 | ||
| + | |||
| + | slowlog = / | ||
| + | request_slowlog_timeout = 5s | ||
| + | request_terminate_timeout = 300s | ||
| + | |||
| + | ;;chdir = / | ||
| + | security.limit_extensions = .php .phar | ||
| + | catch_workers_output = yes | ||
| + | |||
| + | pm.status_path = /fpm-status | ||
| + | ping.path = /ping | ||
| + | |||
| + | php_admin_value[date.timezone] = UTC | ||
| + | php_admin_value[disable_functions] = passthru, | ||
| + | php_admin_value[cgi.fix_pathinfo] = 0 | ||
| + | php_admin_value[memory_limit] = 850M | ||
| + | php_admin_value[post_max_size] = 100M | ||
| + | php_admin_value[upload_max_filesize] = 100M | ||
| + | php_admin_value[max_file_uploads] = 35 | ||
| + | |||
| + | ;; admin_flags | ||
| + | php_admin_flag[expose_php] = off | ||
| + | php_admin_flag[display_errors] = off | ||
| + | php_admin_flag[display_startup_errors] = off | ||
| + | php_admin_flag[log_errors] = on | ||
| + | php_admin_flag[allow_url_fopen] = on | ||
| + | ;; | ||
| + | ;; | ||
| + | php_admin_flag[session.cookie_httponly] = on | ||
| + | ;; | ||
| + | php_admin_flag[session.cookie_secure] = on | ||
| + | |||
| + | ;; admin_values sessions | ||
| + | php_admin_value[session.cookie_lifetime] = 0 | ||
| + | php_admin_value[session.gc_maxlifetime] = 86400 | ||
| + | php_admin_value[session.save_handler] = files | ||
| + | php_admin_value[session.save_path] = / | ||
| + | ;; | ||
| + | |||
| + | ;; admin flag cookie | ||
| + | php_admin_flag[session.cookie_httponly] = on | ||
| + | php_admin_flag[session.use_cookies] = on | ||
| + | php_admin_flag[session.cookie_secure] = on | ||
| + | |||
| + | ;; admin values other | ||
| + | php_admin_value[error_reporting] = E_ALL & ~E_NOTICE | ||
| + | php_admin_value[upload_tmp_dir] = / | ||
| + | php_admin_value[open_basedir] = / | ||
| + | |||
| + | ;; logs | ||
| + | php_admin_value[mail.log] = / | ||
| + | php_admin_value[error_log] = / | ||
| + | |||
| + | ;; opcache | ||
| + | ;; | ||
| + | ;; | ||
| + | ;; | ||
| + | ;; | ||
| + | ;; | ||
| + | ;; | ||
| + | |||
| + | ;; | ||
| + | ;; | ||
| + | ;; | ||
| + | ;; | ||
| + | ;; | ||
| + | |||
| + | env[HOSTNAME] = $HOSTNAME | ||
| + | env[PATH] = / | ||
| + | env[TMP] = / | ||
| + | env[TMPDIR] = / | ||
| + | env[TEMP] = / | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | ===== phpinfo ===== | ||
| + | |||
| + | Проверяем вывод phpinfo по ссылкам batman.foobar.com/ | ||
| + | |||
| + | <tabbox php 8.1> | ||
| + | {{: | ||
| + | |||
| + | <tabbox php 8.2> | ||
| + | {{: | ||
| + | </ | ||
| + | |||
| + | ===== Проверка FPM-POOL ===== | ||
| + | |||
| + | Создаём файл '' | ||
| + | |||
| + | <code bash> | ||
| + | echo "<? | ||
| + | echo "<? | ||
| + | </ | ||
| + | |||
| + | В браузере '' | ||
| + | |||
| + | <code bash> | ||
| + | uid=1000(batman) gid=1000(batman) groups=1000(batman) | ||
| + | uid=1001(joker) gid=1001(joker) groups=1001(joker) | ||
| + | </ | ||
| + | |||
| + | ===== FPM status ===== | ||
| + | |||
| + | Настраиваем [[https:// | ||
| + | |||
| + | В конфиг пула добавляем | ||
| + | |||
| + | <code bash> | ||
| + | pm.status_path = /status | ||
| + | ping.path = /ping | ||
| + | </ | ||
| + | |||
| + | В конфиг виртуального хоста добавляем | ||
| + | |||
| + | <code bash> | ||
| + | < | ||
| + | SetHandler " | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | Alias / | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | Формат данных - html, json, openmetrics (какая-то новинка), | ||
| + | |||
| + | Также стоит добавить в конфиг **Require local** или **Require ip 192.168.100.0/ | ||
| + | |||
| + | ==== HTML ==== | ||
| + | |||
| + | URL | ||
| + | * http:// | ||
| + | * http:// | ||
| + | |||
| + | <tabbox HTML> | ||
| + | {{: | ||
| + | <tabbox HTML full> | ||
| + | {{: | ||
| + | </ | ||
| + | |||
| + | ==== JSON ==== | ||
| + | |||
| + | URL | ||
| + | * http:// | ||
| + | * http:// | ||
| + | |||
| + | <tabbox JSON> | ||
| + | {{: | ||
| + | <tabbox JSON full> | ||
| + | {{: | ||
| + | </ | ||
| + | |||
| + | ==== XML ==== | ||
| + | |||
| + | URL | ||
| + | * http:// | ||
| + | * http:// | ||
| + | |||
| + | <tabbox XML> | ||
| + | {{: | ||
| + | |||
| + | <tabbox XML full> | ||
| + | {{: | ||
| + | </ | ||
| + | |||
| + | ==== Realtime ==== | ||
| + | |||
| + | URL - https:// | ||
| + | |||
| + | //GIF 400+ КБ// | ||
| + | <hidden fpm status realtime> | ||
| + | {{: | ||
| + | </ | ||
| + | |||
| + | На странице [[https:// | ||
| + | ===== Cloudflare realip/ | ||
| + | |||
| + | Если для домена подключен Cloudflare, то необходима настройка для отображения реальных IP адресов с помощью **mod_remoteip** - [[https:// | ||
| + | |||
| + | ===== Ioncube ===== | ||
| + | |||
| + | Основная статья [[linux: | ||
| + | |||
| + | Смотрим **extension_dir** для версии PHP 8.1 | ||
| + | |||
| + | <code bash> | ||
| + | # php8.1 -i | grep extension_dir | ||
| + | extension_dir => / | ||
| + | </ | ||
| + | |||
| + | Копируем .so файл по указанному выше пути | ||
| + | |||
| + | <code bash> | ||
| + | cd ioncube && cp ./ | ||
| + | </ | ||
| + | |||
| + | Подключаем .so модуль к PHP | ||
| + | |||
| + | <code bash> | ||
| + | # echo "; priority=10\nzend_extension=/ | ||
| + | </ | ||
| + | |||
| + | Теперь нужно активировать модуль через **phpenmod**. Т.к. установлено 2 версии PHP ([[https:// | ||
| + | |||
| + | <code bash> | ||
| + | # update-alternatives --query php | ||
| + | Name: php | ||
| + | Link: / | ||
| + | Slaves: | ||
| + | | ||
| + | Status: auto | ||
| + | Best: / | ||
| + | Value: / | ||
| + | |||
| + | Alternative: | ||
| + | Priority: 81 | ||
| + | Slaves: | ||
| + | | ||
| + | |||
| + | Alternative: | ||
| + | Priority: 82 | ||
| + | Slaves: | ||
| + | | ||
| + | </ | ||
| + | |||
| + | необходимо указать версию PHP, по-умолчанию phpenmod работает с версией PHP 8.2 | ||
| + | |||
| + | <code bash> | ||
| + | phpenmod -v 8.1 ioncube | ||
| + | </ | ||
| + | |||
| + | Если не указать '' | ||
| + | |||
| + | <code bash> | ||
| + | |||
| + | И у ioncube будет приоритет 20 | ||
| + | |||
| + | <code bash> | ||
| + | # ls -la / | ||
| + | lrwxrwxrwx 1 root root 39 Jul 19 12:28 20-ioncube.ini -> / | ||
| + | </ | ||
| + | |||
| + | Проверяем, | ||
| + | |||
| + | <code bash> | ||
| + | # php8.1 -v | ||
| + | PHP 8.1.21 (cli) (built: Jul 16 2023 11:01:21) (NTS) | ||
| + | Copyright (c) The PHP Group | ||
| + | Zend Engine v4.1.21, Copyright (c) Zend Technologies | ||
| + | with the ionCube PHP Loader v12.0.5, Copyright (c) 2002-2022, by ionCube Ltd. | ||
| + | with Zend OPcache v8.1.21, Copyright (c), by Zend Technologies | ||
| + | </ | ||
| + | |||
| + | ===== mod_proxy ===== | ||
| + | |||
| + | Вроде бы прокси запросы по-умолчанию запрещены, | ||
| + | |||
| + | <WRAP round info 50% center> | ||
| + | If you want to use apache2 as a forward proxy, uncomment the\\ | ||
| + | # ' | ||
| + | # WARNING: Be careful to restrict access inside the <Proxy *> block.\\ | ||
| + | # Open proxy servers are dangerous both to your network and to the\\ | ||
| + | # Internet at large. | ||
| + | </ | ||
| + | |||
| + | Добавляем в ''/ | ||
| + | |||
| + | <code bash> | ||
| + | <Proxy *> | ||
| + | | ||
| + | | ||
| + | | ||
| + | </ | ||
| + | </ | ||
| + | |||
| + | ===== Дополнительные настройки ===== | ||
| + | |||
| + | Включаем **mod_rewrite** - [[https:// | ||
| + | |||
| + | <code bash> | ||
| + | |||
| + | Включаем **mod_headers** - [[https:// | ||
| + | |||
| + | <code bash> | ||
| + | |||
| + | ===== Ссылки ===== | ||
| + | |||
| + | * https:// | ||
| + | * https:// | ||
| + | * https:// | ||
| + | * https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | * [[https:// | ||
| + | |||
| + | EOM | ||
| + | |||
| + | {{tag> | ||