Установка Apache + PHP-FastCGI для NGINX на Alma Linux 8

Установка, настройка NGINX+certbot

необходимые пакеты

dnf install --enablerepo=powertools wget libxml2-devel sqlite-devel bzip2-devel oniguruma-devel libcurl-devel libpq-devel autoconf

установка Apache 2 и mod_fcgid

dnf install httpd mod_fcgid

создание папок для php:

mkdir -p /opt/source/php && mkdir -p /opt/php/

актуальные версии PHP для скачивания доступна по адресу: https://www.php.net/downloads

переход в директорию в которой будут храниться исходники php:

cd /opt/source/php

скачивание необходимой версию php:

wget https://www.php.net/distributions/php-8.2.17.tar.gz

распаковать архив:

tar -xzvf php-8.2.17.tar.gz

перейти в распакованную папку:

cd php-8.2.17

конфигурирование php:

./configure --prefix=/opt/php/php-8.2 --disable-rpath --enable-calendar --enable-fpm --enable-ftp --enable-mbstring --enable-pcntl --enable-soap --enable-sockets --enable-sysvsem --enable-sysvshm --with-bz2 --with-curl --enable-dba --with-zlib --with-gettext --with-mhash --with-mysqli --with-openssl --with-pdo-mysql --with-pdo-pgsql

в строке —prefix=/opt/php/php-8.2 указана директория, где будет собран проект.

пример успешного результата конфигурирования:

...
checking whether to build shared libraries... yes
checking whether to build static libraries... yes

creating libtool
appending configuration tag "CXX" to libtool

Generating files
configure: patching main/php_config.h.in
configure: creating ./config.status
creating main/internal_functions.c
creating main/internal_functions_cli.c
config.status: creating main/build-defs.h
config.status: creating scripts/phpize
config.status: creating scripts/man1/phpize.1
config.status: creating scripts/php-config
config.status: creating scripts/man1/php-config.1
config.status: creating sapi/cli/php.1
config.status: creating sapi/fpm/php-fpm.conf
config.status: creating sapi/fpm/www.conf
config.status: creating sapi/fpm/init.d.php-fpm
config.status: creating sapi/fpm/php-fpm.service
config.status: creating sapi/fpm/php-fpm.8
config.status: creating sapi/fpm/status.html
config.status: creating sapi/phpdbg/phpdbg.1
config.status: creating sapi/cgi/php-cgi.1
config.status: creating ext/phar/phar.1
config.status: creating ext/phar/phar.phar.1
config.status: creating main/php_config.h
config.status: executing default commands

+--------------------------------------------------------------------+
| License:                                                           |
| This software is subject to the PHP License, available in this     |
| distribution in the file LICENSE. By continuing this installation  |
| process, you are bound by the terms of this license agreement.     |
| If you do not agree with the terms of this license, you must abort |
| the installation process at this point.                            |
+--------------------------------------------------------------------+

Thank you for using PHP.

запуск компиляции (-j<количество задействованных ядер процесора>):

make -j2

успешный результат:

...
Generating phar.php
Generating phar.phar
PEAR package PHP_Archive not installed: generated phar will require PHP's phar extension be enabled.
clicommand.inc
directorygraphiterator.inc
directorytreeiterator.inc
invertedregexiterator.inc
phar.inc
pharcommand.inc

Build complete.
Don't forget to run 'make test'.

установить:

make install

результат:

Installing shared extensions:     /opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/
Installing PHP CLI binary:        /opt/php/php-8.2/bin/
Installing PHP CLI man page:      /opt/php/php-8.2/php/man/man1/
Installing PHP FPM binary:        /opt/php/php-8.2/sbin/
Installing PHP FPM defconfig:     /opt/php/php-8.2/etc/
Installing PHP FPM man page:      /opt/php/php-8.2/php/man/man8/
Installing PHP FPM status page:   /opt/php/php-8.2/php/php/fpm/
Installing phpdbg binary:         /opt/php/php-8.2/bin/
Installing phpdbg man page:       /opt/php/php-8.2/php/man/man1/
Installing PHP CGI binary:        /opt/php/php-8.2/bin/
Installing PHP CGI man page:      /opt/php/php-8.2/php/man/man1/
Installing build environment:     /opt/php/php-8.2/lib/php/build/
Installing header files:          /opt/php/php-8.2/include/php/
Installing helper programs:       /opt/php/php-8.2/bin/
  program: phpize
  program: php-config
Installing man pages:             /opt/php/php-8.2/php/man/man1/
  page: phpize.1
  page: php-config.1
Installing PDO headers:           /opt/php/php-8.2/include/php/ext/pdo/

проверить работу php:

/opt/php/php-8.2/bin/php -v

успешный результат:

PHP 8.2.17 (cli) (built: Mar 23 2024 20:05:27) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.2.17, Copyright (c) Zend Technologies

 

Для работы PHP в системе на него нужно сделать ярлык /usr/bin/php:

ln -s /opt/php/php-8.2/bin/php /usr/bin/php

