LEMP-CentOS-9+WordPress

26 марта 2026 г.  Не закончена, будут вноситься поправки.

ОС установлена с дистрибутива CentOS-Stream-9  с выбором конфигурации Minimal install.
Selinux отключен. Инструкция - сборная солянка из разных источников делалась для себя.
Проверено на VPS с доменным именем и на VirtualBox 7.1.16 ( сайт на VBox без SSL сертификата )
При установке пакетов на вопросы инсталлятора ( если что-то не указал ) отвечаем Y или <Enter>.
Если залогинились не под root-ом, то перед каждой командой добавляйте
sudo (с пробелом)
Некоторые команды могут выполняться довольно долго. ( Такая смешная количественная оценка )
Вместо your-domain.host ставим свое: мальчик.ru, sobaka.gav, 192.168.*.*  и прочая, прочая, прочая.

dnf update -y
dnf install wget -y
dnf install unzip -y
dnf install nano -y

Selinux отключаем. В файле /etc/selinux/config  ставим  SELINUX=disabled
Перезагружаемся.

Install MySQL (MariaDB 10.11)

dnf module -y install mariadb:10.11/server
systemctl enable mariadb
systemctl start mariadb
systemctl status mariadb   # To exit, press Ctrl-C
mysql_secure_installation

Отвечаем на несколько вопросов:
Enter current password for root (enter for none): <Enter>
Switch to unix_socket authentication [Y/n] y
Change the root password? [Y/n] y
2 раза вводим пароль для пользователя  root  базы данных ( это не системный пользователь root !)
Remove anonymous users? [Y/n] y
Disallow root login remotely? [Y/n] y
Remove test database and access to it? [Y/n] y
Reload privilege tables now? [Y/n] y

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

mysql
CREATE DATABASE name_your_db;
CREATE USER name_admin_db@localhost IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON name_your_db.* TO name_admin_db@localhost;
FLUSH PRIVILEGES;

exit

Install php8.4

dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm
dnf makecache -y
dnf module -y install php:remi-8.4
dnf install -y php-{fpm,mysqlnd,curl,gd,mcrypt,json,pear,common,xml,zip,devel,xsl,soap,bcmath,mbstring,gettext,imagick,intl}

В файле /etc/php-fpm.d/www.conf меняем:
user = apache на user = nginx
group = apache на group = nginx

systemctl enable php-fpm && systemctl start php-fpm
php -v
chown root:nginx /var/lib/php/wsdlcache/
chown root:nginx /var/lib/php/session/
chown root:nginx /var/lib/php/opcache/

Install Nginx

Подключим репозиторий для установки свежей версии Nginx.
yum install yum-utils
nano /etc/yum.repos.d/nginx.repo

[nginx-stable]
name=nginx stable repo
baseurl=https://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=https://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

По умолчанию берется репозиторий для стабильной версии nginx. Если нужно использовать
пакеты для основной версии nginx, выполните следующую команду:
yum-config-manager --enable nginx-mainline

yum install nginx

При запросе подтверждения GPG-ключа проверьте, что отпечаток ключа совпадает с
573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62, и, если да, подтвердите его.

nginx -v
systemctl enable nginx --now
systemctl status nginx
firewall-cmd --add-service=http --add-service=https --permanent
firewall-cmd --reload
echo "<?php phpinfo(); ?>" > /usr/share/nginx/html/info.php

Переходим в браузере по адресу: http://your-domain.host/info.php
Должна открыться
( длинная! ) веб-страница, содержащую подробную информацию о сервере.
После этой проверки файл info.php из соображений безопасности удаляем.
rm -f /usr/share/nginx/html/info.php

Если Selinux ( все-таки ) не отключали:
semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/your-domain.host(/.*)?"
restorecon -R /var/www/html/your-domain.host

Install phpmyadmin

Пытаемся скачать с сайта архив с последней версией  phpMyAdmin:
wget https://www.phpmyadmin.net/downloads/phpMyAdmin-latest-all-languages.zip

Если: Connecting to 185.76.9.12:443... connected. и дальше висит, то идем на сайт
https://www.phpmyadmin.net/
скачиваем архив в свой каталог и в нем продолжаем:

unzip phpMyAdmin-*-all-languages.zip
mv phpMyAdmin-*-all-languages /usr/share/phpMyAdmin
chown -R nginx:nginx /usr/share/phpMyAdmin
chmod -R 755 /usr/share/phpMyAdmin
nano /etc/nginx/conf.d/phpMyAdmin.conf

