CentOS Stream 10 подходит для веб-сервера, базы данных, файлового хранилища, контейнеров и учебного стенда на базе технологий экосистемы Red Hat Enterprise Linux. Ниже собран полный путь от выбора ISO и разметки диска до защищённого SSH-доступа, Nginx, PHP, MariaDB, HTTPS, резервных копий и диагностики типичных сбоев.

CentOS Stream 10 даёт актуальную основу для нового сервера
Название CentOS часто связывают с прежним CentOS Linux — бесплатной пересборкой Red Hat Enterprise Linux. Развитие этого направления завершилось: CentOS Linux 8 получил последние обновления 31 декабря 2021 года, CentOS Linux 7 — 30 июня 2024 года. В 2026 году актуальная система проекта называется CentOS Stream.
CentOS Stream занимает место в процессе разработки Red Hat Enterprise Linux. Пакеты проходят через эту ветку перед включением в очередные минорные выпуски RHEL. Для владельца сервера это означает знакомую структуру Enterprise Linux: RPM-пакеты, DNF, systemd, SELinux, firewalld, NetworkManager и совместимые инструкции из документации RHEL.
Руководство рассчитано на CentOS Stream 10. Проект указывает ориентировочный срок сопровождения до 2030 года. CentOS Stream 9 поддерживается до 31 мая 2027 года, поэтому он сохраняет смысл для совместимости со старым программным обеспечением. Новый сервер с современным процессором обычно строят на Stream 10.
| Ветка | Состояние в августе 2026 года | Практический сценарий |
| CentOS Linux 7 | Поддержка завершена 30 июня 2024 года | Только миграция старой системы |
| CentOS Linux 8 | Поддержка завершена 31 декабря 2021 года | Только архивные установки |
| CentOS Stream 9 | Поддержка до 31 мая 2027 года | Совместимость с приложениями семейства EL9 |
| CentOS Stream 10 | Текущая основная ветка, сопровождение ориентировочно до 2030 года | Новая установка и современные серверные роли |
CentOS Stream 10 поставляется с ядром Linux 6.12, Python 3.12, PHP 8.3, Nginx 1.26, MariaDB 10.11, MySQL 8.4 и PostgreSQL 16 в базовом наборе выпуска. Версии пакетов меняются по мере обновления ветки, поэтому фактический состав конкретного сервера показывает команда:
cat /etc/centos-release
dnf info nginx php mariadb-serverПроцессор x86_64_v3 определяет совместимость старого оборудования
Сборка CentOS Stream 10 для AMD и Intel использует уровень x86_64_v3. Такой уровень требует инструкций, которые встречаются в относительно современных процессорах. Старые серверы и бюджетные VPS на устаревших узлах могут не запустить систему.
На работающем Linux поддержку уровней процессора показывает команда:
/lib64/ld-linux-x86-64.so.2 --help | grep x86-64В списке должен присутствовать x86-64-v3 с пометкой supported. Для арендуемого VPS совместимость уточняет описание образа у провайдера. Если образ CentOS Stream 10 доступен в панели создания сервера, гипервизор обычно предоставляет подходящий набор инструкций.
Проект выпускает образы для четырёх архитектур:
- AMD/Intel 64-bit —
x86_64_v3; - ARM 64-bit — ARMv8.0-A;
- IBM Power — POWER9;
- IBM Z — z14.
Серверная установка обходится без графического рабочего стола
Графическая оболочка расходует оперативную память, добавляет пакеты и увеличивает число компонентов, которые получают обновления. Для удалённого сервера достаточно минимальной установки с командной строкой. Управление выполняется через SSH, веб-консоль Cockpit или панель хостинг-провайдера.
Графический интерфейс оправдан на учебной машине, которая стоит рядом с пользователем и одновременно служит рабочей станцией. Для VPS, веб-сервера, базы данных и домашнего мини-сервера минимальный профиль даёт более прозрачную конфигурацию.
Подготовка оборудования и сети предотвращает проблемы во время установки
Сервером может быть физический компьютер, виртуальная машина, VPS или облачный экземпляр. Процесс установки отличается только способом доступа к экрану и загрузочному носителю. На домашнем компьютере используется USB-флешка, в виртуальной машине подключается ISO, в панели VPS выбирается готовый образ.
Ресурсы зависят от роли сервера
CentOS Stream 10 способен загрузиться в небольшой виртуальной машине, но прикладным сервисам тоже нужны процессор, память и диск. Для учебного стенда достаточно 2 виртуальных процессоров, 2 ГБ памяти и 20–25 ГБ диска. Веб-серверу с PHP и MariaDB комфортнее работать с 4 ГБ памяти и диском от 40 ГБ.
| Сценарий | CPU | Оперативная память | Диск | Комментарий |
| Знакомство с системой | 1–2 vCPU | 2 ГБ | 20–25 ГБ | Подходит для SSH и простых служб |
| Небольшой статический сайт | 1–2 vCPU | 2 ГБ | 25–40 ГБ | Nginx, журналы, сертификаты |
| PHP-сайт с MariaDB | 2 vCPU | 4 ГБ | 40–80 ГБ | Запас памяти нужен PHP-FPM и базе данных |
| Несколько сайтов или контейнеров | 4 vCPU | 8 ГБ | от 80 ГБ | Объём зависит от баз, образов и резервных копий |
| Файловое хранилище | 2–4 vCPU | 4–8 ГБ | по объёму данных | Отдельное внимание уделяется дискам и резервированию |
Размер диска включает операционную систему, пакеты, журналы, базы данных, пользовательские файлы и временные резервные копии. Сайт объёмом 2 ГБ может создавать десятки гигабайт журналов и дампов, если очистка файлов отсутствует.
Перед установкой фиксируются сетевые параметры
Для локальной сети понадобятся:
- IP-адрес сервера, например
192.168.1.50; - длина префикса, обычно
/24; - адрес шлюза, например
192.168.1.1; - DNS-серверы;
- имя узла, например
server1.example.com.
VPS обычно получает адрес через DHCP или cloud-init. Публичный IPv4, IPv6, шлюз и обратная DNS-запись отображаются в панели провайдера. Доменное имя можно подключить позже, когда сервер уже отвечает по IP.
ISO загружается с сайта проекта CentOS
На официальной странице загрузки доступны DVD ISO, Boot ISO и облачные образы. Для начинающего пользователя удобнее DVD ISO: установочные пакеты находятся внутри образа, поэтому установка меньше зависит от сети. Boot ISO занимает меньше места и загружает пакеты из сетевого репозитория.
Официальные страницы:
После загрузки полезно сравнить контрольную сумму ISO с опубликованным значением. В Linux:
sha256sum CentOS-Stream-10-latest-x86_64-dvd1.isoВ Windows PowerShell:
Get-FileHash .\CentOS-Stream-10-latest-x86_64-dvd1.iso -Algorithm SHA256Совпадение длинной строки SHA-256 подтверждает целостность файла. Ошибка загрузки, повреждённый накопитель или подменённый файл дадут другую сумму.
Загрузочная флешка записывается как образ диска
В Linux устройство флешки сначала определяют командой lsblk. Запись через dd полностью стирает выбранный накопитель:
lsblk
sudo dd if=CentOS-Stream-10-latest-x86_64-dvd1.iso of=/dev/sdX bs=8M status=progress oflag=direct
sync/dev/sdX заменяется на устройство флешки целиком, например /dev/sdb. Раздел вида /dev/sdb1 здесь не используется.
В Windows подойдут Fedora Media Writer, Rufus или balenaEtcher. В Rufus для гибридного ISO обычно выбирается режим записи DD, если программа предлагает выбор.
Для виртуальной машины ISO подключается к виртуальному DVD-приводу. У VPS с готовым образом этот этап отсутствует.
Установщик Anaconda формирует основу будущей системы
После загрузки с ISO появляется меню CentOS Stream. Пункт Test this media & install CentOS Stream 10 проверяет носитель и запускает установщик Anaconda. Проверка занимает несколько минут и выявляет повреждённые флешки или неполный ISO.
Язык и раскладка не влияют на язык команд
Русский язык интерфейса облегчает первые шаги. Английский язык упрощает поиск сообщений об ошибках в документации и системных журналах. Команды, имена файлов и названия служб остаются английскими при любом выборе.
Для сервера удобно оставить английскую локаль и добавить русскую раскладку только при реальной потребности. В консоли переключение раскладок иногда создаёт путаницу при вводе паролей.
Часовой пояс и синхронизация времени участвуют в работе журналов и сертификатов
В разделе даты и времени выбирается регион сервера. Для Германии подходит Europe/Berlin, для Москвы — Europe/Moscow. Сетевое время оставляют включённым.
Точное время требуется журналам systemd, TLS-сертификатам, базам данных, планировщикам и механизмам аутентификации. Сервер с отставшими часами может отклонять сертификаты и создавать записи журнала с неверной последовательностью событий.
Минимальный профиль сокращает число установленных компонентов
В разделе выбора программного обеспечения используется профиль Minimal Install или близкий серверный профиль без графической среды. Нужные пакеты устанавливаются позже через DNF.
Установка всех доступных дополнений создаёт лишние службы. Минимальный профиль даёт понятный старт: сеть, SSH, пакетный менеджер, systemd и базовые утилиты.
Автоматическая разметка подходит для первого сервера
Для одной системы на одном диске автоматическая разметка с LVM закрывает большинство сценариев. LVM объединяет физическое место в логические тома и позволяет гибко менять размеры разделов.
Типичная структура включает:
- EFI System Partition для загрузки UEFI;
/bootдля ядра и загрузчика;- корневую файловую систему
/; swapдля выгрузки редко используемых страниц памяти;- отдельный
/homeв некоторых профилях.
Для сервера с базой данных или большим числом сайтов ручная схема может отделять /var, где хранятся журналы, базы и веб-данные. Переполненный /var в такой конфигурации не занимает всё место корневого раздела.
Пример ручной схемы для диска 80 ГБ:
| Точка монтирования | Размер | Файловая система | Назначение |
/boot/efi | 600 МБ | EFI System Partition | Загрузка UEFI |
/boot | 1 ГБ | XFS | Ядра и GRUB |
swap | 2–4 ГБ | swap | Резерв памяти |
/ | 25 ГБ | XFS | Система и пакеты |
/var | 35 ГБ | XFS | Сайты, базы, журналы, кэш |
/home | остаток | XFS | Домашние каталоги |
Для VPS с диском 25–40 ГБ отдельные тома могут создать дефицит места в одном разделе при свободном пространстве в другом. Единый корневой том проще для первого небольшого сервера.
Сетевой интерфейс получает имя и адрес
В установщике сетевой интерфейс включается переключателем. DHCP подходит для большинства VPS и домашних роутеров. Статический адрес задаётся вручную, если сервер должен сохранять один IP в локальной сети.
Полное доменное имя узла записывают в формате:
server1.example.comКороткое имя server1 тоже работает, но полное имя облегчает настройку почты, мониторинга, сертификатов и нескольких серверов.
Отдельная учётная запись администратора делает действия прослеживаемыми
В установщике создаётся пользователь, например serveradmin, и включается право выполнять административные команды. В системах семейства RHEL такой пользователь входит в группу wheel и запускает привилегированные операции через sudo.
Пароль содержит не менее 14–16 символов и не совпадает с паролями сайтов, почты и панели хостинга. Менеджер паролей снимает необходимость запоминать случайную комбинацию.
После заполнения обязательных разделов запускается установка. По завершении ISO отключается, сервер перезагружается с диска.
Первый запуск подтверждает состояние дисков, сети и пакетов
После входа в консоль полезно собрать базовую информацию. Эти команды создают исходную точку для дальнейшей диагностики:
cat /etc/centos-release
uname -r
hostnamectl
ip -brief address
ip route
lsblk -f
df -hT
free -hКоманда ip -brief address показывает интерфейсы и адреса в компактном виде. ip route сообщает шлюз по умолчанию. lsblk -f выводит диски, разделы, файловые системы и точки монтирования. df -hT показывает занятое место.
Имя сервера задаётся через hostnamectl
sudo hostnamectl set-hostname server1.example.com
hostnamectlЗапись текущего IP и имени в /etc/hosts помогает локальным программам разрешать имя узла до настройки DNS:
127.0.0.1 localhost localhost.localdomain
192.0.2.10 server1.example.com server1Для VPS строка использует реальный адрес сервера. Некоторые облачные платформы управляют /etc/hosts через cloud-init, поэтому изменения могут восстанавливаться из шаблона провайдера.
Обновление пакетов выполняется сразу после установки
ISO содержит состояние репозиториев на дату сборки образа. После установки сервер получает накопившиеся исправления:
sudo dnf upgrade --refresh -y
sudo rebootПосле перезагрузки проверяются версия ядра и неудачно запущенные службы:
uname -r
systemctl --failedПустой список systemctl --failed означает, что systemd не зафиксировал служб в состоянии ошибки.
DNF управляет пакетами и репозиториями
Базовые операции:
sudo dnf search nginx
sudo dnf info nginx
sudo dnf install nginx
sudo dnf remove nginx
sudo dnf upgrade
sudo dnf history
sudo dnf repolistdnf history показывает транзакции установки, удаления и обновления. Подробности конкретной операции доступны по номеру:
sudo dnf history info 12CentOS Stream 10 использует основные репозитории BaseOS и AppStream. Репозиторий CRB содержит дополнительные библиотеки и инструменты разработки и по умолчанию выключен:
sudo dnf config-manager --set-enabled crb
sudo dnf repolistКоманда dnf config-manager входит в пакет плагинов. Если она отсутствует:
sudo dnf install dnf-plugins-coreEPEL добавляет пакеты Fedora, собранные для Enterprise Linux. Подключение выполняется только при наличии нужного пакета, которого нет в BaseOS и AppStream:
sudo dnf install epel-release
sudo dnf repolistПеред установкой стороннего пакета полезно увидеть его источник:
dnf info certbotСтрока From repo показывает репозиторий.
Часовой пояс и chrony проверяются после загрузки
timedatectl
systemctl status chronyd --no-pager
chronyc tracking
chronyc sources -vСмена часового пояса:
sudo timedatectl set-timezone Europe/BerlinСлужба chronyd обычно установлена и включена. Если пакета нет:
sudo dnf install chrony
sudo systemctl enable --now chronydСтрока System clock synchronized: yes в timedatectl и нормальный вывод chronyc tracking подтверждают синхронизацию.
Swap смягчает кратковременный дефицит памяти
Наличие swap проверяется командой:
swapon --show
free -hЕсли swap отсутствует и сервер имеет 2–4 ГБ памяти, можно создать файл объёмом 2 ГБ:
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap defaults 0 0' | sudo tee -a /etc/fstab
swapon --showSwap не заменяет оперативную память: активная работа с ним замедляет сервер. Он даёт системе дополнительное время при кратком скачке потребления и снижает вероятность немедленного завершения процесса из-за нехватки памяти.
Администраторская учётная запись отделяет повседневную работу от root
Если пользователь не был создан в установщике, его можно добавить после загрузки:
sudo useradd -m -G wheel serveradmin
sudo passwd serveradmin
id serveradminГруппа wheel обычно имеет право на sudo. Проверка:
sudo visudoВ файле должна быть активна строка:
%wheel ALL=(ALL) ALLРедактор visudo проверяет синтаксис перед сохранением. Ошибка в обычном редакторе способна заблокировать работу sudo.
Рабочая схема выглядит так:
ssh serveradmin@203.0.113.10
sudo dnf upgrade
sudo systemctl restart nginxКоманда whoami показывает текущего пользователя, sudo whoami возвращает root после успешной проверки прав.
SSH-ключи защищают удалённый вход от перебора паролей
SSH создаёт зашифрованный канал между компьютером администратора и сервером. На CentOS Stream служба называется sshd, конфигурация находится в /etc/ssh/sshd_config и каталоге /etc/ssh/sshd_config.d/.
Состояние службы:
sudo systemctl status sshd --no-pager
sudo ss -tlnp | grep ':22'Ключ создаётся на компьютере администратора
В Linux, macOS и современном Windows с OpenSSH:
ssh-keygen -t ed25519 -a 100 -C "serveradmin@server1"По умолчанию создаются два файла:
~/.ssh/id_ed25519— закрытый ключ, который остаётся на компьютере;~/.ssh/id_ed25519.pub— открытый ключ для сервера.
Парольная фраза закрытого ключа защищает файл при краже ноутбука или резервной копии. Сам закрытый ключ не передаётся на сервер и не отправляется другим людям.
Копирование открытого ключа:
ssh-copy-id serveradmin@203.0.113.10Если ssh-copy-id отсутствует:
cat ~/.ssh/id_ed25519.pub | ssh serveradmin@203.0.113.10 'umask 077; mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys'Проверка входа:
ssh serveradmin@203.0.113.10На Windows открытый ключ можно скопировать из файла %USERPROFILE%\.ssh\id_ed25519.pub и добавить в /home/serveradmin/.ssh/authorized_keys через консоль провайдера.
Права каталога SSH влияют на принятие ключа
На сервере:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
restorecon -Rv ~/.ssh
ls -ldZ ~/.ssh
ls -lZ ~/.ssh/authorized_keysСлишком широкие права приводят к отказу OpenSSH использовать файл. restorecon восстанавливает ожидаемые SELinux-метки.
Парольный вход отключается после успешного теста ключа
Новый файл /etc/ssh/sshd_config.d/10-hardening.conf отделяет локальные настройки от основного конфигурационного файла:
sudo tee /etc/ssh/sshd_config.d/10-hardening.conf > /dev/null <<'EOFSSH'
PermitRootLogin no
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
AllowUsers serveradmin
EOFSSHПроверка синтаксиса и перечитывание конфигурации:
sudo sshd -t
sudo systemctl reload sshdТекущий сеанс оставляют открытым и создают второе SSH-подключение. Успешный вход во втором окне подтверждает, что ключ, имя пользователя и правила работают. При ошибке открытый первый сеанс позволяет исправить файл.
Команда выводит итоговые параметры с учётом всех файлов:
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|allowusers'В RHEL 10 вход root по паролю уже ограничен значением PermitRootLogin prohibit-password. Полный запрет root-входа и работа через персонального пользователя делают журнал sudo более понятным.
Другой порт SSH уменьшает шум в журналах
Сканеры постоянно проверяют порт 22. Перенос SSH на порт, например 2222, уменьшает число автоматических попыток, но не заменяет ключи, firewall и ограничение пользователей.
Сначала порт регистрируется в SELinux и firewall:
sudo dnf install policycoreutils-python-utils
sudo semanage port -a -t ssh_port_t -p tcp 2222
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reloadЗатем в SSH-конфигурацию добавляется:
Port 2222Проверка и перечитывание:
sudo sshd -t
sudo systemctl reload sshd
sudo ss -tlnp | grep 2222Новое подключение:
ssh -p 2222 serveradmin@203.0.113.10После успешного теста старое правило SSH удаляется из firewall, если служба больше не слушает порт 22:
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reloadFirewalld открывает только порты работающих служб
Firewalld управляет сетевыми правилами через зоны и сервисы. В типичной публичной зоне входящий трафик блокируется, пока администратор явно не откроет сервис или порт.
Проверка состояния:
sudo systemctl enable --now firewalld
sudo firewall-cmd --state
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --list-allFirewalld хранит две конфигурации:
- runtime действует сейчас и исчезает после перезапуска службы;
- permanent сохраняется на диске и загружается при старте.
Поэтому постоянное правило обычно создаётся с --permanent, затем выполняется --reload.
Имена сервисов понятнее отдельных портов
Для веб-сервера:
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-servicesСервисы http и https соответствуют TCP-портам 80 и 443. SSH обычно открыт сервисом ssh.
Произвольный порт открывается так:
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-portsУдаление:
sudo firewall-cmd --permanent --remove-port=8080/tcp
sudo firewall-cmd --reloadОграничение SSH по IP подходит для постоянного адреса администратора
Если рабочий компьютер выходит в интернет через фиксированный IPv4 198.51.100.25, SSH можно разрешить только с него:
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="198.51.100.25/32" service name="ssh" accept'
sudo firewall-cmd --reload
sudo firewall-cmd --list-rich-rulesДля динамического домашнего адреса такое правило способно заблокировать доступ после смены IP. VPN, jump-host или панель провайдера дают более устойчивую точку входа для закрытой инфраструктуры.
Проверка порта выполняется снаружи и изнутри
На сервере:
sudo ss -tulpnС другого компьютера:
nc -vz 203.0.113.10 22
nc -vz 203.0.113.10 80
nc -vz 203.0.113.10 443Открытый firewall не создаёт слушающий сервис. Для доступности нужны одновременно работающий процесс, прослушиваемый адрес, разрешающее правило firewalld и отсутствие блокировки в облачном security group.
SELinux ограничивает последствия ошибок в сервисах
SELinux применяет обязательные правила доступа к процессам, файлам, каталогам и портам. Обычные права Unix могут разрешать чтение файла, а политика SELinux сохраняет запрет для процесса, которому этот файл не предназначен.
Состояние:
getenforce
sestatusДля рабочего сервера используется режим Enforcing. Режим Permissive регистрирует нарушения без блокировки и подходит для короткой диагностики. Полное отключение лишает систему дополнительного уровня изоляции.
Метки файлов восстанавливаются через restorecon
Просмотр меток:
ls -lZ /var/wwwПосле копирования файлов из нестандартного места:
sudo restorecon -Rv /var/wwwДля сайта в /srv/www/example.com задаётся постоянное соответствие:
sudo dnf install policycoreutils-python-utils
sudo semanage fcontext -a -t httpd_sys_content_t '/srv/www/example.com(/.*)?'
sudo restorecon -Rv /srv/www/example.comКаталог, куда веб-приложение записывает загрузки или кэш, получает метку для записи:
sudo semanage fcontext -a -t httpd_sys_rw_content_t '/srv/www/example.com/storage(/.*)?'
sudo restorecon -Rv /srv/www/example.com/storageМетка назначается только каталогам, которым запись действительно нужна. Исходный код и конфигурация приложения обычно остаются доступными только для чтения со стороны веб-процесса.
Reverse proxy требует разрешения сетевых подключений
Nginx или Apache, работающий как reverse proxy к приложению на 127.0.0.1:3000, может получить отказ SELinux. Разрешение исходящих соединений для веб-процессов включается boolean-параметром:
sudo setsebool -P httpd_can_network_connect on
getsebool httpd_can_network_connectКлюч -P сохраняет значение после перезагрузки.
Журнал AVC показывает причину блокировки
sudo ausearch -m AVC -ts recent
sudo journalctl -t setroubleshoot --since todayПорядок диагностики состоит из трёх проверок: правильный путь, обычные права Unix и SELinux-метка. Генерация широкой разрешающей политики через audit2allow без анализа способна открыть процессу больше доступа, чем требовалось.
Nginx превращает установленную систему в веб-сервер
Nginx принимает HTTP-запросы, отдаёт статические файлы, передаёт PHP-запросы в PHP-FPM и проксирует трафик к приложениям Node.js, Python, Go или контейнерам.
Установка и запуск:
sudo dnf install nginx
sudo systemctl enable --now nginx
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reloadПроверка:
systemctl status nginx --no-pager
curl -I http://127.0.0.1
sudo ss -tlnp | grep -E ':80|:443'Стандартная страница должна открыться по IP сервера через браузер.
Отдельный каталог и server block обслуживают конкретный домен
В примерах используется домен example.com. Его заменяют реальным именем.
sudo install -d -m 0755 /var/www/example.com/public
sudo tee /var/www/example.com/public/index.html > /dev/null <<'EOFHTML'
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Сервер работает</title>
</head>
<body>
<h1>CentOS Stream 10 и Nginx работают</h1>
</body>
</html>
EOFHTML
sudo restorecon -Rv /var/www/example.comКонфигурация /etc/nginx/conf.d/example.com.conf:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.html;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ =404;
}
}Создание файла:
sudo nano /etc/nginx/conf.d/example.com.conf
sudo nginx -t
sudo systemctl reload nginxnginx -t проверяет синтаксис до перечитывания. Ошибка сообщает имя файла и номер строки.
DNS связывает домен с публичным адресом
У регистратора или DNS-провайдера создаются записи:
| Тип | Имя | Значение |
| A | @ | публичный IPv4 сервера |
| A | www | публичный IPv4 сервера |
| AAAA | @ | публичный IPv6 сервера, если он настроен |
| AAAA | www | публичный IPv6 сервера, если он настроен |
Проверка распространения:
dig +short example.com A
dig +short example.com AAAA
curl -I http://example.comЗапись AAAA публикуется только при рабочем IPv6 на сервере и разрешённом порте 80/443 для IPv6. Сломанная AAAA-запись приводит к задержкам и ошибкам у клиентов, которые выбирают IPv6.
PHP-FPM запускает динамические сайты через отдельный процесс
PHP-FPM управляет пулом PHP-процессов и принимает запросы от Nginx через Unix-сокет. Для типичного CMS или небольшого приложения устанавливаются основные расширения:
sudo dnf install php php-fpm php-cli php-mysqlnd php-opcache php-gd php-mbstring php-xml php-intl php-pecl-zip
php -v
php -mВ файле /etc/php-fpm.d/www.conf задаются пользователь Nginx и права сокета:
user = nginx
group = nginx
listen = /run/php-fpm/www.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660После изменения:
sudo php-fpm -t
sudo systemctl enable --now php-fpm
sudo systemctl status php-fpm --no-pager
ls -lZ /run/php-fpm/www.sockВ server block Nginx добавляется обработчик PHP:
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/run/php-fpm/www.sock;
}Проверка и перечитывание:
sudo nginx -t
sudo systemctl reload nginxТестовый файл:
sudo tee /var/www/example.com/public/info.php > /dev/null <<'EOFPHP'
<?php phpinfo();
EOFPHP
sudo restorecon -v /var/www/example.com/public/info.phpПосле открытия http://example.com/info.php файл удаляется, поскольку страница phpinfo раскрывает версии, пути и параметры окружения:
sudo rm /var/www/example.com/public/info.phpПараметры PHP настраиваются под приложение
Основной файл находится в /etc/php.ini. Удобнее создать отдельный файл /etc/php.d/99-application.ini:
date.timezone = Europe/Berlin
memory_limit = 256M
upload_max_filesize = 32M
post_max_size = 32M
max_execution_time = 60
expose_php = OffПосле изменения:
sudo systemctl restart php-fpmpost_max_size должен быть не меньше upload_max_filesize. Реальные лимиты выбираются по требованиям приложения и объёму памяти. Несколько PHP-процессов с лимитом 512 МБ способны исчерпать память небольшого VPS.
MariaDB хранит данные приложения локально
CentOS Stream 10 включает MariaDB 10.11 в базовом выпуске. Установка:
sudo dnf install mariadb-server
sudo systemctl enable --now mariadb
sudo systemctl status mariadb --no-pagerПервичная настройка:
sudo mariadb-secure-installationСценарий предлагает удалить анонимных пользователей, тестовую базу и удалённый вход root. В локальной установке эти действия сокращают число лишних точек доступа.
База и пользователь создаются для одного приложения
Вход в консоль:
sudo mariadbSQL-команды:
CREATE DATABASE appdb
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
CREATE USER 'appuser'@'localhost'
IDENTIFIED BY 'длинный-случайный-пароль';
GRANT ALL PRIVILEGES ON appdb.*
TO 'appuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;Проверка:
mariadb -u appuser -p appdbПриложение получает доступ только к своей базе. Отдельная учётная запись для каждого сайта ограничивает последствия утечки пароля одного проекта.
Порт 3306 остаётся закрытым для локального сайта
Если PHP и MariaDB работают на одном сервере, приложение подключается к localhost или Unix-сокету. Открывать mysql в firewalld не требуется.
Проверка слушающих адресов:
sudo ss -tlnp | grep 3306Для внешнего подключения базы используются VPN, SSH-туннель или отдельная закрытая сеть. Публикация 3306 в интернет создаёт постоянный поток перебора паролей.
Логический дамп подходит для небольших и средних баз
Создание резервной копии:
sudo install -d -m 0700 /var/backups/mariadb
sudo mariadb-dump --single-transaction --routines --events appdb | gzip | sudo tee /var/backups/mariadb/appdb-$(date +%F-%H%M).sql.gz > /dev/null
ls -lh /var/backups/mariadbВосстановление в пустую базу:
gunzip -c /var/backups/mariadb/appdb-2026-08-04-0300.sql.gz | sudo mariadb appdbОпция --single-transaction создаёт согласованный дамп таблиц InnoDB без длительной блокировки записей. Для очень больших баз применяются физические резервные копии и репликация.
HTTPS шифрует трафик и подтверждает имя сайта
Сертификат Let’s Encrypt выдаётся после того, как домен указывает на сервер, Nginx отвечает по порту 80, а firewall пропускает HTTP и HTTPS.
Certbot доступен в EPEL 10:
sudo dnf install epel-release
sudo dnf install certbot python3-certbot-nginxПолучение сертификата и изменение конфигурации Nginx:
sudo certbot --nginx -d example.com -d www.example.comCertbot проверяет домены через HTTP, получает сертификат, добавляет блоки TLS и может настроить перенаправление с HTTP на HTTPS.
Проверка:
sudo nginx -t
curl -I https://example.com
sudo certbot certificatesАвтоматическое продление контролируется systemd-таймером
Пакет EPEL содержит certbot-renew.timer. Его состояние:
systemctl list-timers | grep certbot
systemctl status certbot-renew.timer --no-pagerЕсли таймер выключен:
sudo systemctl enable --now certbot-renew.timerТест продления:
sudo certbot renew --dry-runУспешный dry-run подтверждает доступность проверки домена, работоспособность плагина Nginx и возможность перечитать конфигурацию.
Ошибка выдачи сертификата обычно связана с DNS или портом 80
Последовательность проверки:
dig +short example.com A
dig +short example.com AAAA
curl -I http://example.com
sudo firewall-cmd --list-services
sudo ss -tlnp | grep ':80'
sudo journalctl -u nginx -n 100 --no-pagerIP в DNS должен совпадать с адресом сервера. Облачный firewall или security group проверяется отдельно от firewalld внутри CentOS.
Cockpit даёт браузерную панель для базовых операций
Cockpit показывает загрузку процессора, память, диски, сетевые интерфейсы, журналы, службы и обновления. Он удобен для первого знакомства с systemd и журналом systemd-journald.
Установка:
sudo dnf install cockpit
sudo systemctl enable --now cockpit.socket
sudo firewall-cmd --permanent --add-service=cockpit
sudo firewall-cmd --reloadПанель открывается по адресу:
https://IP-СЕРВЕРА:9090Первое подключение использует локальный сертификат, поэтому браузер показывает предупреждение. Вход выполняется системной учётной записью.
Порт 9090 лучше ограничивать VPN, внутренней сетью или фиксированным адресом администратора. После завершения работы публичное правило можно удалить:
sudo firewall-cmd --permanent --remove-service=cockpit
sudo firewall-cmd --reloadСам Cockpit продолжит слушать локальный порт, но внешний firewall перестанет пропускать соединения.
Автоматические обновления уменьшают период работы с известными уязвимостями
Пакет dnf-automatic запускает обновления по таймеру systemd:
sudo dnf install dnf-automatic
sudo nano /etc/dnf/automatic.confДля установки только исправлений безопасности в секции [commands] задаётся:
upgrade_type = securityЗначение default устанавливает все доступные обновления. Таймер установки включается командой:
sudo systemctl enable --now dnf-automatic-install.timer
systemctl status dnf-automatic-install.timer --no-pager
systemctl list-timers | grep dnfНа критичном сервере обновления могут сначала проходить на тестовой машине. Для небольшого личного сервера автоматическая установка сокращает время между публикацией исправления и его применением.
После обновления ядра или ключевых библиотек процессам может потребоваться перезапуск. Плагин входит в dnf-plugins-core:
sudo dnf install dnf-plugins-core
sudo dnf needs-restarting
sudo dnf needs-restarting --servicesПервая команда показывает процессы, которые используют прежние версии файлов. Вторая перечисляет службы systemd, для которых доступен управляемый перезапуск.
Резервная копия включает данные, конфигурацию и базу
Снимок виртуальной машины удобен для быстрого отката, но зависит от одного провайдера и одной учётной записи. Полная схема резервирования содержит отдельные копии данных, конфигурации и базы на другом хранилище.
Для сайта нужны как минимум:
/var/www/example.com;/etc/nginx;/etc/php.iniи/etc/php.d;/etc/php-fpm.d;- дамп MariaDB;
- список установленных пакетов;
- пользовательские systemd units и скрипты;
- сертификаты
/etc/letsencrypt, если стратегия восстановления включает их перенос.
Скрипт создаёт локальный архив и дамп
Файл /usr/local/sbin/backup-example.sh:
#!/usr/bin/env bash
set -euo pipefail
BACKUP_ROOT="/var/backups/example.com"
STAMP="$(date +%F-%H%M%S)"
TARGET="$BACKUP_ROOT/$STAMP"
install -d -m 0700 "$TARGET"
mariadb-dump --single-transaction --routines --events appdb \
| gzip > "$TARGET/appdb.sql.gz"
tar -czf "$TARGET/files.tar.gz" \
/var/www/example.com \
/etc/nginx \
/etc/php.ini \
/etc/php.d \
/etc/php-fpm.d
dnf repoquery --userinstalled > "$TARGET/packages.txt"
find "$BACKUP_ROOT" -mindepth 1 -maxdepth 1 -type d -mtime +7 -exec rm -rf {} +Права и тестовый запуск:
sudo chmod 700 /usr/local/sbin/backup-example.sh
sudo /usr/local/sbin/backup-example.sh
sudo find /var/backups/example.com -maxdepth 2 -type f -lsПароль базы не размещают в строке команды. Для автоматизации создаётся защищённый клиентский файл MariaDB или отдельная учётная запись с минимальными правами на резервное копирование.
Systemd timer запускает копирование по расписанию
Unit /etc/systemd/system/backup-example.service:
[Unit]
Description=Backup example.com
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/backup-example.shTimer /etc/systemd/system/backup-example.timer:
[Unit]
Description=Daily backup of example.com
[Timer]
OnCalendar=*-*-* 03:15:00
Persistent=true
RandomizedDelaySec=10m
[Install]
WantedBy=timers.targetАктивация:
sudo systemctl daemon-reload
sudo systemctl enable --now backup-example.timer
systemctl list-timers backup-example.timerРучной тест:
sudo systemctl start backup-example.service
sudo systemctl status backup-example.service --no-pager
sudo journalctl -u backup-example.service -n 100 --no-pagerPersistent=true запускает пропущенную задачу после включения сервера. RandomizedDelaySec сдвигает старт в пределах указанного интервала и снижает одновременную нагрузку, если одинаковый таймер установлен на нескольких узлах.
Внешняя копия переживает потерю самого сервера
Rsync через SSH переносит каталог на резервный узел:
sudo rsync -aH --delete /var/backups/example.com/ backupuser@backup.example.net:/srv/backups/server1/example.com/Параметр --delete удаляет на приёмнике файлы, которых уже нет в источнике. Он подходит только для каталога, выделенного под синхронизацию, и требует предварительного теста через --dry-run:
sudo rsync -aH --delete --dry-run /var/backups/example.com/ backupuser@backup.example.net:/srv/backups/server1/example.com/Резервная копия подтверждается восстановлением на тестовой машине. Наличие архивов без проверки не гарантирует, что дамп читается, файлов хватает, а инструкции восстановления актуальны.
Журналы и системные команды показывают причину большинства сбоев
Systemd-journald собирает сообщения ядра и служб. Основные команды:
sudo journalctl -p warning -b
sudo journalctl -u nginx --since today
sudo journalctl -u php-fpm -n 100 --no-pager
sudo journalctl -u mariadb -n 100 --no-pager
sudo journalctl -f-b ограничивает вывод текущей загрузкой. -f показывает новые записи в реальном времени.
Состояние службы:
systemctl status nginx --no-pager
systemctl is-active nginx
systemctl is-enabled nginx
systemctl --failedФайлы Nginx:
sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/example.com.error.log
sudo tail -f /var/log/nginx/example.com.access.logНагрузка проверяется по четырём направлениям
Процессор и процессы:
top
ps aux --sort=-%cpu | headПамять:
free -h
ps aux --sort=-%mem | headДиск:
df -hT
du -xhd1 /var | sort -h
lsblk -fСеть:
ip -brief address
ip route
ss -tulpn
curl -I https://example.comДля статистики дискового ввода-вывода:
sudo dnf install sysstat
sudo systemctl enable --now sysstat
iostat -xz 1Высокий %util, большая задержка await и растущая очередь указывают на перегрузку диска. В виртуальной среде причина может находиться на уровне хранилища провайдера.
Типичные ошибки разбираются по уровню, на котором возник сбой
Одинаковое внешнее проявление может иметь разные причины. Браузерное сообщение о недоступности сайта встречается при ошибке DNS, закрытом firewall, остановленном Nginx, неверном сертификате и сбое приложения.
SSH сообщает Connection timed out
Connection timed out означает, что клиент не получил ответ. Проверяются:
ping 203.0.113.10
nc -vz 203.0.113.10 22На сервере через консоль провайдера:
ip -brief address
ip route
sudo systemctl status sshd --no-pager
sudo ss -tlnp | grep ssh
sudo firewall-cmd --list-allЧастые причины: неверный IP, закрытый cloud firewall, закрытый firewalld, служба слушает другой порт, сервер выключен, маршрут провайдера нарушен.
SSH сообщает Connection refused
Connection refused означает, что узел отвечает, но на порту нет слушающей службы или firewall активно отклоняет соединение:
sudo systemctl restart sshd
sudo sshd -t
sudo journalctl -u sshd -n 100 --no-pager
sudo ss -tlnp | grep -E ':22|:2222'SSH сообщает Permission denied publickey
Проверка на клиенте:
ssh -vvv serveradmin@203.0.113.10Проверка на сервере:
sudo journalctl -u sshd -n 100 --no-pager
sudo -u serveradmin ls -la /home/serveradmin/.ssh
sudo ls -lZ /home/serveradmin/.ssh/authorized_keysИсправление прав и меток:
sudo chown -R serveradmin:serveradmin /home/serveradmin/.ssh
sudo chmod 700 /home/serveradmin/.ssh
sudo chmod 600 /home/serveradmin/.ssh/authorized_keys
sudo restorecon -Rv /home/serveradmin/.sshNginx возвращает 403 Forbidden
Проверяются права на каждый каталог пути и SELinux-метки:
namei -l /var/www/example.com/public/index.html
ls -lZ /var/www/example.com/public/index.html
sudo restorecon -Rv /var/www/example.com
sudo tail -n 100 /var/log/nginx/example.com.error.logПользователю nginx нужен доступ на чтение файлов и проход по каталогам. Для каталога обычно достаточно режима 0755, для статического файла — 0644.
Nginx возвращает 502 Bad Gateway
Код 502 появляется, когда Nginx не может получить корректный ответ от PHP-FPM или другого backend-процесса:
sudo systemctl status php-fpm --no-pager
sudo journalctl -u php-fpm -n 100 --no-pager
ls -l /run/php-fpm/www.sock
sudo nginx -T | grep -n fastcgi_passПуть сокета в Nginx должен совпадать с listen в /etc/php-fpm.d/www.conf. Владелец сокета и пользователь Nginx должны иметь совместимые права.
Для reverse proxy к приложению:
curl -I http://127.0.0.1:3000
getsebool httpd_can_network_connect
sudo ausearch -m AVC -ts recentMariaDB не запускается
sudo systemctl status mariadb --no-pager
sudo journalctl -u mariadb -n 200 --no-pager
sudo mariadb-check --all-databases
sudo df -hTЗапуск часто нарушают переполненный диск, ошибка конфигурации, повреждение таблиц после аварийного отключения и неподходящие права на каталог данных.
Диск заполнен, хотя сайт занимает мало места
df -hT
sudo du -xhd1 /var | sort -h
sudo du -xhd1 /var/log | sort -h
sudo journalctl --disk-usageОчистка старых записей journald по размеру:
sudo journalctl --vacuum-size=500MПроверка logrotate:
sudo logrotate -d /etc/logrotate.confУдалённый файл может продолжать занимать место, пока процесс держит его открытым:
sudo lsof +L1Перезапуск конкретной службы освобождает такой дескриптор после выяснения причины.
DNF сообщает конфликт или недоступный репозиторий
sudo dnf clean all
sudo dnf makecache
sudo dnf repolist --all
sudo dnf check
sudo dnf distro-syncСначала проверяются дата и время, DNS, доступ к зеркалам и сторонние репозитории. Смешивание пакетов для EL9 и EL10 создаёт несовместимые зависимости.
Контрольный список показывает готовность базового сервера
Перед размещением приложения состояние можно проверить наблюдаемыми командами:
cat /etc/centos-release
sudo dnf upgrade --refresh
systemctl --failed
getenforce
sudo firewall-cmd --list-all
sudo sshd -t
sudo nginx -t
systemctl is-active sshd firewalld nginx php-fpm mariadb
chronyc tracking
df -hT
free -h
ss -tulpn
systemctl list-timersБазовая конфигурация считается собранной, когда:
- система получает обновления из ожидаемых репозиториев;
- административный вход работает по SSH-ключу;
- root-вход и парольная аутентификация SSH закрыты;
- firewalld пропускает только используемые сервисы;
- SELinux работает в режиме Enforcing;
- Nginx проходит
nginx -t; - PHP-FPM и MariaDB активны, если они нужны приложению;
- домен разрешается в адрес сервера;
- HTTPS открывается без ошибки сертификата;
- таймер продления сертификата активен;
- резервная копия создаётся и восстанавливается на тестовом окружении;
- свободное место, память и журналы контролируются.
Официальная документация уточняет поведение конкретной версии
Материал опирается на первичные источники проекта CentOS, Red Hat и Fedora:
- CentOS Stream 10 Release Notes;
- сравнение CentOS Linux и CentOS Stream и даты EOL;
- документация CentOS;
- интерактивная установка Enterprise Linux 10;
- защищённые соединения OpenSSH;
- настройка firewalld;
- работа с SELinux;
- установка и настройка Nginx;
- использование PHP;
- настройка MariaDB;
- Extra Packages for Enterprise Linux.
Команды из документации RHEL 10 в большинстве случаев применимы к CentOS Stream 10, поскольку обе системы используют одну технологическую основу. Названия отдельных пакетов и версии приложений меняются по мере обновления Stream, поэтому dnf info, dnf repoquery и локальные man-страницы отражают точное состояние установленной системы.
Рабочий сервер складывается из нескольких проверяемых уровней
CentOS Stream 10 предоставляет операционную основу с DNF, systemd, NetworkManager, firewalld и SELinux. Установка веб-стека добавляет Nginx, PHP-FPM и MariaDB, а доменное имя и TLS-сертификат связывают локальные службы с публичным интернетом.
Надёжность такой системы определяется состоянием каждого уровня: загрузка и диски, сеть и DNS, SSH-доступ, правила firewall, SELinux-метки, процессы приложений, журналы, обновления и резервные копии. Сбой на одном уровне проявляется через конкретные команды, коды состояния и записи журнала, поэтому диагностика остаётся воспроизводимой даже для человека без многолетнего опыта администрирования.
Остается решить, какую прикладную роль выбрать: статический сайт, CMS, базу данных, контейнерную платформу, файловое хранилище или несколько независимых сервисов. Этот выбор влияет на требования к памяти, дискам, резервному копированию и схеме обновлений, но сохраняет базовую архитектуру CentOS Stream.