XAMPP bundles Apache, MariaDB, PHP, and Perl into a single installer, which makes it the fastest way to spin up a local development stack on Rocky Linux or AlmaLinux. The catch on RHEL-based systems is that several shared libraries XAMPP depends on have been removed from the default install, so the installer will fail silently or throw cryptic errors if you don’t handle those first.
This guide walks through the full XAMPP setup on Rocky Linux 10/9 and AlmaLinux 10/9, including the dependency fixes that trip up most people, firewalld rules, SELinux considerations, a systemd service for automatic startup, and deploying a WordPress site on top of it. If you’re on Ubuntu or Debian, check the Ubuntu guide or Debian guide instead.
Tested April 2026 on Rocky Linux 10.1 with XAMPP 8.2.12 (PHP 8.2.12, Apache 2.4.58, MariaDB 10.4.32), SELinux permissive
Prerequisites
- Rocky Linux 10/9 or AlmaLinux 10/9 with root or sudo access
- Tested on: Rocky Linux 10.1 (kernel 6.12), AlmaLinux 10
- At least 1 GB RAM and 2 GB free disk space
- No existing Apache, MySQL/MariaDB, or PHP installation (XAMPP brings its own)
Install Required Dependencies
Rocky Linux 10 and AlmaLinux 10 stripped out two libraries that XAMPP still needs. Without them, both Apache and PHP crash on startup with shared library errors. Install these before touching the XAMPP installer:
sudo dnf install -y wget net-tools libnsl libxcrypt-compat
Here’s what each package does:
libxcrypt-compatprovideslibcrypt.so.1, which XAMPP’s PHP and Apache binaries link against. Without it you geterror while loading shared libraries: libcrypt.so.1libnslprovides the NIS library that XAMPP’s MySQL/MariaDB binary expectsnet-toolsgives younetstat, which XAMPP’s control scripts use internallywgetfor downloading the installer
On Rocky 9 and AlmaLinux 9, libnsl is usually already present but libxcrypt-compat still needs to be installed. On Rocky/AlmaLinux 8, both libraries ship by default.
RHEL Version Differences
If you manage servers across multiple RHEL releases, here’s what to expect:
| Item | Rocky/Alma 10 | Rocky/Alma 9 | Rocky/Alma 8 |
|---|---|---|---|
| libxcrypt-compat | Must install | Must install | Pre-installed |
| libnsl | Must install | Usually installed | Pre-installed |
| SELinux | Enforcing (needs permissive for XAMPP) | Enforcing | Enforcing |
| egrep warning | Yes (grep -E) | No | No |
| Firewall | firewalld (may need install) | firewalld | firewalld |
Download and Install XAMPP
Grab the XAMPP installer from SourceForge. The version variable keeps the download command clean and easy to update:
export PHP_VER="8.2.12"
wget "https://sourceforge.net/projects/xampp/files/XAMPP%20Linux/${PHP_VER}/xampp-linux-x64-${PHP_VER}-0-installer.run/download" -O xampp-installer.run
Make the installer executable and run it in unattended mode:
chmod +x xampp-installer.run
sudo ./xampp-installer.run --mode unattended
The installer extracts everything to /opt/lampp. No package manager involvement, no dependency resolution. That’s both the appeal and the drawback of XAMPP.
Configure SELinux
XAMPP writes to /opt/lampp extensively, and SELinux in enforcing mode blocks most of those operations. For a development environment, switching to permissive mode is the practical choice:
sudo setenforce 0
sudo sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
Verify the change took effect:
getenforce
The output should read Permissive.
For a production-like environment where you want SELinux enforcing, you would need to label the XAMPP directories and create a custom policy. Set the correct file contexts on the XAMPP tree:
sudo semanage fcontext -a -t httpd_sys_content_t "/opt/lampp/htdocs(/.*)?"
sudo semanage fcontext -a -t httpd_log_t "/opt/lampp/logs(/.*)?"
sudo semanage fcontext -a -t httpd_tmp_t "/opt/lampp/temp(/.*)?"
sudo restorecon -Rv /opt/lampp
Then allow Apache to make network connections (needed for PHP connecting to MariaDB):
sudo setsebool -P httpd_can_network_connect on
sudo setsebool -P httpd_can_network_connect_db on
The permissive approach is simpler and perfectly fine for local development. Use the custom policy route only if this box faces the internet.
Configure the Firewall
Rocky Linux uses firewalld. Open HTTP and HTTPS ports so you can reach the XAMPP dashboard from your browser:
sudo dnf install -y firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --add-port=80/tcp --permanent
sudo firewall-cmd --add-port=443/tcp --permanent
sudo firewall-cmd --reload
Confirm the ports are open:
sudo firewall-cmd --list-ports
You should see 80/tcp 443/tcp in the output.
Start XAMPP
Launch all XAMPP services with the bundled control script:
sudo /opt/lampp/lampp start
On Rocky Linux 10, you’ll see a few egrep deprecation warnings:
egrep: warning: egrep is obsolescent; using grep -E
Starting XAMPP for Linux 8.2.12-0...
XAMPP: Starting Apache...ok.
XAMPP: Starting MySQL...ok.
XAMPP: Starting ProFTPD...ok.
These warnings are harmless. Rocky 10 ships grep 3.x which flags the old egrep binary, but XAMPP’s internal scripts still call it. Everything works fine despite the noise.
Verify the Installed Versions
Check which versions XAMPP bundled:
/opt/lampp/bin/php -v
/opt/lampp/bin/mysql --version
/opt/lampp/bin/httpd -v
Expected output confirms PHP 8.2.12, MariaDB 10.4.32, and Apache 2.4.58:
PHP 8.2.12 (cli) (built: Oct 24 2023 21:15:15) (NTS)
/opt/lampp/bin/mysql Ver 15.1 Distrib 10.4.32-MariaDB, for Linux (x86_64)
Server version: Apache/2.4.58 (Unix)
Access the XAMPP Dashboard
Open your browser and navigate to http://10.0.1.50/dashboard/ (replace with your server’s IP). The default XAMPP dashboard should load:

phpMyAdmin is available at http://10.0.1.50/phpmyadmin/:

The PHP info page at http://10.0.1.50/dashboard/phpinfo.php shows the full PHP configuration:

Create a systemd Service
XAMPP doesn’t ship with a systemd unit file, so it won’t survive a reboot unless you create one. Open the service file:
sudo vi /etc/systemd/system/xampp.service
Add this unit definition:
[Unit]
Description=XAMPP Service
After=network.target
[Service]
Type=forking
ExecStart=/opt/lampp/lampp start
ExecStop=/opt/lampp/lampp stop
ExecReload=/opt/lampp/lampp reload
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable --now xampp
Check that it’s running:
sudo systemctl status xampp
The service should show active (exited) since XAMPP forks its own processes. After a reboot, Apache, MariaDB, and ProFTPD will start automatically.
Secure the XAMPP Installation
Out of the box, XAMPP has no passwords set and allows network access to phpMyAdmin. Run the security script to lock things down:
sudo /opt/lampp/lampp security
The script walks through several prompts:
- Set a password for the XAMPP directory protection (htpasswd for
/dashboard) - Set the MySQL/MariaDB root password
- Set a password for the phpMyAdmin user
- Set a password for the ProFTPD admin
Set strong passwords for all of them. The MariaDB root password is especially important if the server is reachable from the network.
After setting the MariaDB root password, phpMyAdmin needs to know about it. Edit the phpMyAdmin config:
sudo vi /opt/lampp/phpmyadmin/config.inc.php
Find the authentication section and update these values:
$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['password'] = '';
Setting auth_type to cookie forces a login prompt instead of auto-connecting as root. Restart XAMPP after the change:
sudo /opt/lampp/lampp restart
Deploy WordPress on XAMPP
With Apache, PHP, and MariaDB running, WordPress takes about two minutes to deploy. Start by creating a database and user.
Create the WordPress Database
Connect to the MariaDB shell:
/opt/lampp/bin/mysql -u root -p
Create the database, user, and grant privileges:
CREATE DATABASE wordpress;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'StrongPassword123';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Download and Configure WordPress
Download the latest WordPress release into the XAMPP web root:
cd /opt/lampp/htdocs
sudo wget https://wordpress.org/latest.tar.gz
sudo tar -xzf latest.tar.gz
sudo rm latest.tar.gz
Set up the WordPress config file with the database credentials:
cd /opt/lampp/htdocs/wordpress
sudo cp wp-config-sample.php wp-config.php
sudo vi wp-config.php
Update the database settings to match what you created earlier:
define( 'DB_NAME', 'wordpress' );
define( 'DB_USER', 'wpuser' );
define( 'DB_PASSWORD', 'StrongPassword123' );
define( 'DB_HOST', 'localhost' );
define( 'DB_CHARSET', 'utf8mb4' );
define( 'DB_COLLATE', '' );
Also update the authentication keys and salts in the same file. Generate fresh values from the WordPress secret key generator and paste them in.
Set ownership so XAMPP’s Apache process can write to the WordPress directory:
sudo chown -R daemon:daemon /opt/lampp/htdocs/wordpress
XAMPP runs Apache as the daemon user by default, not www-data like Debian-based systems.
Run the WordPress Installer
Open http://10.0.1.50/wordpress/ in your browser. The WordPress setup wizard will ask for the site title, admin username, password, and email. Fill those in and click Install:

WordPress is now running on XAMPP with the full LAMP stack on Rocky Linux.
Upgrade to a Newer PHP Version
XAMPP bundles a specific PHP version. To upgrade, you need to download a newer XAMPP release. The process is straightforward but requires backing up your data first.
Back up your web files and databases:
sudo cp -r /opt/lampp/htdocs ~/htdocs-backup
/opt/lampp/bin/mysqldump -u root -p --all-databases > ~/all-databases.sql
Stop XAMPP and remove the old installation:
sudo /opt/lampp/lampp stop
sudo rm -rf /opt/lampp
Download and install the newer XAMPP version (replace the version number with the latest from the XAMPP downloads page):
export PHP_VER="8.3.14"
wget "https://sourceforge.net/projects/xampp/files/XAMPP%20Linux/${PHP_VER}/xampp-linux-x64-${PHP_VER}-0-installer.run/download" -O xampp-installer.run
chmod +x xampp-installer.run
sudo ./xampp-installer.run --mode unattended
Restore your web files and import the databases:
sudo cp -r ~/htdocs-backup/* /opt/lampp/htdocs/
sudo /opt/lampp/lampp start
/opt/lampp/bin/mysql -u root -p < ~/all-databases.sql
Confirm the new PHP version:
/opt/lampp/bin/php -v
Troubleshooting
error while loading shared libraries: libcrypt.so.1
This is the most common XAMPP failure on Rocky Linux 10 and AlmaLinux 10. The full error looks like:
/opt/lampp/bin/httpd: error while loading shared libraries: libcrypt.so.1: cannot open shared object file: No such file or directory
The fix is one package:
sudo dnf install -y libxcrypt-compat
This installs the compatibility library at /lib64/libcrypt.so.1. Restart XAMPP after installing.
XAMPP is currently only availably as 32 bit application
This warning appears on some Rocky 10 installs and looks alarming, but it's misleading. The actual problem is missing shared libraries, not a 32-bit/64-bit mismatch. Installing libxcrypt-compat and libnsl resolves it:
sudo dnf install -y libxcrypt-compat libnsl
Apache Fails to Bind to Port 80
If another web server (like the system Apache from httpd package) is already running on port 80, XAMPP's Apache can't start. Check what's using the port:
sudo ss -tlnp | grep :80
If you see httpd in the output, stop and disable the system Apache:
sudo systemctl stop httpd
sudo systemctl disable httpd
Then restart XAMPP.
MariaDB Won't Start
Check the error log for details:
cat /opt/lampp/var/mysql/$(hostname).err
Common causes include a stale PID file or leftover socket. Remove them and restart:
sudo rm -f /opt/lampp/var/mysql/*.pid
sudo rm -f /opt/lampp/var/mysql/mysql.sock
sudo /opt/lampp/lampp restart
Uninstall XAMPP
If you need to remove XAMPP completely, stop the services first:
sudo /opt/lampp/lampp stop
Remove the systemd service file and reload:
sudo systemctl disable xampp
sudo rm /etc/systemd/system/xampp.service
sudo systemctl daemon-reload
Delete the XAMPP directory:
sudo rm -rf /opt/lampp
That removes everything. XAMPP doesn't scatter files across the filesystem, so deleting /opt/lampp is a clean removal. The dependency packages (libxcrypt-compat, libnsl) can stay since they don't cause any harm.
Production Considerations
XAMPP is a development tool, not a production stack. The Apache Friends project says so explicitly on their site. If you're planning to host a public-facing site, install Apache, PHP, and MariaDB separately from the Rocky Linux repositories. You get security updates through dnf update, proper SELinux integration, and systemd management that actually works with the system's package manager.
For local development and testing, XAMPP saves time. It bundles known-working versions of the stack and keeps everything self-contained in /opt/lampp. Just remember that XAMPP's bundled versions don't receive security patches unless you download a new XAMPP release. Keep an eye on PHP and Apache CVEs if you leave XAMPP running for extended periods.