How To

How to Run, Secure, and Uninstall XAMPP on Linux

Installing XAMPP is the easy part. The questions that follow are the ones that actually cost time: why Apache refuses to start when the distro already runs its own web server, how to bring the stack up automatically after a reboot, what the lampp security script really changes, and how to remove everything cleanly when a project ends. This guide covers the full day-2 workflow for XAMPP on Linux, with every command executed on a real machine and every error reproduced before its fix was written down.

Original content from computingforgeeks.com - post 165825

If XAMPP is not on the box yet, start with the install guide for your distro: Ubuntu, Debian, Fedora, or Rocky Linux and AlmaLinux. Everything below applies to all of them, because XAMPP ships the same self-contained stack under /opt/lampp regardless of distribution.

Ran through all of this on a clean Ubuntu 24.04 VM with XAMPP 8.2.12 in August 2026, including the ProFTPD breakage covered near the end.

Where XAMPP Lives on a Linux System

The installer puts the entire stack, Apache, MariaDB, PHP, Perl and ProFTPD, under a single directory. Nothing registers with the package manager and nothing lands in /etc, which is why apt or dnf know nothing about it. The paths you will touch most:

PathWhat it holds
/opt/lampp/lamppThe control script for the whole stack
/opt/lampp/htdocsWeb root, where your PHP projects go
/opt/lampp/etcConfig files (httpd.conf, my.cnf, proftpd.conf, php.ini)
/opt/lampp/var/mysqlMariaDB data directory
/opt/lampp/logsApache error and access logs
/opt/lampp/binBundled binaries (mysql, php, ftpasswd and friends)

Because the stack is self-contained, none of the usual systemctl start apache2 or systemctl start mariadb commands apply. The lampp script is the only interface, until you wire it into systemd yourself further down.

Start, Stop and Check XAMPP on Linux

Bring the whole stack up with one command:

sudo /opt/lampp/lampp start

Each component reports individually as it comes up:

Starting XAMPP for Linux 8.2.12-0...
XAMPP: Starting Apache...ok.
XAMPP: Starting MySQL...ok.
XAMPP: Starting ProFTPD...ok.

A live run looks like this. Here the installer had already left ProFTPD up, so it reports already running instead:

XAMPP on Linux starting Apache, MySQL and ProFTPD from the lampp control script

The counterparts are stop, restart and status. Status is worth memorising because it names exactly which component is down instead of leaving you to guess:

sudo /opt/lampp/lampp status

A healthy stack reports all three services running:

Version: XAMPP for Linux 8.2.12-0
Apache is running.
MySQL is running.
ProFTPD is running.

Then confirm the web tier answers. Opening http://localhost in a browser redirects to the XAMPP dashboard at /dashboard/:

XAMPP for Linux dashboard on localhost confirming Apache, MariaDB and PHP are running

The dashboard page itself states that XAMPP is meant only for development. Take that seriously: the defaults trade security for convenience, which is exactly what the security section below exists to walk back.

Error: “xampplib: line 22: netstat: command not found”

XAMPP’s helper scripts still probe ports with netstat, which modern minimal Ubuntu and Debian installs no longer ship. When a script restarts a service you get this in the middle of otherwise normal output:

XAMPP: Starting MySQL.../opt/lampp/share/xampp/xampplib: line 22: netstat: command not found
ok.

The service still starts, but the port checks silently stop working. One package fixes it:

sudo apt install net-tools

On Fedora, Rocky or AlmaLinux the equivalent is sudo dnf install net-tools.

Control Apache, MySQL and ProFTPD Individually

You rarely need the whole stack. Working on a PHP app that only touches the database? There is no reason to run an FTP daemon. The lampp script accepts per-service actions, and running it with no arguments prints the full list:

Usage: lampp <action>

	start         Start XAMPP (Apache, MySQL and eventually others)
	startapache   Start only Apache
	startmysql    Start only MySQL
	startftp      Start only ProFTPD

	stop          Stop XAMPP (Apache, MySQL and eventually others)
	stopapache    Stop only Apache
	stopmysql     Stop only MySQL
	stopftp       Stop only ProFTPD

	reload        Reload XAMPP (Apache, MySQL and eventually others)
	reloadapache  Reload only Apache
	reloadmysql   Reload only MySQL
	reloadftp     Reload only ProFTPD

	restart       Stop and start XAMPP
	security      Check XAMPP's security

	enablessl     Enable SSL support for Apache
	disablessl    Disable SSL support for Apache

	backup        Make backup file of your XAMPP config, log and data files

So a config change to httpd.conf needs only:

sudo /opt/lampp/lampp reloadapache

And the bundled MariaDB client connects over the local socket without any service names to remember:

/opt/lampp/bin/mysql -u root -e "SELECT VERSION();"

Which returns the MariaDB build XAMPP actually ships, not whatever your distro packages:

VERSION()
10.4.32-MariaDB

Fix “XAMPP: Another web server is already running”

This is the most common XAMPP failure on Linux, and it means exactly what it says: something else already owns port 80. Usually it is the distribution’s own Apache or Nginx, installed as a dependency of some other package and enabled at boot. The failure looks like this:

XAMPP: Starting Apache...fail.
XAMPP:  Another web server is already running.

Note that only Apache fails; MySQL and ProFTPD carry on starting normally around it:

XAMPP Apache fails to start with another web server is already running error on Linux

Before killing anything, confirm who actually holds the port:

sudo ss -ltnp | grep ":80 "

Here the system Apache owns it, with three worker processes listed:

LISTEN 0  511  *:80  *:*  users:(("apache2",pid=19523,fd=4),("apache2",pid=19522,fd=4),("apache2",pid=19520,fd=4))

Stop the conflicting server and prevent it from returning on the next boot. For the distro Apache:

sudo systemctl disable --now apache2

If ss showed Nginx instead, the command is sudo systemctl disable --now nginx. On RHEL-family distros the Apache unit is named httpd. Then start XAMPP’s Apache again:

sudo /opt/lampp/lampp startapache

This time it binds cleanly:

XAMPP: Starting Apache...ok.

Start XAMPP Automatically at Boot with systemd

XAMPP installs no service unit, so after every reboot the stack is down until someone runs lampp start by hand. A small oneshot unit fixes that. Create it:

sudo vim /etc/systemd/system/xampp.service

Add the following unit definition:

[Unit]
Description=XAMPP for Linux
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/opt/lampp/lampp start
ExecStop=/opt/lampp/lampp stop

[Install]
WantedBy=multi-user.target

Reload systemd, then enable and start the unit in one step:

sudo systemctl daemon-reload
sudo systemctl enable --now xampp.service

The unit shows active (exited), which is correct for a oneshot service whose job is to launch other processes:

● xampp.service - XAMPP for Linux
     Loaded: loaded (/etc/systemd/system/xampp.service; enabled; preset: enabled)
     Active: active (exited) since Mon 2026-08-17 11:18:48 UTC; 2s ago
    Process: 682 ExecStart=/opt/lampp/lampp start (code=exited, status=0/SUCCESS)

A reboot test confirmed the whole stack came back on its own, with Apache answering on port 80 seconds after login. One caveat from that testing: systemd marks the unit failed if lampp start exits non-zero, and it exits non-zero when any single component fails to start. So if ProFTPD is broken (see the section below), your Apache and MariaDB still start but the unit reports failed. Fix the failing component rather than papering over the exit code.

Serve Your Own PHP Project from htdocs

Anything under /opt/lampp/htdocs is served by Apache immediately. Quick proof:

sudo vim /opt/lampp/htdocs/test.php

With one line of PHP inside:

<?php echo "XAMPP on Linux: PHP " . PHP_VERSION . " is working\n"; ?>

Fetch it and the bundled PHP interpreter answers:

curl http://localhost/test.php

The response comes from XAMPP’s own PHP build:

XAMPP on Linux: PHP 8.2.12 is working

The web root belongs to root, so rather than editing everything through sudo, give your own user a project directory:

sudo mkdir -p /opt/lampp/htdocs/myapp
sudo chown -R $USER:$USER /opt/lampp/htdocs/myapp

From here your editor, git and build tools work in /opt/lampp/htdocs/myapp without permission errors, and the app is live at http://localhost/myapp/.

Secure XAMPP with the lampp security Script

A fresh XAMPP install has no MariaDB root password, a passwordless pma account for phpMyAdmin, MariaDB listening on the network, and an FTP account with the default password xampp. The bundled audit script walks through all of it interactively:

sudo /opt/lampp/lampp security

Answer yes to each prompt and give real passwords. The transcript from the test box, trimmed of the password prompt lines (the spelling mistakes are XAMPP’s own):

XAMPP:  Quick security check...
XAMPP:  MySQL is accessable via network.
XAMPP: Normaly that's not recommended. Do you want me to turn it off? [yes]
XAMPP:  Turned off.
XAMPP:  The MySQL/phpMyAdmin user pma has no password set!!!
XAMPP: Do you want to set a password? [yes]
XAMPP:  Setting new MySQL pma password.
XAMPP:  MySQL has no root passwort set!!!
XAMPP: Do you want to set a password? [yes]
XAMPP:  Setting new MySQL root password.
XAMPP:  Change phpMyAdmin's authentication method.
XAMPP:  The FTP password for user 'daemon' is still set to 'xampp'.
XAMPP: Do you want to change the password? [yes]
XAMPP:  Done.

