We may earn a referral fee at no additional cost to you when you shop through the links on this page.
Installing phpMyAdmin on Apache gives you a browser-based GUI for your MariaDB or MySQL databases. This DevAnswers guide walks through a complete, security-hardened install on Debian 13 (Trixie) with the distro’s stock phpMyAdmin 5.x, Apache 2.4, and PHP 8.4 from the official repositories.
The walkthrough covers the interactive installer’s three prompts, a dedicated admin login user (not root), URL obfuscation to kill bot traffic, an Apache Basic Auth gateway in front of the phpMyAdmin login, and two extra config.inc.php hardening lines for once HTTPS is in place.
Prerequisites
You need a running LAMP stack on Debian 13 (Trixie) (Apache 2.4, MariaDB 11.8, and PHP 8.4) before installing phpMyAdmin. If you haven’t built one yet, follow our complete LAMP stack guide for Debian 13 (Trixie) first.
- A non-root user with
sudoprivileges (see our initial server setup guide if you haven’t created one). - The MariaDB or MySQL root account reachable via
sudo mysql(the unix_socket default on modern Debian 13 (Trixie)). - Recommended: a domain name pointed at the server. Examples below use
devanswers.test; substitute your real domain.
Install phpMyAdmin and Required Extensions
The distro packages bundle phpMyAdmin with a working Apache configuration. You also need php-mbstring for character-encoding support and php-zip for the import/export feature, both of which the phpMyAdmin web UI complains about if missing.
sudo apt update
sudo apt install -y phpmyadmin php8.4-mbstring php8.4-zip
The installer drops you into an interactive debconf prompt. Three answers matter:
- Web server to configure automatically: press Space to tick
apache2, then Tab and Enter. Without ticking this, phpMyAdmin installs but Apache won’t serve it. - Configure database for phpmyadmin with dbconfig-common: choose Yes. This creates the internal storage database phpMyAdmin uses for bookmarks, query history, and column comments.
- MySQL application password for phpmyadmin: enter a strong generated password (or leave blank to let dbconfig generate one). This is the password for the
phpmyadmininternal user, not your login account.
Reload Apache so the new phpmyadmin.conf drop-in is picked up:
sudo systemctl reload apache2
Verify by visiting http://your-server-ip/phpmyadmin in a browser. You should see the phpMyAdmin login screen.
Create a Dedicated phpMyAdmin Login User
Don’t log into phpMyAdmin as root. On modern Debian 13 (Trixie), the root account uses unix_socket authentication (which only works for local shell access), so password login as root fails at the phpMyAdmin login screen. This step is required whether or not phpMyAdmin will ever face the internet: without a password-authenticated user, you cannot log in at all. Create a dedicated database user with the privileges you actually need.
sudo mysql
At the prompt, create a privileged user. GRANT ALL ... WITH GRANT OPTION makes this an effectively all-powerful administrative account, which suits a single-administrator phpMyAdmin box where you manage every database. If you only ever work with one application database, a narrower grant such as GRANT ALL ON app_db.* is safer. Replace change-this-strong-password with a strong generated password before running:
CREATE USER 'pmaadmin'@'localhost' IDENTIFIED BY 'change-this-strong-password';
GRANT ALL PRIVILEGES ON *.* TO 'pmaadmin'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;
You’ll use pmaadmin as the phpMyAdmin login username from now on. The phpmyadmin internal user that dbconfig created stays as a system account; never log in with it directly.
Obfuscate the phpMyAdmin URL
Security through obscurity isn’t a real layer, but it blocks the overwhelming majority of automated scanners, which only ever probe the default path. /phpmyadmin is one of the most heavily scanned URLs on the internet. Changing it to something random kills automated brute-force attempts before they reach Apache’s authentication layer.
Edit Apache’s phpMyAdmin config:
sudo nano /etc/apache2/conf-enabled/phpmyadmin.conf
Find the first line (it’ll read Alias /phpmyadmin /usr/share/phpmyadmin) and change the alias to a random path. Use a passphrase or random string you’ll remember; the example below uses secret-db-92xq7m:
Alias /secret-db-92xq7m /usr/share/phpmyadmin
Save and exit (press CTRL + X, press Y, then press ENTER)
Save and reload Apache:
sudo apache2ctl configtest
sudo systemctl reload apache2
The old /phpmyadmin URL now 404s; phpMyAdmin is reachable only at http://your-server-ip/secret-db-92xq7m. Note this URL: you’ll need it again in a moment.
Add an .htpasswd Gateway
Apache Basic Auth in front of phpMyAdmin gives you a second authentication factor. An attacker who somehow discovers your obfuscated URL still has to break a separate Apache password before reaching the phpMyAdmin login form. Two independent password hurdles defeats every commodity brute-force tool.
Install the Apache password-file utility if it isn’t already present:
sudo apt install -y apache2-utils
Create a password file outside the web root so it can’t be served as static content. Replace gatekeeper with whatever username you want for the gateway:
sudo htpasswd -c /etc/apache2/.htpasswd gatekeeper
You’ll be prompted to enter and confirm a password. The -c flag creates the file; omit it when adding additional users later.
Now wire the password file into Apache’s phpMyAdmin config. Open the file again:
sudo nano /etc/apache2/conf-enabled/phpmyadmin.conf
Find the <Directory /usr/share/phpmyadmin> block. Inside it, add the four authentication directives shown below. Place them before the <IfModule> blocks that handle PHP options:
<Directory /usr/share/phpmyadmin>
Options SymLinksIfOwnerMatch
DirectoryIndex index.php
# Apache Basic Auth gateway (added by us)
AuthType Basic
AuthName "Restricted Access"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
# ...existing IfModule php and IfModule mod_php blocks stay below...
</Directory>
Save and exit (press CTRL + X, press Y, then press ENTER)
Save and reload Apache:
sudo apache2ctl configtest
sudo systemctl reload apache2
Browse to your obfuscated URL again. Before phpMyAdmin’s login form loads, Apache pops a browser-native authentication dialog: enter your gateway username (gatekeeper) and password. Only then do you reach phpMyAdmin’s own login, where you sign in as pmaadmin.
Verify the Setup End-to-End
Run through the full happy path one more time to confirm both layers work:
http://your-server-ip/phpmyadminreturns a 404 (the old URL is gone).http://your-server-ip/secret-db-92xq7mtriggers the Apache Basic Auth dialog. Wrong gateway password returns HTTP 401.- After the gateway, the phpMyAdmin login form loads. Logging in as
pmaadminwith the correct password lands you on the phpMyAdmin dashboard. Wrong pmaadmin password returns to the login form with an error. - Confirm you can see all databases on the left sidebar (your grant covers
*.*).
Optional: Harden config.inc.php
Two more low-cost settings improve the security posture. Edit phpMyAdmin’s local config (created automatically by dbconfig):
sudo nano /etc/phpmyadmin/config.inc.php
Add (or set) the following lines near the bottom of the file, before the final ?> if it exists:
// Disallow login with an empty password.
$cfg['Servers'][$i]['AllowNoPassword'] = false;
// Shorten the admin login session to 15 minutes (default is 1440 seconds, 24 minutes).
$cfg['LoginCookieValidity'] = 900;
Save and exit (press CTRL + X, press Y, then press ENTER)
Reload Apache one more time:
sudo systemctl reload apache2
Troubleshooting
Three issues come up often enough to call out:
- Obfuscated URL still 404s after reload: check the Alias line for trailing whitespace and make sure
configtestreturnsSyntax OK. Note that/etc/apache2/conf-enabled/phpmyadmin.confis a symlink to/etc/phpmyadmin/apache.conf, so editing either changes the same file; confirm your edit landed withreadlink -f /etc/apache2/conf-enabled/phpmyadmin.confand re-check the Alias line. - “Cannot start session without errors” on the login form: the session directory is unwritable. On Debian and Ubuntu it ships as
/var/lib/php/sessionsowned byroot:rootwith mode1733(world-writable but deliberately not listable), sowww-datacan write to it. Confirm it exists withsudo ls -ld /var/lib/php/sessions; if a customsession.save_pathis set inphp.ini, make sure that path is writable bywww-data. - Forgot the obfuscated URL: grep the Apache config for it:
sudo grep '^Alias' /etc/apache2/conf-enabled/phpmyadmin.conf.
Next Steps
- Add HTTPS with a free Let’s Encrypt certificate: follow our Secure Apache with Let’s Encrypt SSL on Debian 13 (Trixie) guide. Once HTTPS is working, add an Apache redirect from port 80 to 443 (plus a
Strict-Transport-Securityheader) so admin sessions are always encrypted. - Restrict access by IP (paranoid mode): add a
Require ip 1.2.3.4line inside the Apache<Directory>block to allow only your own IP. Effectively makes phpMyAdmin a private interface. - Set up a daily database backup: see our
mysqldump+ cron backup guide, or use a managed backup add-on. Install phpMyAdmin without a backup story and the convenience becomes a liability the first time someone clicks “Drop” on the wrong table.
Conclusion
Your Debian 13 server now hosts a phpMyAdmin instance reachable only via an obfuscated URL behind an Apache Basic Auth gateway, with a dedicated login user that sits separately from the system MariaDB root account.
From here, install a TLS certificate so the gateway and phpMyAdmin login travel encrypted, then uncomment the ForceSSL line in config.inc.php. After that, layer on an IP allowlist if you genuinely don’t need remote access from arbitrary networks; for a single-admin setup that’s the single biggest improvement to the security posture left.
Comments