Installing LEMP stack in AlmaLinux 9, RockyLinux 9 and CentOS Stream 9

Installing LEMP stack

Installing LEMP stack

In this article I will describe in detail the process of installing a LEMP server, configuring a sudo user and a firewall (iptables), and will also present my scripts for automating these processes without using popular hosting panels. Due to the large volume of material, I divided the article into two parts: the first part is devoted to installing a LEMP server and configuring a firewall, and the second part is devoted to configuring a turnkey LEMP server.

In this article we will consider:

  1. Setting up sudo

  2. Setting up Firewall (iptables)

  3. Setting up repositories

  4. Installing PHP

  5. Installing Nginx

  6. Installing MariaDB

LEMP — is an abbreviation for a technology stack consisting of the Linux operating system, the Nginx web server, the MySQL (or MariaDB) database management system, and the PHP interpreter.

Setting up SELinux and ModSecurity and other SIEM systems, as well as setting up a mail server, are extensive topics that require a separate series of articles. We will cover these issues in the future to provide you with detailed and comprehensive guides.

System requirements

Before you begin installation, make sure you have the following:

  • CPU: Minimum 2 cores or more, with a clock speed of 2.0 GHz or higher.

  • Random Access Memory (RAM): Minimum 2GB RAM (4GB or more recommended).

  • HDD: from 20 GB of free space (for better performance use SSD or WMe).

  • Network interface: 100 Mbps or more.

  • Operating system: An updated version of AlmaLinux 9, RockyLinux 9 or CentOS Stream 9.

Prerequisites

  • Internet access to download the required packages.

  • Privilege root or the possibility of use sudo.

  • SSH access to the remote server with the above privileges.

Setting up sudo

If you encounter an error bash: sudo: command not foundthis means that the team sudo is not installed on your server. To fix this situation, follow these steps:

  1. If the package sudo is not installed by default in your operating system, follow the steps below to install it using command dnf install sudo.

  2. Adding a user to a group wheel: By default on CentOS systems, group members wheel have access to sudo. Add a new user to the group wheel:

usermod -aG wheel username

Setting up Firewall (iptables)

Setting up a firewall is a critical step in securing your server. In this section, we will look at how to set up iptables to protect your server and keep it running securely.

Installing iptables-services. To manage iptables, install the iptables-services package:

sudo dnf install -y iptables-services

Disabling the firewalld service:

sudo systemctl disable firewalld 
sudo systemctl stop firewalld

Setting up iptables rules. Create basic rules for iptables. These rules include allowing traffic to standard ports such as SSH (22), HTTP (80), and HTTPS (443):

IPv4:

# Очищаем правила
sudo iptables -F
sudo iptables -X
sudo iptables -t nat -F
sudo iptables -t nat -X
sudo iptables -t mangle -F
sudo iptables -t mangle -X
sudo iptables -P INPUT ACCEPT
sudo iptables -P FORWARD ACCEPT
sudo iptables -P OUTPUT ACCEPT
# Разрешение установленных соединений
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Разрешение входящих соединений на localhost
sudo iptables -A INPUT -i lo -j ACCEPT
# Разрешить входящий ICMP трафик (например, ping)
sudo iptables -A INPUT -p icmp --icmp-type 8 -j ACCEPT
# Разрешить входящий ICMP трафик для Destination Unreachable
sudo iptables -A INPUT -p icmp --icmp-type 3 -j ACCEPT
# Разрешить входящий ICMP трафик для Time Exceeded
sudo iptables -A INPUT -p icmp --icmp-type 11 -j ACCEPT
# Разрешение входящих соединений на порт 22 для SSH
sudo iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# Разрешение входящих соединений на порт 80 для HTTP
sudo iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
# Разрешение входящих соединений на порт 443 для HTTPS
sudo iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
# Установка политики по умолчанию для цепочки INPUT на DROP
sudo iptables -P INPUT DROP

