CentOS Stream 10 — установка и настройка сервера с нуля для начинающих

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 vCPU2 ГБ20–25 ГБПодходит для SSH и простых служб
Небольшой статический сайт1–2 vCPU2 ГБ25–40 ГБNginx, журналы, сертификаты
PHP-сайт с MariaDB2 vCPU4 ГБ40–80 ГБЗапас памяти нужен PHP-FPM и базе данных
Несколько сайтов или контейнеров4 vCPU8 ГБот 80 ГБОбъём зависит от баз, образов и резервных копий
Файловое хранилище2–4 vCPU4–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/efi600 МБEFI System PartitionЗагрузка UEFI
/boot1 ГБXFSЯдра и GRUB
swap2–4 ГБswapРезерв памяти
/25 ГБXFSСистема и пакеты
/var35 ГБ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 repolist

dnf history показывает транзакции установки, удаления и обновления. Подробности конкретной операции доступны по номеру:

sudo dnf history info 12

CentOS Stream 10 использует основные репозитории BaseOS и AppStream. Репозиторий CRB содержит дополнительные библиотеки и инструменты разработки и по умолчанию выключен:

sudo dnf config-manager --set-enabled crb
sudo dnf repolist

Команда dnf config-manager входит в пакет плагинов. Если она отсутствует:

sudo dnf install dnf-plugins-core

EPEL добавляет пакеты 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 --show

Swap не заменяет оперативную память: активная работа с ним замедляет сервер. Он даёт системе дополнительное время при кратком скачке потребления и снижает вероятность немедленного завершения процесса из-за нехватки памяти.

Администраторская учётная запись отделяет повседневную работу от 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 --reload

Firewalld открывает только порты работающих служб

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-all

Firewalld хранит две конфигурации:

  • 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 nginx

nginx -t проверяет синтаксис до перечитывания. Ошибка сообщает имя файла и номер строки.

DNS связывает домен с публичным адресом

У регистратора или DNS-провайдера создаются записи:

ТипИмяЗначение
A@публичный IPv4 сервера
Awwwпубличный IPv4 сервера
AAAA@публичный IPv6 сервера, если он настроен
AAAAwwwпубличный 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-fpm

post_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 mariadb

SQL-команды:

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.com

Certbot проверяет домены через 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-pager

IP в 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.sh

Timer /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-pager

Persistent=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/.ssh

Nginx возвращает 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 recent

MariaDB не запускается

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:

Команды из документации 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.

При использовании материалов сайта необходимо указывать ссылку на TGLand.ru. Если вы копируете фрагменты текста в интернете, прямая гиперссылка, доступная для индексации поисковыми системами, должна быть размещена в начале материала.

Вам также может понравиться