проверить работу php:

php -v

скопировать конфигурационный файл из установки:

cp /opt/source/php/php-8.2.17/php.ini-production /opt/php/php-8.2/lib/php.ini

или создать php.ini по пути /opt/php/php-8.2/lib/php.ini с содержимым:

[PHP]
; Механизм языка сценариев PHP в Apache
engine = On

; Разрешить принимать теги <? и ?>, а не только <?php и ?>
short_open_tag = On

; кол-во символов после точки в числах с плавающей точкой
precision = 14

; максимальный буфер который php формирует перед отдачей веб-серверу
; если объем данных выше указанного то php отдает по кусочкам ответ
output_buffering = 4096

; сжатие результата при помощи zlib (т.к. php работает через веб-сервер - сжимать не нужно)
zlib.output_compression = Off

; отменить буфиризирование.
; если включить то все, что будет print или echo сразу отправляться на вывод
; не учитывая output_buffering. аналог выполнения функции flush()
implicit_flush = Off

unserialize_callback_func =
serialize_precision = -1

; отключение указанных функций. перечислять через запятую
disable_functions =

; отключение указанных классов. перечислять через запятую
disable_classes =

; включение или исключение сборщика циклических ссылок
zend.enable_gc = On

; включение или исключение аргументов из трассировок стека, полученных в исключениях
zend.exception_ignore_args = On

; установка максимальной длины строки в аргументе строковой трассировки стека
zend.exception_string_param_max_len = 0

; включить или выключить отображение информации о PHP в заголовках ответа
expose_php = Off

; максимальное время выполнения скрипта в секундах
max_execution_time = 30

; максимальное время которое тратит скрипт на анализ входных данных в секундах
; к примеру ожидание загружаемого файла
max_input_time = 60

; максимальное кол-во ОЗУ для скрипта
memory_limit = 512M

; какие ошибки выводить
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

; выводить или нет ошибки
display_errors = Off

; выводить или нет ошибки которые возникают при запуске PHP
display_startup_errors = Off

; записывать или нет ошибки в журнал
log_errors = On

; игнорировать ошибку возникшую в том-же файле и тойже строке если она произошла повторно
ignore_repeated_errors = Off

; игнорировать повторяющуюся ошибку возникшую в любом файле и любой строке если она произошла повторно
ignore_repeated_source = Off

; показывать ошибки об утечки памяти. отображается в E_WARNING списке. полезно при отладке
report_memleaks = On

; какие super global массивы регистрируются при запуске. G,P,C,E,S являются первой буквой
; глобальных массивов: GET, POST, COOKIE, ENV, SERVER. значение EGPCS - подключит все
variables_order = "GPCS"

; определение какие super global данные должны быть в массиве REQUEST. G,P,C являются
; первой буквой массивов: GET, POST, COOKIE
request_order = "GP"

; регистрировать ли $argv и $argc каждый раз при запуске.
; $argv - массив аргументов переданный PHP при запуске, $argc - кол-во аргументов
register_argc_argv = Off

; если включена то будет лучше производительность, но при выключеном register_argc_argv.
; переменные ENV, REQUEST и SERVER создаются при первом к ним обращении в скриптах
auto_globals_jit = On

; масксимальный объем данных в POST запросе которые обработает PHP
post_max_size = 512M

; указать путь в скрипту который будет всегда запускаться вначале выполнения.
; файл вызывется по аналогии функции require
auto_prepend_file =

; указать путь в скрипту который будет всегда запускаться после выполнения.
; файл вызывется по аналогии функции require
auto_append_file =

; по умолчанию Content-Type
default_mimetype = "text/html"

; кодировка по умолчанию
default_charset = "UTF-8"

; корень проекта по умолчанию. НЕ УКАЗЫВАТЬ при использовании с веб-сервером
doc_root =

; каталог скриптов по умолчанию. НЕ УКАЗЫВАТЬ при использовании с веб-сервером
user_dir =

; путь к директории с расширениями
;extension_dir = "./"

; путь к директории с временными файлами
;sys_temp_dir = "/tmp"

; динамическая подгрузка расширений. не рекомендуется включать в целях безопасности.
enable_dl = Off

; https://php.net/cgi.force-redirect
;cgi.force_redirect = 1

; если включен, то cgi всегда будет возвращать статус 200
;cgi.nph = 1

; https://php.net/cgi.redirect-status-env
;cgi.redirect_status_env =

; https://php.net/cgi.fix-pathinfo
cgi.fix_pathinfo=1

; если включен, то PHP CGI может располагатся вне публичной части
;cgi.discard_path=1

; https://php.net/fastcgi.impersonate
;fastcgi.impersonate = 1

; отключить уведомления в журнал при соединениях FastCGI.
;fastcgi.logging = 0

; для Apache значение 1, для прямого доступа 0. RFC2616
cgi.rfc2616_headers = 1

; https://php.net/cgi.check-shebang-line
;cgi.check_shebang_line=1