server {
    listen 80;
        server_name phpMyAdmin.your-domain.host;
        root /usr/share/phpMyAdmin;
        index index.php index.html index.htm;
    location / {
        try_files $uri $uri/ =404;
    }
    location ~ \.php$ {
        include fastcgi_params;
        fastcgi_pass unix:/var/run/php-fpm/www.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

systemctl restart nginx
ln -s /usr/share/phpMyAdmin /usr/share/nginx/html/phpMyAdmin

Делаем попытку открыть: http://your-domain.host  и если "Not found" - чистим куки!
Заходим и переходим по ссылочке внизу :  "Узнайте причину"


На открывшейся странице жмем " Создать базу данных ..."  и выходим из  phpMyAdmin.



Переходим в
/usr/share/phpMyAdmin/ и в файле config.sample.inc.php в 16 строке вставляем свой
32-значный ключ.
Затем  config.sample.inc.php  переименовываем в  config.inc.php  Идем дальше.

mkdir -p /var/www/html/your-domain.host
nano /etc/nginx/conf.d/your-domain.host.conf

server {
    listen 80;
        server_name your-domain.host www.your-domain.host;     # here, use real domain names or IP address
        root /var/www/html/your-domain.host;
        index index.php index.html index.htm;
    location / {
            try_files $uri $uri/ /index.php?$args;
    }
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm/www.sock;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        include fastcgi_params;
    }
}

Переходим в директорию  /var/www/html/your-domain.host/  и работаем дальше.
cd /var/www/html/your-domain.host
wget https://ru.wordpress.org/latest-ru_RU.zip
unzip latest-ru_RU.zip
mv wordpress/* .
rm -rf wordpress latest-ru_RU.zip
chown -R nginx:nginx /var/www/html/your-domain.host
systemctl restart nginx

Устанавливаем WordPress

Открываем в браузере http://your-domain.host и дальше "как обычно" 🙂

Небольшие донастройки

Открываем конфиг nginx на редактирование, и в секцию http добавляем параметр
client_max_body_size с необходимым размером загружаемого файла (в примере - 128 мб):
nano /etc/nginx/nginx.conf
http {
...
client_max_body_size 128M;
...
}
В файле /etc/php.ini выставляем значения директив:

upload_max_filesize = 128M
post_max_size = 128M
memory_limit = 128M

В файле wp-config.php после строки: define( ‘WP_DEBUG’, false ); вписываем:

define('ALLOW_UNFILTERED_UPLOADS', true);

Это позволит загружать на сайт файлы любых типов. ( Что, впрочем, небезопасно ! )
Проверяем конфигурацию и перезапускаем сервис.

nginx -t
systemctl restart nginx

Let's Encrypt SSL

epel репозиторий уже подключен, поэтому просто ставим и запускаем certbot:

dnf install certbot python3-certbot-nginx
certbot --nginx -d your-domain.host -d www.your-domain.host --register-unsafely-without-email

Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.6-August-18-2025.pdf. You must agree
in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y
Account registered.
Requesting a certificate for your-domain.host and www.your-domain.host
Successfully received certificate.
Дальше бла, бла, бла.....

Обновление сертификатов вручную:
certbot renew

Файл /etc/nginx/conf.d/your-domain.host.conf теперь выглядит так:

Показать скрытое содержимое
server {
        server_name your-domain.host www.your-domain.host;
        root /var/www/html/your-domain.host;
        index index.php index.html index.htm;

        location / {
            try_files $uri $uri/ /index.php?$args;
        }
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php-fpm/www.sock;
        fastcgi_param SCRIPT_FILENAME $request_filename;
        include fastcgi_params;

    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/your-domain.host/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/your-domain.host/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    }
server {
    if ($host = www.your-domain.host) {
    return 301 https://$host$request_uri;
    } # managed by Certbot

    if ($host = your-domain.host) {
    return 301 https://$host$request_uri;
    } # managed by Certbot

        listen 80;
            server_name your-domain.host www.your-domain.host;
            return 404; # managed by Certbot
}

Следующее не проверял.
Автоматическое обновление. Откройте cron в редакторе и добавьте следующую строку:

30 3 * * 2 /usr/bin/certbot renew >> /var/log/renew-ssl.log --post-hook "systemctl reload nginx"

Эта задача настроит автоматическое обновление сертификатов каждый вторник в 03:30 утра.
certbot будет проверять срок действия сертификатов и, если до их истечения останется менее 30 дней,
выполнит автоматическое обновление. После успешного обновления Nginx будет перезагружен,
чтобы начать использовать новый сертификат. Все действия certbot будут записываться в файл renew-ssl.log

Самоподписанный SSL

Чтобы создать самоподписанный сертификат для Nginx на CentOS, нужно выполнить несколько шагов:
создать приватный ключ, сгенерировать сертификат и настроить Nginx.

Создать каталог /etc/ssl/private для хранения файла закрытого ключа.
Ограничить доступ к каталогу, чтобы предотвратить несанкционированный доступ:

mkdir /etc/ssl/private
chmod 700 /etc/ssl/private

Запустить команду с помощью OpenSSL, чтобы создать самоподписанный сертификат и ключ:

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt

Опция -x509 указывает, что нужно создать самоподписанный сертификат, а не запрос на подпись.
Опция -nodes пропускает защиту сертификата парольной фразой,
чтобы сервер Nginx мог читать файл без вмешательства пользователя.

Опция -days 365 устанавливает срок действия сертификата (в данном случае — год).
Опция -newkey rsa:2048 позволяет одновременно создать новый сертификат и новый ключ.

Отредактировать настройки Nginx, чтобы указать пути к файлам сертификата и ключа:
server {
listen 443 http2 ssl;
listen [::]:443 http2 ssl;
server_name your-domain.host;
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
}
nginx -t
Ругнется на устаревший параметр "http2" и отсутствие dhparam.pem , который сгенерим командой:
openssl dhparam -out /etc/ssl/certs/dhparam.pem 4096
( Запасись терпением. Может занять до 20 минут на слабом железе ! )
В Nginx 1.25.1 и выше параметр "http2" внутри директивы listen меняем на отдельную директиву "http2"
server {
listen 443 ssl; http2 on
# listen [::]:443 http2 ssl; Эту строку комментируем, т.к. IPv6 не юзаем
...
}
nginx -t
systemctl reload nginx

Так выглядит файл /etc/nginx/conf.d/your-domain.host.conf в "почти" окончательном виде:
server {
listen 443 ssl; http2 on;
server_name 192.168.*.*;    # В моем конкретном случае...*
root /var/www/html/your-domain.host;
index index.php index.html index.htm;

ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php-fpm/www.sock;
fastcgi_param SCRIPT_FILENAME $request_filename;
include fastcgi_params;

add_header Cache-Control "no-cache";
add_header x-cache-enabled "true";
}
}

* Можно привязать доменное имя к внешнему адресу своего роутера, но это уже другая тема.

 
 
 
Флешка "памяти"
Добавить комментарий