IPv6:

# Очищаем правила
sudo ip6tables -F
sudo ip6tables -X
sudo ip6tables -t nat -F
sudo ip6tables -t nat -X
sudo ip6tables -t mangle -F
sudo ip6tables -t mangle -X
sudo ip6tables -P INPUT ACCEPT
sudo ip6tables -P FORWARD ACCEPT
sudo ip6tables -P OUTPUT ACCEPT
# Разрешение установленных соединений
sudo ip6tables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
# Разрешение входящих соединений на localhost
sudo ip6tables -A INPUT -i lo -j ACCEPT
# Разрешить входящий ICMPv6 трафик (например, ping)
sudo ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 128 -j ACCEPT
# Разрешить входящий ICMPv6 трафик для Destination Unreachable
sudo ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 1 -j ACCEPT
# Разрешить входящий ICMPv6 трафик для Time Exceeded
sudo ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 3 -j ACCEPT
# Разрешение входящих соединений на порт 22 для SSH
sudo ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# Разрешение входящих соединений на порт 80 для HTTP
sudo ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
# Разрешение входящих соединений на порт 443 для HTTPS
sudo ip6tables -A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
# Установка политики по умолчанию для цепочки INPUT на DROP
sudo ip6tables -P INPUT DROP

Saving the rules. After setting up the rules, save them to be applied automatically on reboot:

IPv4:

sudo service iptables save

IPv6:

sudo service ip6tables save

Enabling and starting the iptables and ip6tables service. To enable and start the iptables firewall, run the following commands:

IPv4:

sudo systemctl enable iptables 
sudo systemctl start iptables

IPv6:

sudo systemctl enable ip6tables 
sudo systemctl start ip6tables

Checking the configuration. Make sure that iptables rules are configured and applied correctly:

IPv4:

sudo iptables -L -vn

IPv6:

sudo ip6tables -L -vn

These steps will provide basic security for your server by allowing access only to necessary services and blocking unauthorized traffic.

Important! It is recommended that you carefully read the official documentation on setting up Firewall (iptables): Documentation about the netfilter/iptables project.

Setting up repositories

Before installing packages, you need to update your system so that all packages are up to date and set up the necessary repositories.

Updating packages. First, let's update all packages in the system:

sudo dnf update -y

Setting up Nginx repositories. Let's create a repository file for Nginx and add the necessary parameters:

sudo tee /etc/yum.repos.d/nginx.repo << EOF
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/rhel/\$releasever/\$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true


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

Setting up Remi repositories. Let's install Remi repositories to access different versions of PHP (7.4, 8.0, 8.1, 8.2, 8.3):

sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm -y

Setting up EPEL repositories. Let's add EPEL repositories for additional packages:

sudo dnf install -y epel-release -y

Setting up MariaDB repositories. Let's set up MariaDB 11.4 repositories using the official script:

curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version="mariadb-11.4"

Example output of the command to add a MariaDB repository:

[unixweb@localhost ~]# curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | sudo bash -s -- --mariadb-server-version="mariadb-11.4"
# [info] Checking for script prerequisites.
# [warning] Found existing file at /etc/yum.repos.d/mariadb.repo. Moving to /etc/yum.repos.d/mariadb.repo.old_1
# [info] MariaDB Server version 11.4 is valid
# [info] Repository file successfully written to /etc/yum.repos.d/mariadb.repo
# [info] Adding trusted package signing keys...
/etc/pki/rpm-gpg ~
~
# [info] Successfully added trusted package signing keys
# [info] Cleaning package cache...
93 files removed

It is recommended that you carefully read the official documentation on setting up MariaDB repositories: MariaDB Repository Setup.

Installing PHP

For installation PHP 8.1 and the required extensions on Linux distributions that use the DNF package manager (e.g. AlmaLinux 9, RockyLinux 9, CentOS Stream 9), run the following commands:

Reset PHP module. First, reset the current PHP module to avoid conflicts with already installed PHP versions.

sudo dnf module reset php -y

Enabling PHP 8.1 module. Then enable the PHP module version 8.1 from the Remi repository, which contains the latest versions of PHP.

sudo dnf module enable php:remi-8.1 -y

Installing PHP 8.1 and required extensions. Install PHP 8.1 and many extensions needed to work with various functions and databases.

sudo dnf install php81 php81-php-fpm php81-php-cli php81-php-mysqlnd php81-php-gd php81-php-ldap php81-php-odbc php81-php-pdo php81-php-pear php81-php-xml php81-php-xmlrpc php81-php-mbstring php81-php-snmp php81-php-soap php81-php-zip php81-php-opcache -y

Enabling and starting the PHP-FPM service. Enable the PHP-FPM service to start automatically on system boot and start it immediately.

sudo systemctl enable --now php81-php-fpm.service

PHP 8.1 and its required extensions are now installed and configured on your server. PHP-FPM is running and configured to start automatically on system boot. For more detailed information and further configuration, it is recommended to read the official PHP and PHP-FPM documentation.

Installing Nginx

Nginx ensures consistently high website performance even under significant loads, which is why it is widely used for high-load web services around the world.

It is worth noting that many popular content management systems (CMS), such as WordPress, are initially optimized to work with Apache. This means that some of their features may require specific configuration of rewrite rules to work correctly with Nginx.

To install Nginx, run the following command:

sudo dnf install nginx --repo nginx-stable -y

Set up Nginx in three easy steps. After installing Nginx, you need to make changes to the file /etc/nginx/nginx.conf and in the nginx service settings in systemd.

1. Copy the script shown below:

#!/bin/bash
# Copyright (C) 2024 
# Автор: Крячко Алексей
# Электронная почта: admin@unixweb.info 
# Веб-сайт: https://unixweb.info 
# GitHub: https://github.com/unixweb-info 

set -euo pipefail

# Переименование старого конфигурационного файла Nginx
if [ -f /etc/nginx/nginx.conf ]; then
    mv /etc/nginx/nginx.conf /etc/nginx/nginx.conf.old
else
    echo "/etc/nginx/nginx.conf not found!"
    exit 1
fi

# Получение количества физических ядер
phycores=$(grep -m 1 "cpu cores" /proc/cpuinfo | awk '{print $4}')
if [[ -z "$phycores" ]]; then
    echo "Failed to retrieve the number of physical cores."
    exit 1
fi

# Настройка /etc/nginx/nginx.conf
cat <<EOF > /etc/nginx/nginx.conf
# Этот файл был сгенерирован автоматически, не редактируйте его
user apache;
worker_processes $phycores;
worker_rlimit_nofile 200000;
worker_priority -5;
pcre_jit on;