; разрешить обрабатывать загруженные файлы
file_uploads = On

; путь к временной директории с загруженными файлами
;upload_tmp_dir =

; максимальный объем загружаемого файла
upload_max_filesize = 512M

; максимальное кол-во файлов в одном запросе
max_file_uploads = 20

; разрешить функцией fopen открывать через URLs (к примеру http:// or ftp://)
allow_url_fopen = On

; Whether to allow include/require to open URLs (like https:// or ftp://) as files.
; https://php.net/allow-url-include
; разрешить подключать скрипты (include/require) через URLs (к примеру http:// or ftp://)
allow_url_include = Off

; timeout по умолчанию для socket соединений
default_socket_timeout = 60

; подключение readline
;extension=/opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/readline.so

; подключение ldap
;extension=/opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/ldap.so

; подключение memcached
;extension=/opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/memcached.so

; подключение redis
;extension=/opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/redis.so

[CLI Server]
; Whether the CLI web server uses ANSI color coding in its terminal output.
cli_server.color = On

[Date]
; timezone по умолчанию
date.timezone = "Europe/Moscow"

[Pdo_mysql]
; путь к сокету MySQL. узнать сокет можно в консоли: mysql -u root -p
; show variables like '%sock%';
; Variable_name: socket; частый результат: /var/lib/mysqld/mysqld.sock
pdo_mysql.default_socket=/var/lib/mysql/mysql.sock

[mail function]
SMTP = localhost
smtp_port = 25

; опция позволяет включить логирование отправки почты из скриптов сайта
; логи будут содержать полный путь до скрипта, адрес получателя и заголовки
mail.add_x_header = Off
; путь для хранения логов
;mail.log =

; использовать вместе LF и CRLF для разделения строк
mail.mixed_lf_and_crlf = Off

[ODBC]
; разрешать ли постоянные соединения ODBC
odbc.allow_persistent = On

; перед повторным запросом проверить, что соединение всё ещё доступно
odbc.check_persistent = On

; максимальное кол-во постоянных соединений ODBC на процесс. если -1 то безлимитно.
odbc.max_persistent = -1

; максимальное количество соединений ODBC на процесс, включая постоянные соединения.
odbc.max_links = -1

; обработка длинных (LONG) полей. Определяет количество байтов, возвращаемых переменным
odbc.defaultlrl = 4096

; обработка двоичных данных. 0 - проход; 1 - как есть; 2 - преобразует в символ
odbc.defaultbinmode = 1

[MySQLi]
; максимально возможное количество постоянных соединений
mysqli.max_persistent = -1

; включает возможность создавать постоянные соединения с помощью mysqli_connect()
mysqli.allow_persistent = On

; максимальное количество соединений MySQL на процесс
mysqli.max_links = -1

; TCP-порт, используемый по умолчанию для соединения с сервером MySQL
mysqli.default_port = 3306

; имя сокета по умолчанию, которое используется для соединения с локальной базой данных,
; если имя сокета не было указано явно
mysqli.default_socket=/var/lib/mysql/mysql.sock
mysqli.default_host =
mysqli.default_user =
mysqli.default_pw =

[mysqlnd]
; Enable / Disable collection of general statistics by mysqlnd which can be
; used to tune and monitor MySQL operations.
mysqlnd.collect_statistics = On

; Enable / Disable collection of memory usage statistics by mysqlnd which can be
; used to tune and monitor MySQL operations.
mysqlnd.collect_memory_statistics = Off

[PostgreSQL]
; https://php.net/pgsql.allow-persistent
pgsql.allow_persistent = On

; https://php.net/pgsql.auto-reset-persistent
pgsql.auto_reset_persistent = Off

; https://php.net/pgsql.max-persistent
pgsql.max_persistent = -1

; https://php.net/pgsql.max-links
pgsql.max_links = -1

; https://php.net/pgsql.ignore-notice
pgsql.ignore_notice = 0

; https://php.net/pgsql.log-notice
pgsql.log_notice = 0

[bcmath]
; Кол-во десятичных цифр для всех функций bcmath
bcmath.scale = 0

[browscap]
; https://php.net/browscap
;browscap = extra/browscap.ini

[Session]
; обработчик хранения данных сессии
; https://php.net/session.save-handler
session.save_handler = files

; если обработчик files, то можно указать путь хранения данных сессий
; https://php.net/session.save-path
;session.save_path = "/tmp"

; разрешать соединения только при наличии сессии
; https://wiki.php.net/rfc/strict_sessions
session.use_strict_mode = 0

; использовать-ли cookies.
; https://php.net/session.use-cookies
session.use_cookies = 1

; https://php.net/session.cookie-secure
;session.cookie_secure =

; https://php.net/session.use-only-cookies
session.use_only_cookies = 1

; наименование сессии
session.name = PHPSESSID

; инициализировать сеанс автоматически при всех запросах
; https://php.net/session.auto-start
session.auto_start = 0

; время жизни сессии в секундах. если 0, то до перезапуска браузера
session.cookie_lifetime = 0

; путь для cookie
session.cookie_path = /

; домен для cookie
session.cookie_domain =

; включить httpOnly, тогда сессия не будет доступна для сценариев JavaScript
session.cookie_httponly =

; параметр SameSite для разрешения межсайтовых запросов. принимает одно из: "Strict", "Lax" or "None"
session.cookie_samesite =

; обработчик, используемый для сериализации данных
session.serialize_handler = php

; https://php.net/session.gc-probability
session.gc_probability = 1

; https://php.net/session.gc-divisor
session.gc_divisor = 1000

; время жизни сессии в секундах
session.gc_maxlifetime = 86400

; https://php.net/session.referer-check
session.referer_check =

; https://php.net/session.cache-limiter
session.cache_limiter = nocache

; https://php.net/session.cache-expire
session.cache_expire = 180

; https://php.net/session.use-trans-sid
session.use_trans_sid = 0

; кол-во символов ID сессии. можно указать от 22 до 256.
session.sid_length = 32

; https://php.net/url-rewriter.tags
session.trans_sid_tags = "a=href,area=href,frame=src,form="

; сколько бит будет для генерации ID:
;   4  (4 bits: 0-9, a-f)
;   5  (5 bits: 0-9, a-v)
;   6  (6 bits: 0-9, a-z, A-Z, "-", ",")
session.sid_bits_per_character = 5

[Assertion]
; https://php.net/zend.assertions
zend.assertions = -1


[Tidy]
; https://php.net/tidy.default-config
;tidy.default_config = /usr/local/lib/php/default.tcfg

; https://php.net/tidy.clean-output
tidy.clean_output = Off

[soap]
; https://php.net/soap.wsdl-cache-enabled
soap.wsdl_cache_enabled=1

; https://php.net/soap.wsdl-cache-dir
soap.wsdl_cache_dir="/tmp"

; https://php.net/soap.wsdl-cache-ttl
soap.wsdl_cache_ttl=86400

; Sets the size of the cache limit. (Max. number of WSDL files to cache)
soap.wsdl_cache_limit = 5

[sysvshm]
; A default size of the shared memory segment
;sysvshm.init_mem = 10000

[ldap]
; Sets the maximum number of open links or -1 for unlimited.
ldap.max_links = -1

создаем файл /opt/php/php-8.2/etc/php-fpm.conf с содержимым:

[global]
include=/opt/php/php-8.2/etc/php-fpm.d/*.conf

создаем файл /opt/php/php-8.2/etc/php-fpm.d/www.conf с содержимым:

[www]
user = apache
group = apache

listen = 127.0.0.1:9000

pm = dynamic

pm.max_children = 5

pm.start_servers = 2

pm.min_spare_servers = 1

pm.max_spare_servers = 3

создаем файл /etc/systemd/system/php-fpm-8-2.service для сервиса php-fpm с содержимым:

[Unit]
Description=PHP 8.2 FastCGI process manager
After=local-fs.target network.target nginx.service

[Service]
PIDFile=/opt/php/php-fpm-8-2.pid
ExecStart=/opt/php/php-8.2/sbin/php-fpm --fpm-config /opt/php/php-8.2/etc/php-fpm.conf -c /opt/php/php-8.2/lib/php.ini --nodaemonize
Type=simple

[Install]
WantedBy=multi-user.target

перечитать демоны:

systemctl daemon-reload

запустить сервис:

systemctl start php-fpm-8-2

поставить сервис на автозапуск:

systemctl enable php-fpm-8-2

 

Конфигурирование HTTPD

создать файл /etc/httpd/conf/httpd.conf и заполнить:

ServerTokens Prod
ServerRoot "/etc/httpd"
PidFile run/httpd.pid

KeepAlive Off

MaxKeepAliveRequests 100

KeepAliveTimeout 15

<IfModule worker.c>
	StartServers         2
	MaxClients         150
	MinSpareThreads     25
	MaxSpareThreads     75
	ThreadsPerChild     25
	MaxRequestsPerChild  0
</IfModule>

Include conf.modules.d/*.conf

<IfModule setenvif_module>
    SetEnvIf X-Forwarded-Scheme https HTTPS=on
    SetEnvIf X-Forwarded-Proto https HTTPS=on
</IfModule>

User apache
Group apache

ServerAdmin web-rise@ya.ru

UseCanonicalName Off

DocumentRoot "/var/www/html"

<Directory />
	Options FollowSymLinks
	AllowOverride None
</Directory>

<IfModule mod_userdir.c>
	UserDir disable
</IfModule>

DirectoryIndex index.php index.html
AccessFileName .htaccess

<Files ~ "^\.ht">
    Require all denied
</Files>

TypesConfig /etc/mime.types
#ForceType text/plain
<IfModule mod_mime_magic.c>
	MIMEMagicFile conf/magic
</IfModule>

HostnameLookups Off
ErrorLog logs/error_log

LogLevel warn
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent

CustomLog logs/access_log combined

ServerSignature On

<IfModule mod_autoindex.c>
	IndexOptions FancyIndexing VersionSort NameWidth=* HTMLTable
	IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t
</IfModule>

AddDefaultCharset UTF-8

AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz

AddHandler type-map var
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml

BrowserMatch "Mozilla/2" nokeepalive
BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0
BrowserMatch "RealPlayer 4\.0" force-response-1.0
BrowserMatch "Java/1\.0" force-response-1.0
BrowserMatch "JDK/1\.0" force-response-1.0

IncludeOptional vhosts.conf

создать файл /etc/httpd/vhosts.conf и заполнить:

# основной хост
Listen 127.0.0.1:9888
<VirtualHost 127.0.0.1:9888>

    # указать реальный ip для $_SERVER["REMOTE_ADDR"]
    RemoteIPHeader X-Real-IP

    <Directory />
        AllowOverride All
    </Directory>

    DocumentRoot /var/www/html

    # обработка php файлов через php-fpm
    <FilesMatch \.php$>
        SetHandler proxy:fcgi://127.0.0.1:9000
    </FilesMatch>

    ErrorLog /var/www/logs/error.log
    CustomLog /var/www/logs/access.log combined

</VirtualHost>

создать директорию для логов http

mkdir /var/www/logs

все веб-файлы основного хоста сделать под пользователем nginx:

chown -R apache:apache /var/www

добавить пользователя nginx в группу к пользователю apache:

usermod -aG apache nginx

запустить и добавить в автозагрузку httpd:

systemctl start httpd && systemctl enable httpd

изменить конфиг nginx /etc/nginx/vhost.conf:

server {

    listen       0.0.0.0:80 default_server;
    server_name  srv01.example.com;

    return 301 https://$host$request_uri;

}

server {

    listen       0.0.0.0:443 ssl http2 default_server;
    server_name  srv01.example.com;

    include conf.d/ssl.conf;

    ssl_certificate /etc/letsencrypt/live/s018.yourtunes.net/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/s018.yourtunes.net/privkey.pem;

    index index.php index.html index.htm;
    root /var/www/html;

    location / {
        try_files $uri $uri/ @httpd;
    }

    if ($request_filename ~* \.(css|js|gif|png|jpg|jpeg|ico)$) {
        break;
    }

    location ~ \.php {
        proxy_pass http://127.0.0.1:9888;
        proxy_redirect http://127.0.0.1:9888 /;
        proxy_set_header Host $host:443;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        access_log off;
    }

    location @httpd {
        proxy_pass http://127.0.0.1:9888;
        proxy_redirect http://127.0.0.1:9888 /;
        proxy_set_header Host $host:443;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        access_log off;
    }

}

перечитать конфиги nginx:

nginx -s reload

создать файл /var/www/html/info.php для теста с содержимым:

<?php

phpinfo();

перейти по хосту и убедится, что все работает.

заглушка /var/www/html/index.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>server</title>
  </head>
  <body>
    <h1>server</h1>
  </body>
</html>

 

Добавление пользователя и хоста

Для примера:

  • пользователь: test
  • домен: test.example.com

создание пользователя:

useradd test

задать пароль пользователю:

passwd test

добавить пользователя apache в группу к пользователю test:

usermod -aG test apache

добавить пользователя nginx в группу к пользователю test:

usermod -aG test nginx

открыть доступ к папке пользователя test для группы test:

chmod 0750 /home/test

создать директории для проекта и присвоить их пользователю:

mkdir /home/test/{public,logs,session} && chown -R test:test /home/test

добавить в файл /etc/nginx/vhosts.conf:

# ...
# test.example.com
server {

    listen       0.0.0.0:80;
    server_name  test.example.com;

    index index.php index.html index.htm;
    root /home/test/public;

}

перечитать конфиги на nginx:

nginx -s reload

добавить сертификат к домену:

certbot --nginx -d test.example.com

изменить виртуальный хост test.example.com в конфиге nginx /etc/nginx/vhosts.conf:

# ...
# test.example.com
server {

    listen       0.0.0.0:80;
    server_name  test.example.com;

    return 301 https://$host$request_uri;

}
# test.example.com
server {

    listen       0.0.0.0:443 ssl http2;
    server_name  test.example.com;

    include conf.d/ssl.conf;

    ssl_certificate /etc/letsencrypt/live/test.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/test.example.com/privkey.pem;

    index index.php index.html index.htm;
    root /home/test/public;

    location / {
        try_files $uri $uri/ @httpd;
    }

    if ($request_filename ~* \.(css|js|gif|png|jpg|jpeg|ico)$) {
        break;
    }

    location ~ \.php {
        proxy_pass http://127.0.0.1:9887;
        proxy_redirect http://127.0.0.1:9887 /;
        proxy_set_header Host $host:443;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        access_log off;
    }

    location @httpd {
        proxy_pass http://127.0.0.1:9887;
        proxy_redirect http://127.0.0.1:9887 /;
        proxy_set_header Host $host:443;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        access_log off;
    }

}

создать и заполнить /opt/php/php-8.2/etc/php-fpm.d/test.conf:

[test]
user = test
group = test

listen = 127.0.0.1:9001

pm = dynamic

pm.max_children = 5

pm.start_servers = 2

pm.min_spare_servers = 1

pm.max_spare_servers = 3

php_value[session.save_path] = /home/test/session

добавить в файл /etc/httpd/vhosts.conf:

# test.example.com
Listen 127.0.0.1:9887
<VirtualHost 127.0.0.1:9887>

    # указать реальный ip для $_SERVER["REMOTE_ADDR"]
    RemoteIPHeader X-Real-IP

    <Directory />
        AllowOverride All
    </Directory>

    DocumentRoot /home/test/public

    <FilesMatch \.php$>
        SetHandler proxy:fcgi://127.0.0.1:9001
    </FilesMatch>

    ErrorLog /home/test/logs/error.log
    CustomLog /home/test/logs/access.log combined

</VirtualHost>

перезапустить php-fpm, httpd, nginx:

systemctl restart php-fpm-8-2 && systemctl restart httpd && nginx -s reload

в данном примере публичная часть файлов выкладывается в директорию: /home/test/public

 

Дополнительные расширения

ldap

скачать расширение ldap под php 8.2.17

установить openldap-devel:

dnf install openldap-devel

для PHP расширения ldap нужно сделать ярлык на libldap.so:

ln -s /usr/lib64/libldap.so /usr/lib/libldap.so

перейти в директорию дополнения ldap:

cd /opt/source/php/php-8.2.17/ext/ldap

выполнить phpize для создания configure:

/opt/php/php-8.2/bin/phpize

выполнить configure:

./configure --with-php-config=/opt/php/php-8.2/bin/php-config

при успешном конфигурировании:

...
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no

creating libtool
appending configuration tag "CXX" to libtool
configure: patching config.h.in
configure: creating ./config.status
config.status: creating config.h

подготовить к установке:

make

успешный результат:

...
(cd .libs && rm -f ldap.la && ln -s ../ldap.la ldap.la)
/bin/sh /opt/source/php/php-8.2.17/ext/ldap/libtool --tag=CC --mode=install cp ./ldap.la /opt/source/php/php-8.2.17/ext/ldap/modules
cp ./.libs/ldap.so /opt/source/php/php-8.2.17/ext/ldap/modules/ldap.so
cp ./.libs/ldap.lai /opt/source/php/php-8.2.17/ext/ldap/modules/ldap.la
PATH="$PATH:/sbin" ldconfig -n /opt/source/php/php-8.2.17/ext/ldap/modules
----------------------------------------------------------------------
Libraries have been installed in:
   /opt/source/php/php-8.2.17/ext/ldap/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.

установка:

make install

успешный результат (отображает путь где лежит memcached.so):

Installing shared extensions:     /opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/

добавить путь к дополнению в php.ini в группе [PHP]:

[PHP]
...
extension=/opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/ldap.so

перезапустить сервис php-fpm:

systemctl restart php-fpm-8-2

 

gd

установить libpng-devel:

dnf install libpng-devel libjpeg-turbo libjpeg-turbo-devel libwebp-devel libwebp

перейти в директорию дополнения gd:

cd /opt/source/php/php-8.2.17/ext/gd

выполнить phpize для создания configure:

/opt/php/php-8.2/bin/phpize

выполнить configure:

./configure --with-php-config=/opt/php/php-8.2/bin/php-config --with-jpeg --with-webp 

configure на старых версиях php 7.3 и ниже:

./configure --with-php-config=/opt/php/php-7.3/bin/php-config --with-webp-dir --with-jpeg-dir --with-png-dir --with-zlib-dir

при успешном конфигурировании:

...
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no

creating libtool
appending configuration tag "CXX" to libtool
configure: patching config.h.in
configure: creating ./config.status
config.status: creating config.h

скомпилировать:

make

успешный результат:

...
cp ./.libs/gd.so /opt/source/php/php-7.4.33/ext/gd/modules/gd.so
cp ./.libs/gd.lai /opt/source/php/php-7.4.33/ext/gd/modules/gd.la
PATH="$PATH:/sbin" ldconfig -n /opt/source/php/php-7.4.33/ext/gd/modules
----------------------------------------------------------------------
Libraries have been installed in:
   /opt/source/php/php-7.4.33/ext/gd/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.

установка:

make install

успешный результат (отображает путь где лежит readline.so):

Installing shared extensions:     /opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/
Installing header files:          /opt/php/php-8.2/include/php/

добавить путь к дополнению в php.ini в группе [PHP]:

[PHP]
...
extension=/opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/gd.so

перезапустить сервис php-fpm:

systemctl restart php-fpm-8-2

 

readline

скачать расширение readline под php 8.2.17

установить libedit-devel:

dnf --enablerepo=powertools install libedit-devel

перейти в директорию дополнения readline:

cd /opt/source/php/php-8.2.17/ext/readline

выполнить phpize для создания configure:

/opt/php/php-8.2/bin/phpize

выполнить configure:

./configure --with-php-config=/opt/php/php-8.2/bin/php-config

при успешном конфигурировании:

...
checking whether -lc should be explicitly linked in... no
checking dynamic linker characteristics... GNU/Linux ld.so
checking how to hardcode library paths into programs... immediate
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no

creating libtool
appending configuration tag "CXX" to libtool
configure: patching config.h.in
configure: creating ./config.status
config.status: creating config.h

скомпилировать:

make

успешный результат:

...
/bin/sh /opt/source/php/php-8.2.17/ext/readline/libtool --tag=CC --mode=install cp ./readline.la /opt/source/php/php-8.2.17/ext/readline/modules
cp ./.libs/readline.so /opt/source/php/php-8.2.17/ext/readline/modules/readline.so
cp ./.libs/readline.lai /opt/source/php/php-8.2.17/ext/readline/modules/readline.la
PATH="$PATH:/sbin" ldconfig -n /opt/source/php/php-8.2.17/ext/readline/modules
----------------------------------------------------------------------
Libraries have been installed in:
   /opt/source/php/php-8.2.17/ext/readline/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.

установка:

make install

успешный результат (отображает путь где лежит readline.so):

Installing shared extensions:     /opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/

добавить путь к дополнению в php.ini в группе [PHP]:

[PHP]
...
extension=/opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/readline.so

перезапустить сервис php-fpm:

systemctl restart php-fpm-8-2

 

memcached

скачать расширение memcached под php 8.2.17

установить memcached

dnf install memcached

запустить и добавить в автозапуск:

systemctl start memcached && systemctl enable memcached

установить пакет libmemcached-devel с репозитория PowerTools:

dnf --enablerepo=powertools install libmemcached-devel

memcached для php: https://pecl.php.net/package/memcached

wget https://pecl.php.net/get/memcached-3.2.0.tgz && tar -xzvf memcached*.tgz

перейти в папку распаковки расширения:

cd memcached-3.2.0

выполнить phpize для создания configure:

/opt/php/php-8.2/bin/phpize

выполнить configure:

./configure --with-php-config=/opt/php/php-8.2/bin/php-config

при успешном конфигурировании:

...
checking whether stripping libraries is possible... yes
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no

creating libtool
appending configuration tag "CXX" to libtool
configure: patching config.h.in
configure: creating ./config.status
config.status: creating config.h

подготовить к установке:

make

успешный результат:

...
cp ./.libs/memcached.so /opt/source/php/php-8.2.17/ext/memcached/modules/memcached.so
cp ./.libs/memcached.lai /opt/source/php/php-8.2.17/ext/memcached/modules/memcached.la
PATH="$PATH:/sbin" ldconfig -n /opt/source/php/php-8.2.17/ext/memcached/modules
----------------------------------------------------------------------
Libraries have been installed in:
   /opt/source/php/php-8.2.17/ext/memcached/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.

установка:

make install

успешный результат (отображает путь где лежит memcached.so):

Installing shared extensions:     /opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/

добавить путь к дополнению в php.ini в группе [PHP]:

[PHP]
...
extension=/opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/memcached.so

перезапустить сервис php-fpm:

systemctl restart php-fpm-8-2

 

redis

скачать расширение redis под php 8.2.17

установить redis

dnf install redis

запустить и добавить в автозапуск:

systemctl start redis && systemctl enable redis

redis для php: https://pecl.php.net/package/redis

wget https://pecl.php.net/get/redis-6.0.2.tgz && tar -xzvf redis*.tgz

перейти в папку распаковки расширения:

cd redis-6.0.2

выполнить phpize для создания configure:

/opt/php/php-8.2/bin/phpize

выполнить configure:

./configure --with-php-config=/opt/php/php-8.2/bin/php-config

при успешном конфигурировании:

...
checking if libtool supports shared libraries... yes
checking whether to build shared libraries... yes
checking whether to build static libraries... no

creating libtool
appending configuration tag "CXX" to libtool
configure: patching config.h.in
configure: creating ./config.status
config.status: creating config.h

подготовить к установке:

make

успешный результат:

...
(cd .libs && rm -f redis.la && ln -s ../redis.la redis.la)
/bin/sh /opt/source/php/php-8.2.17/ext/redis/libtool --tag=CC --mode=install cp ./redis.la /opt/source/php/php-8.2.17/ext/redis/modules
cp ./.libs/redis.so /opt/source/php/php-8.2.17/ext/redis/modules/redis.so
cp ./.libs/redis.lai /opt/source/php/php-8.2.17/ext/redis/modules/redis.la
PATH="$PATH:/sbin" ldconfig -n /opt/source/php/php-8.2.17/ext/redis/modules
----------------------------------------------------------------------
Libraries have been installed in:
   /opt/source/php/php-8.2.17/ext/redis/modules

If you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:
   - add LIBDIR to the `LD_LIBRARY_PATH' environment variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during linking
   - use the `-Wl,--rpath -Wl,LIBDIR' linker flag
   - have your system administrator add LIBDIR to `/etc/ld.so.conf'

See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------

Build complete.
Don't forget to run 'make test'.

установка:

make install

успешный результат (отображает путь где лежит redis.so):

Installing shared extensions:     /opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/

добавить путь к дополнению в php.ini в группе [PHP]:

[PHP]
...
extension=/opt/php/php-8.2/lib/php/extensions/no-debug-non-zts-20220829/redis.so

перезапустить сервис php-fpm:

systemctl restart php-fpm-8-2

 

Ошибки конфигурирования

ошибка пакета libxml-2.0

...
checking whether to build with LIBXML support... yes
checking for libxml-2.0 >= 2.9.0... no
configure: error: Package requirements (libxml-2.0 >= 2.9.0) were not met:

Package 'libxml-2.0', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables LIBXML_CFLAGS
and LIBXML_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

нужно установить пакет libxml2-devel:

dnf install libxml2-devel

 

ошибка пакета sqlite3

...
checking whether to enable the SQLite3 extension... yes
checking for sqlite3 >= 3.7.7... no
configure: error: Package requirements (sqlite3 >= 3.7.7) were not met:

Package 'sqlite3', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables SQLITE_CFLAGS
and SQLITE_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

нужно установить пакет sqlite-devel:

dnf install sqlite-devel

 

ошибка: BZip2 in default path… not found

...
checking for BZip2 support... yes
checking for BZip2 in default path... not found
configure: error: Please reinstall the BZip2 distribution

нужно установить пакет bzip2-devel:

dnf install bzip2-devel

 

ошибка пакета libcurl

...
checking for cURL support... yes
checking for libcurl >= 7.29.0... no
configure: error: Package requirements (libcurl >= 7.29.0) were not met:

Package 'libcurl', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables CURL_CFLAGS
and CURL_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

нужно установить пакет libcurl-devel:

dnf install libcurl-devel

 

ошибка: configure: error: Cannot find ldap.h

...
checking size of long... (cached) 8
checking if we're at 64-bit platform... yes
checking size of long... (cached) 8
checking if we're at 64-bit platform... yes
configure: error: Cannot find ldap.h

нужно установить пакет openldap2-devel:

dnf install openldap-devel

 

ошибка: configure: error: Cannot find ldap libraries in /usr/lib.

...
checking for inttypes.h... (cached) yes
checking for stdint.h... (cached) yes
checking for unistd.h... (cached) yes
configure: error: Cannot find ldap libraries in /usr/lib.

для PHP расширения ldap нужно скопировать файл:

cp /usr/lib64/libldap.so /usr/lib/libldap.so

 

ошибка пакета oniguruma

...
checking whether to enable multibyte regex support (requires oniguruma)... yes
checking for oniguruma... no
configure: error: Package requirements (oniguruma) were not met:

Package 'oniguruma', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables ONIG_CFLAGS
and ONIG_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

нужно установить пакет oniguruma-devel с репозитория PowerTools:

dnf --enablerepo=powertools install oniguruma-devel

 

ошибка: pg_config… not found

...
checking for PostgreSQL support for PDO... yes
checking for pg_config... not found
configure: error: Cannot find libpq-fe.h. Please specify correct PostgreSQL installation path

нужно установить пакет libpq-devel:

dnf install libpq-devel

 

ошибка при выполнении phpize

Configuring for:
PHP Api Version:         20220829
Zend Module Api No:      20220829
Zend Extension Api No:   420220829
Cannot find autoconf. Please check your autoconf installation and the
$PHP_AUTOCONF environment variable. Then, rerun this script.

нужно установить пакет autoconf:

dnf install autoconf

 

ошибка пакета libmemcached:

...
checking for memcached igbinary support... disabled
checking for memcached msgpack support... disabled
checking for libmemcached location... configure: error: memcached support requires libmemcached. Use --with-libmemcached-dir=<DIR> to specify the prefix where libmemcached headers and library are located

нужно установить пакет libmemcached-devel с репозитория PowerTools:

dnf --enablerepo=powertools install libmemcached-devel

 

ошибка пакета libedit:

...
checking if zts is enabled... no
checking for gawk... gawk
checking for libedit readline replacement... yes, shared
checking for libedit... no
configure: error: Package requirements (libedit) were not met:

Package 'libedit', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables EDIT_CFLAGS
and EDIT_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

установить libedit-devel:

dnf --enablerepo=powertools install libedit-devel

 

ошибка пакета libpng:

...
checking for fabsf... no
checking for floorf... no
checking for zlib... yes
checking for libpng... no
configure: error: Package requirements (libpng) were not met:

Package 'libpng', required by 'virtual:world', not found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables PNG_CFLAGS
and PNG_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

установить libpng-devel:

dnf install libpng-devel