On a later run, anything already fixed reports clean and only the remaining items prompt again, which doubles as a quick audit of the instance:

Running sudo /opt/lampp/lampp security to set MySQL root password and secure XAMPP on Linux

Two of these answers change daily behaviour. Turning off network access adds skip-networking, so MariaDB stops listening on TCP 3306 and is reachable only through the local socket, which is what the bundled client and PHP use anyway. And once root has a password, connections need the -p flag:

/opt/lampp/bin/mysql -u root -p

Even secured, this stack skips the hardening a distro package gets. Keep it bound to localhost and never port-forward it to the internet.

Fix ProFTPD: “unknown configuration directive ‘function'”

Here is the bug the security script does not warn you about. On the current XAMPP for Linux build, letting lampp security change the FTP password corrupts the ProFTPD config. The next start fails like this:

XAMPP: Starting ProFTPD...fail.
Contents of "/opt/lampp/var/proftpd/start.err":
proftpd[20289]: fatal: unknown configuration directive 'function' on line 44 of '/opt/lampp/etc/proftpd.conf'

The cause is visible in the config file: the script tried to generate a password hash with a PHP helper, the helper did not execute, and the raw PHP source code got written into proftpd.conf where the hash should be. ProFTPD then chokes on the word function. The fix is to generate a valid hash yourself and replace the garbage. First create the hash:

openssl passwd -1 'YourFtpPassword'

Copy the output, which looks like this:

$1$.i5bmO/J$LHZrUhc5k6b12zbNhFE2A0

Then open the config:

sudo vim /opt/lampp/etc/proftpd.conf

Delete everything from the line UserPassword daemon <? down to the closing ?>, and put a single clean directive in its place with your hash:

UserPassword daemon $1$.i5bmO/J$LHZrUhc5k6b12zbNhFE2A0

Start the FTP service again:

sudo /opt/lampp/lampp startftp

It reports XAMPP: Starting ProFTPD...ok. this time, and an FTP login as daemon with the new password lists the contents of htdocs, which is what that account serves. With ProFTPD healthy again, lampp start returns to exit code 0 and the systemd unit from earlier stops reporting failures. If you never use FTP to reach htdocs, the simpler path is skipping the FTP password prompt in the security script entirely and just not starting the service.

Uninstall XAMPP Completely

XAMPP ships its own uninstaller binary. Stop the stack, remove the systemd unit if you created one, then run it:

sudo systemctl disable --now xampp.service
sudo rm -f /etc/systemd/system/xampp.service
sudo systemctl daemon-reload
sudo /opt/lampp/uninstall

Add --mode unattended to the uninstall command to skip the confirmation dialog. Either way, the uninstaller deliberately leaves your data behind. After it finished on the test machine, this is what survived:

/opt/lampp/htdocs
/opt/lampp/htdocs/myapp
/opt/lampp/var/mysql

Your projects and the MariaDB data directory are preserved so a reinstall can pick them up. If you want the machine genuinely clean, back up anything worth keeping from htdocs, dump any databases you need, then remove the directory:

sudo rm -rf /opt/lampp

That is the entire footprint. No packages to purge, no stray configs in /etc. If you are removing XAMPP because a project graduated beyond it, the natural next step is a native stack with proper systemd units and unattended security updates: the LAMP setup guide for Ubuntu and its Debian equivalent cover that move end to end.

Keep reading

Claude Code Cheat Sheet – Commands, Shortcuts, Tips AI Claude Code Cheat Sheet – Commands, Shortcuts, Tips Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) Ubuntu Upgrade Ubuntu 24.04 to Ubuntu 26.04 LTS (Step by Step) Create Bootable Windows USB and Install Windows 11 Windows Create Bootable Windows USB and Install Windows 11 Best NAS Case for a DIY Build: ITX to 12-Bay Chassis Storage Best NAS Case for a DIY Build: ITX to 12-Bay Chassis Best HBA Card for TrueNAS: IT-Mode SAS Cards for ZFS Storage Best HBA Card for TrueNAS: IT-Mode SAS Cards for ZFS Setup MariaDB Galera Cluster on Ubuntu 24.04 with ProxySQL Databases Setup MariaDB Galera Cluster on Ubuntu 24.04 with ProxySQL

Leave a Comment

Press ESC to close