include /etc/nginx/modules-enabled/*.conf;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  2048;
    use epoll;
    multi_accept on;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
                    '\$status \$body_bytes_sent "\$http_referer" '
                    '\"\$http_user_agent\" \"\$http_x_forwarded_for\"';
    access_log /var/log/nginx/access.log main;
    keepalive_timeout 65;
    client_max_body_size 100m;
    server_tokens off;
    reset_timedout_connection on;

    client_body_buffer_size 10K;
    client_header_buffer_size 1k;
    large_client_header_buffers 4 4k;

    sendfile on;
    aio on;
    tcp_nopush on;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*.conf;

    server_names_hash_bucket_size 128;
}
EOF

# Дополнительная настройка Nginx /etc/nginx/conf.d/99-my-settings.conf
cat <<EOF > /etc/nginx/conf.d/99-my-settings.conf
fastcgi_temp_path /var/cache/nginx/fastcgi_temp 1 2;
fastcgi_cache_path /var/cache/nginx/fastcgi_cache levels=1:2 keys_zone=two:60m max_size=256m inactive=24h;
fastcgi_cache_key "\$scheme\$request_method\$host\$request_uri";
fastcgi_cache_methods GET HEAD;
fastcgi_cache_min_uses 2;

open_file_cache max=100000 inactive=20s;
open_file_cache_valid 45s;
open_file_cache_min_uses 2;
open_file_cache_errors on;

fastcgi_send_timeout 3600s;
fastcgi_read_timeout 3600s;
fastcgi_connect_timeout 3600s;
fastcgi_buffer_size   128k;
fastcgi_buffers   4 256k;
fastcgi_busy_buffers_size   256k;

client_body_timeout   1800s;
client_header_timeout  900s;
send_timeout  1800s;
EOF

# Настройка nginx в systemd
nginx_service="/lib/systemd/system/nginx.service"

# Проверка существования файла
if [ -f "$nginx_service" ]; then
    # Добавление LimitNOFILE=200000 в раздел [Service]
    if ! grep -q "LimitNOFILE=200000" "$nginx_service"; then
        sed -i '/\[Service\]/a LimitNOFILE=200000' "$nginx_service"
    fi
else
    echo "$nginx_service not found!"
    exit 1
fi

# Перезагрузка systemd
systemctl daemon-reload

# Проверяем статус nginx
if systemctl is-active --quiet nginx; then
  echo "Nginx работает."
else
  echo "Nginx не запускается. Запускаем Nginx..."
  # Запускаем Nginx
  systemctl start nginx
  
  # Проверяем, успешно ли запущен Nginx
  if systemctl is-active --quiet nginx; then
    echo "Nginx успешно запустился."
  else
    echo "Не удалось запустить Nginx."
  fi
fi
  1. Save the file, for example, under the name settings_nginx.shhaving previously copied the contents of the script and exit the editor.

  2. Make the script executable and then run it:

chmod +x ./settings_nginx.sh && sudo ./settings_nginx.sh

This script does the following:

1. Backup the old Nginx configuration file:

If the file /etc/nginx/nginx.conf exists, it is renamed to /etc/nginx/nginx.conf.oldIf the file is not found, the script terminates with an error.

2. Getting the number of physical cores:

Determines the number of physical cores of the processor using the command grep And awk.

3. Create a new Nginx configuration file:

4. Creating an additional Nginx configuration file:

5. Configuring the Nginx service in systemd:

  • Checks if a file exists /lib/systemd/system/nginx.service.

  • Adds a line LimitNOFILE=200000 to section [Service]if it has not been added yet.

  • Reloads the systemd configuration.

  • A check is performed if Nginx is not running, the message “Nginx is not running. Starting Nginx…” and the command to start it is executed. If Nginx is running, the message “Nginx is running.”

This script automatically generates the Nginx configuration and updates the service to reflect the new settings.

Additional actions:

After installation and execution of scripts, you need to restart Nginx, if you made any changes in the configuration files, run the command 'sudo systemctl restart nginx' or 'sudo systemctl reload nginx'. After running the script, be sure to run the command 'sudo systemctl enable nginx' so that it starts automatically when the system boots.

# Перезапуск сервиса Nginx (полная перезагрузка):
sudo systemctl restart nginx

# или так (перезагрузка только конфигурации, без остановки сервиса):
sudo systemctl reload nginx

# Включение автоматического запуска Nginx при загрузке системы:
sudo systemctl enable nginx

Check the Nginx status to make sure the server is running:

sudo systemctl status nginx

This is just a small list of Nginx commands. It is recommended to familiarize yourself with official documentation for more complete information.

Installing MariaDB

MySQL It is a popular database management system. You can also use MariaDBwhich is a fork of MySQL and is fully compatible with it.

To install MariaDB, run the following command:

sudo dnf install mariadb-server mariadb -y

After installation, make sure the MariaDB service is running. If it is not running, run the command sudo systemctl start mariadb and configure the service to start automatically when the system boots:

# Проверка статуса MariaDB: 
# Эта команда выводит текущий статус службы MariaDB. 
# Полезно для проверки, запущена ли служба и работает ли корректно.
sudo systemctl status mariadb

# Запуск MariaDB:
# Эта команда запускает службу MariaDB, если она не запущена. 
# Полезно при первой настройке или если служба была остановлена.
sudo systemctl start mariadb

# Включение автоматического запуска MariaDB при загрузке системы:
# Эта команда добавляет службу MariaDB в автозагрузку, 
# что означает, что MariaDB будет автоматически запускаться при каждой загрузке системы. 
sudo systemctl enable mariadb

To initially configure database security, run the script mariadb-secure-installation:

sudo mariadb-secure-installation

Follow the on-screen instructions to set up a root password and improve database security:

[unixweb@localhost ~]# sudo mariadb-secure-installation

ПРИМЕЧАНИЕ: РЕКОМЕНДУЕТСЯ ЗАПУСКАТЬ ВСЕ ЧАСТИ ЭТОГО СЦЕНАРИЯ ДЛЯ ВСЕХ СЕРВЕРОВ MariaDB
  	В ПРОИЗВОДСТВЕННОМ ИСПОЛЬЗОВАНИИ!  ПОЖАЛУЙСТА, ВНИМАТЕЛЬНО ПРОЧИТАЙТЕ КАЖДЫЙ ШАГ!

Чтобы войти в MariaDB для его защиты, нам понадобится текущий
пароль для пользователя root. Если вы только что установили MariaDB, и
еще не установили пароль root, вы должны просто нажать enter здесь.

Введите текущий пароль для root (введите для отсутствия):
OK, успешно использован пароль, продолжаем...

Установка пароля root или использование unix_socket гарантирует, что никто
не сможет войти в MariaDB под пользователем root без надлежащего разрешения.

У вас уже защищен аккаунт root, поэтому вы можете безопасно ответить 'n'.

Переключиться на аутентификацию через unix_socket [Y/n] Y
Успешно включено!
Перезагрузка таблиц привилегий..
 ... Успех!

У вас уже защищен аккаунт root, поэтому вы можете безопасно ответить 'n'.

Изменить пароль root? [Y/n] Y
Новый пароль:
Повторите новый пароль:
Пароль успешно обновлён!
Перезагрузка таблиц привилегий..
 ... Успех!

По умолчанию, установка MariaDB имеет анонимного пользователя, позволяющего любому
войти в MariaDB, не имея созданного для них учетной записи пользователя.  Это предназначено только для тестирования, и чтобы установка
шла немного глаже. Вы должны удалить их, прежде чем переходить в
производственную среду.

Удалить анонимных пользователей? [Y/n] Y
 ... Успех!

Обычно, root должен иметь возможность подключаться только с 'localhost'.Это
гарантирует, что кто-то не сможет угадать пароль root по сети.

Запретить удаленный вход под root? [Y/n] Y
 ... Успех!

По умолчанию, MariaDB поставляется с базой данных под названием 'test', к которой может
доступить любой.  Это также предназначено только для тестирования, и должно быть удалено
перед переходом в производственную среду.

Удалить тестовую базу данных и доступ к ней? [Y/n] Y
 - Удаление тестовой базы данных...
 ... Успех!
 - Удаление привилегий на тестовую базу данных...
 ... Успех!

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

Перезагрузить таблицы привилегий сейчас? [Y/n] Y
 ... Успех!

Очистка...

Все готово!  Если вы выполнили все вышеперечисленные шаги, ваша установка MariaDB
теперь должна быть безопасной.

Спасибо за использование MariaDB!

The script has been translated into Russian for ease of understanding.

Basic MariaDB configuration. MariaDB auto-configuration script:

1. Copy the script shown below:

#!/bin/bash
# Copyright (C) 2024 
# Автор: Крячко Алексей
# Электронная почта: admin@unixweb.info 
# Веб-сайт: https://unixweb.info 
# GitHub: https://github.com/unixweb-info 

# Проверяем, установлен ли пакет bc
if ! command -v bc &> /dev/null; then
    echo "Пакет bc не установлен. Устанавливаю..."
    sudo dnf install -y bc
else
    echo "Пакет bc уже установлен."
fi

if [ ! -d "/var/log/mariadb" ]; then
    mkdir -p /var/log/mariadb
    touch /var/log/mariadb/error.log
    chown -R mysql:adm /var/log/mariadb
fi

CPU_CORES=$(grep -c ^processor /proc/cpuinfo)
TOTAL_MEM=$(free -m | awk '/^Mem:/{print $2}')

CPU_CORES_REF=4
MEM_REF=8192
SCALE_CPU=$(echo "$CPU_CORES / $CPU_CORES_REF" | bc -l)
SCALE_MEM=$(echo "$TOTAL_MEM / $MEM_REF" | bc -l)

calculate_new_value() {
    local original_value=$1
    local scale_factor=$2
    echo $(echo "$original_value * $scale_factor" | bc -l | xargs printf "%.0f")
}

innodb_buffer_pool_size=5368709120
innodb_buffer_pool_instances=5
max_allowed_packet=134217728
thread_cache_size=64
tmp_table_size=536870912
max_connections=2000
max_user_connections=1000
table_open_cache=8192
innodb_open_files=8192
read_buffer_size=16777216
join_buffer_size=134217728
sort_buffer_size=16777216
binlog_cache_size=33554432
key_buffer_size=268435456
query_cache_limit=134217728
query_cache_min_res_unit=1024
query_cache_size=134217728

new_innodb_buffer_pool_size=$(calculate_new_value $innodb_buffer_pool_size $SCALE_MEM)
new_innodb_buffer_pool_instances=$(calculate_new_value $innodb_buffer_pool_instances $SCALE_CPU)
new_max_allowed_packet=$(calculate_new_value $max_allowed_packet $SCALE_MEM)
new_thread_cache_size=$(calculate_new_value $thread_cache_size $SCALE_CPU)
new_tmp_table_size=$(calculate_new_value $tmp_table_size $SCALE_MEM)
new_max_connections=$(calculate_new_value $max_connections $SCALE_CPU)
new_max_user_connections=$(calculate_new_value $max_user_connections $SCALE_CPU)
new_table_open_cache=$(calculate_new_value $table_open_cache $SCALE_CPU)
new_innodb_open_files=$(calculate_new_value $innodb_open_files $SCALE_CPU)
new_read_buffer_size=$(calculate_new_value $read_buffer_size $SCALE_MEM)
new_join_buffer_size=$(calculate_new_value $join_buffer_size $SCALE_MEM)
new_sort_buffer_size=$(calculate_new_value $sort_buffer_size $SCALE_MEM)
new_binlog_cache_size=$(calculate_new_value $binlog_cache_size $SCALE_MEM)
new_key_buffer_size=$(calculate_new_value $key_buffer_size $SCALE_MEM)
new_query_cache_limit=$(calculate_new_value $query_cache_limit $SCALE_MEM)
new_query_cache_min_res_unit=$(calculate_new_value $query_cache_min_res_unit $SCALE_MEM)
new_query_cache_size=$(calculate_new_value $query_cache_size $SCALE_MEM)

convert_to_mb() {
    echo "$(echo "$1 / 1048576" | bc)M"
}

convert_to_gb() {
    echo "$(echo "$1 / 1073741824" | bc)G"
}

cat << EOF > /etc/my.cnf.d/my-settings.cnf
[mysqld]
bind-address=127.0.0.1
log_error=/var/log/mariadb/error.log
symbolic-links=0
innodb_strict_mode=OFF
event_scheduler=ON
sql_mode=""
local-infile=0
max_allowed_packet=$(convert_to_mb $new_max_allowed_packet)
thread_stack=256K
long_query_time=10
disable-log-bin=1
log-queries-not-using-indexes=1
innodb_buffer_pool_size=$(echo "$new_innodb_buffer_pool_size / 1048576" | bc)M
innodb_buffer_pool_instances=${new_innodb_buffer_pool_instances}
innodb_flush_log_at_trx_commit=2
innodb_flush_method=O_DIRECT
transaction-isolation=READ-COMMITTED
innodb_log_file_size=512M
max_heap_table_size=512M
thread_cache_size=${new_thread_cache_size}
tmp_table_size=$(echo "$new_tmp_table_size / 1048576" | bc)M
innodb_file_per_table=1
table_open_cache=${new_table_open_cache}
innodb_open_files=${new_innodb_open_files}
read_buffer_size=$(echo "$new_read_buffer_size / 1048576" | bc)M
join_buffer_size=$(echo "$new_join_buffer_size / 1048576" | bc)M
sort_buffer_size=$(echo "$new_sort_buffer_size / 1048576" | bc)M
binlog_cache_size=$(echo "$new_binlog_cache_size / 1048576" | bc)M
key_buffer_size=$(echo "$new_key_buffer_size / 1048576" | bc)M
table_definition_cache=4051
interactive_timeout=60
wait_timeout=60
performance_schema=ON
open_files_limit=65721
max-connect-errors=10000
max_connections=${new_max_connections}
max_user_connections=${new_max_user_connections}
query_cache_limit=$(echo "$new_query_cache_limit / 1048576" | bc)M
query_cache_min_res_unit=${new_query_cache_min_res_unit}
query_cache_size=$(echo "$new_query_cache_size / 1048576" | bc)M
query_cache_type=ON
EOF

echo "Конфигурационный файл MariaDB создан в /etc/my.cnf.d/my-settings.cnf"

systemctl daemon-reload
systemctl restart mariadb
  1. Save the file, for example, under the name settings_mariadb.shhaving previously copied the contents of the script and exit the editor.

  2. Make the script executable and then run it:

chmod +x ./settings_mariadb.sh && sudo ./settings_mariadb.sh

This script automatically configures MariaDB according to the system characteristics, these settings are enough for stable operation of WordPress and other CMS, but under high loads, the script requires revision. Database optimization is a worthy topic for a separate article, but now I wanted to share this solution.
I would appreciate constructive comments and suggestions from engineers for further improvement of the script.

This completes the setup. For a more detailed study of MariaDB, it is recommended to read official documentation.

Completion of Part One: Installing LEMP stack on AlmaLinux 9, RockyLinux 9 and CentOS Stream 9. This concludes the first part of the article, dedicated to installing a LEMP server. Although not all the steps are described here, thank you for understanding!

In the next article, Part 2: Setting up a LEMP server to run WordPress CMS on AlmaLinux 9, RockyLinux 9 or CentOS Stream 9we will describe:

  1. Creating a Linux User

  2. Setting up a virtual host

  3. Checking PHP operation

  4. Working with MariaDB database

  5. Let's Encrypt Setup

  6. Installing and Configuring Fail2ban

Automation Script: UnixWeb Panel

Automation Script: UnixWeb Panel

Automation Script: UnixWeb Panel

In conclusion of this article, a bash script UnixWeb Panel is presented, which will be relevant for a private server and small projects. This script eliminates the need for bulky hosting panels. The lack of a web interface makes the work more hardcore, while you get open source code and minimalistic functionality that can be adapted to your needs.

UnixWeb Panel is distributed under the license GNU General Public License v3.0. The script code is open for review and modification, which allows system administrators to easily adapt it to their needs.

I would appreciate constructive criticism and feedback to improve the functionality.

For more information and access to the script, visit my GitHub repository .

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *