How to Install & Secure phpMyAdmin for Apache on Debian 13

Install phpMyAdmin on Apache for Debian 13 – DevAnswers.net guide

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 sudo privileges (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.

Terminal
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:

  1. 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.
  2. Configure database for phpmyadmin with dbconfig-common: choose Yes. This creates the internal storage database phpMyAdmin uses for bookmarks, query history, and column comments.
  3. MySQL application password for phpmyadmin: enter a strong generated password (or leave blank to let dbconfig generate one). This is the password for the phpmyadmin internal user, not your login account.

Reload Apache so the new phpmyadmin.conf drop-in is picked up:

Terminal
sudo systemctl reload apache2

Verify by visiting http://your-server-ip/phpmyadmin in a browser. You should see the phpMyAdmin login screen.

You will see the login screen, but you cannot sign in yet. First create a dedicated login user (the next section): on modern systems the root account uses socket authentication and cannot log in through the phpMyAdmin form, so this step is required for every install, whether local or internet-facing. The two sections after it (obfuscating the URL and adding an Apache gateway) are only needed if phpMyAdmin will be reachable from the internet. For a local or LAN-only install, you can stop once the login user exists.

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.

Terminal
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:

MySQL
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:

Terminal
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:

/etc/apache2/conf-enabled/phpmyadmin.conf
Alias /secret-db-92xq7m /usr/share/phpmyadmin

Save and exit (press CTRL + X, press Y, then press ENTER)

Save and reload Apache:

Terminal
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:

Terminal
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:

Terminal
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:

Terminal
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:

/etc/apache2/conf-enabled/phpmyadmin.conf
<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:

Terminal
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/phpmyadmin returns a 404 (the old URL is gone).
  • http://your-server-ip/secret-db-92xq7m triggers the Apache Basic Auth dialog. Wrong gateway password returns HTTP 401.
  • After the gateway, the phpMyAdmin login form loads. Logging in as pmaadmin with 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):

Terminal
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:

/etc/phpmyadmin/config.inc.php
// 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)

phpMyAdmin has no built-in force-HTTPS option (the old ForceSSL setting was removed back in version 4.6). Enforce HTTPS at the web server instead: once you have a TLS certificate, redirect port 80 to 443 in Apache and add a Strict-Transport-Security header so the admin session is always encrypted. See Next Steps below.

Reload Apache one more time:

Terminal
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 configtest returns Syntax OK. Note that /etc/apache2/conf-enabled/phpmyadmin.conf is a symlink to /etc/phpmyadmin/apache.conf, so editing either changes the same file; confirm your edit landed with readlink -f /etc/apache2/conf-enabled/phpmyadmin.conf and 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/sessions owned by root:root with mode 1733 (world-writable but deliberately not listable), so www-data can write to it. Confirm it exists with sudo ls -ld /var/lib/php/sessions; if a custom session.save_path is set in php.ini, make sure that path is writable by www-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-Security header) so admin sessions are always encrypted.
  • Restrict access by IP (paranoid mode): add a Require ip 1.2.3.4 line 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.

Support DevAnswers
Written, tested and maintained by one developer. Your support keeps these guides accurate and ad-light.
Buy me a coffee

Comments

Leave a reply