LEMP Server Installation Guide on AlmaLinux 10
This guide shows how to set up a LEMP server (Linux, Nginx, MariaDB and PHP; the "E" comes from how Nginx is pronounced, "engine-x") on AlmaLinux 10, so you can host websites without a control panel. When you finish, your server will run:
- Nginx 1.26 web server
- MariaDB 10.11 database server (a drop-in replacement for MySQL)
- PHP 8.3, run through PHP-FPM
- A free Let's Encrypt SSL certificate for your website
AlmaLinux 10 is the newest AlmaLinux release and receives security updates until 2035. AlmaLinux 10 no longer uses module streams, so the default packages are the versions above.
The version numbers are from October 2026; regular updates may install newer releases of the same versions. If you'd rather use Apache, see our LAMP guides.
Nginx and .htaccess files
Nginx doesn't read .htaccess files. Settings that applications put in .htaccess, such as rewrite rules for friendly URLs, go in the website's Nginx configuration instead (step 6). The configuration in this guide already handles friendly URLs for WordPress and most other PHP applications.
Before you start
- A server running a fresh installation of AlmaLinux 10, such as an Acenet cloud server, virtual server or dedicated server, with no control panel installed.
- Root access over SSH. Run every command in this guide as root, or put sudo in front of it.
- A domain name whose A record points to your server's IP address. In this guide, replace example.com with your own domain.
Step 1: Update the server
dnf -y update
If the update installed a new kernel, restart the server with reboot and log in again.
Step 2: Install Nginx
Install Nginx and start it:
dnf -y install nginx systemctl enable --now nginx
Open http://your-server-ip/ in a browser. You should see the Nginx test page. If the page doesn't load, open the firewall first (step 3).
Step 3: Open the firewall
If firewalld is running (the command below prints active), allow web traffic through it:
systemctl is-active firewalld firewall-cmd --permanent --add-service=http --add-service=https firewall-cmd --reload
If you use a different firewall, allow incoming connections on ports 80 (HTTP) and 443 (HTTPS).
Step 4: Install MariaDB
Install MariaDB, start it, and secure it:
dnf -y install mariadb-server systemctl enable --now mariadb mariadb-secure-installation
The mariadb-secure-installation script asks a few questions:
- Enter current password for root: press Enter (there is none yet).
- Switch to unix_socket authentication and Change the root password: answering n is fine. The database's root user can only log in as the server's root user, through mariadb on the command line, which is secure without a password.
- Answer Y to remove anonymous users, disallow root login remotely, remove the test database and reload the privilege tables.
Step 5: Install PHP
Install PHP-FPM and the extensions most websites need (for example WordPress):
dnf -y install php-fpm php-cli php-mysqlnd php-gd php-mbstring php-xml php-opcache php-intl php-pecl-zip
PHP-FPM runs as the apache user by default. Change it to Nginx's user, so PHP can write to your website's files. PHP keeps its session and cache files in folders that belong to the apache group, so also add the nginx user to that group:
sed -i -e 's/^user = apache/user = nginx/' -e 's/^group = apache/group = nginx/' /etc/php-fpm.d/www.conf usermod -a -G apache nginx
Start PHP-FPM, and restart Nginx so it loads the PHP-FPM connection settings that came with PHP (/etc/nginx/conf.d/php-fpm.conf):
systemctl enable --now php-fpm systemctl restart nginx php -v
Step 6: Set up your website
Each website gets its own folder and its own Nginx configuration file (a "server block").
1. Create the folder and give it to Nginx's user:
mkdir -p /var/www/example.com/public_html chown -R nginx:nginx /var/www/example.com
2. Create /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_html;
index index.php 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/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass php-fpm;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
The try_files line sends requests for pages that don't exist as files to index.php, which is what WordPress and most PHP applications need for friendly URLs. The last block stops visitors from downloading any .htaccess files that come with an application.
3. Check the configuration and reload Nginx:
nginx -t systemctl reload nginx
SELinux
AlmaLinux 10 has SELinux turned on. Files in /var/www are already labeled so Nginx and PHP can read them, but not write to them. If your website needs to write files (for example uploads or a cache folder), label that folder as writable, replacing the path with your own:
dnf -y install policycoreutils-python-utils semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/example.com/public_html/wp-content(/.*)?" restorecon -Rv /var/www/example.com/public_html/wp-content
If your website connects to a database or an API on another server, also allow it to make network connections:
setsebool -P httpd_can_network_connect 1
Step 7: Test PHP
Create a test page in your website's folder:
echo '<?php phpinfo();' > /var/www/example.com/public_html/info.php
Open http://example.com/info.php. You should see the PHP information page showing PHP 8.3 and Server API: FPM/FastCGI. Then delete the test page, because it shows details about your server that visitors shouldn't see:
rm /var/www/example.com/public_html/info.php
Step 8: Create a database and user for your website
Log in to MariaDB as root:
mariadb
Run these commands, replacing the database name, user name and password with your own (use a long, random password):
CREATE DATABASE exampledb; CREATE USER 'exampleuser'@'localhost' IDENTIFIED BY 'a-strong-password'; GRANT ALL PRIVILEGES ON exampledb.* TO 'exampleuser'@'localhost'; FLUSH PRIVILEGES; EXIT;
Your website's software connects with these details and host localhost. Upload your website's files to /var/www/example.com/public_html.
Step 9: Add a free SSL certificate
Install Certbot and its Nginx plugin from the EPEL repository, and get a certificate:
dnf -y install epel-release dnf -y install certbot python3-certbot-nginx certbot --nginx -d example.com -d www.example.com
Certbot asks for an email address for renewal notices, gets the certificate, and adds HTTPS to your website's Nginx configuration, including a redirect from HTTP to HTTPS.
Let's Encrypt certificates last 90 days. Turn on automatic renewal and test it:
systemctl enable --now certbot-renew.timer certbot renew --dry-run
Keep your server updated
Install updates regularly, so you get security fixes for Nginx, MariaDB, PHP and the operating system:
dnf -y update
To install security updates automatically, you can use dnf-automatic.
Where to find things
| Item | Location |
|---|---|
| Nginx configuration | /etc/nginx/nginx.conf and /etc/nginx/conf.d/ |
| Nginx logs | /var/log/nginx/ |
| PHP settings | /etc/php.ini and /etc/php.d/ |
| PHP-FPM settings and log | /etc/php-fpm.d/www.conf and /var/log/php-fpm/ |
| MariaDB settings | /etc/my.cnf.d/ |
| Restart a service | systemctl restart nginx (or php-fpm, or mariadb) |
If you have any questions, please open a support ticket from your client area.