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_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";
}
}
* Можно привязать доменное имя к внешнему адресу своего роутера, но это уже другая тема.
