Install and Secure phpMyAdmin on a Linux VPS

3 min
VPS/VDS Hosting

phpMyAdmin is a convenient web interface for MariaDB and MySQL, and also one of the most scanned URLs on the Internet. This guide shows two installations on your VPS Linux Infrawire, the apt package with Apache and a manual install behind Nginx, then the measures that keep it out of reach of bots.

📋 Prerequisites

  • A VPS running Ubuntu 24.04 or Debian 12, with root or sudo access (IP and root password are available in your client area)
  • A working LAMP stack (option A) or LEMP stack (option B) with MariaDB
  • Your own public IP, referred to below as ADMIN_IP

1. Option A: install the apt package with Apache

Bash
apt update apt install -y phpmyadmin php-mbstring php-zip php-gd php-curl

In the installer, select apache2 with the space bar (an asterisk must appear), then answer "Yes" to configure the database with dbconfig-common and set a password for the internal phpMyAdmin account. Then reload Apache:

Bash
phpenmod mbstring systemctl reload apache2

phpMyAdmin is now served at http://VPS_IP/phpmyadmin.

2. Create a dedicated database user

Never log in as root. On MariaDB under Ubuntu and Debian, root uses unix_socket authentication and phpMyAdmin will refuse it anyway: leave it that way and create a normal account.

Bash
mariadb
SQL
CREATE USER 'pmauser'@'localhost' IDENTIFIED BY 'STRONG_PASSWORD'; GRANT ALL PRIVILEGES ON appdb.* TO 'pmauser'@'localhost'; FLUSH PRIVILEGES; EXIT;

Grant rights only on the databases the user really manages. Do not enable AllowNoPassword in the configuration.

3. Hide the URL and add authentication (Apache)

Change the default alias to a random one, and create a password file:

Bash
SUFFIX=$(openssl rand -hex 6); echo "pma-$SUFFIX" sed -i "s#Alias /phpmyadmin#Alias /pma-$SUFFIX#" /etc/phpmyadmin/apache.conf htpasswd -c /etc/phpmyadmin/.htpasswd USER

Then add these lines inside the existing <Directory /usr/share/phpmyadmin> block of /etc/phpmyadmin/apache.conf:

Apache
1AuthType Basic 2AuthName 'Restricted area' 3AuthUserFile /etc/phpmyadmin/.htpasswd 4<RequireAll> 5 Require valid-user 6 Require ip ADMIN_IP 7</RequireAll>

Without <RequireAll>, Apache would accept either condition; with it, both the password and the IP are required.

Bash
apache2ctl configtest && systemctl reload apache2

4. Option B: manual install behind Nginx

Install the dependencies, then download the latest release from the official phpMyAdmin site (replace VERSION with the current number):

Bash
apt install -y nginx php-fpm php-mysql php-mbstring php-xml php-zip php-gd php-curl apache2-utils cd /tmp wget https://files.phpmyadmin.net/phpMyAdmin/VERSION/phpMyAdmin-VERSION-all-languages.tar.gz tar xzf phpMyAdmin-VERSION-all-languages.tar.gz mkdir -p /var/www/pma mv phpMyAdmin-VERSION-all-languages /var/www/pma/pma-SECRET cd /var/www/pma/pma-SECRET cp config.sample.inc.php config.inc.php openssl rand -hex 16

Replace pma-SECRET with a random name. Edit config.inc.php and paste the generated value (32 characters) as the secret:

PHP
$cfg['blowfish_secret'] = 'RANDOM_32_CHARS'; $cfg['TempDir'] = '/var/lib/phpmyadmin/tmp';
Bash
mkdir -p /var/lib/phpmyadmin/tmp chown www-data:www-data /var/lib/phpmyadmin/tmp chmod 700 /var/lib/phpmyadmin/tmp chown -R root:www-data /var/www/pma chmod 640 /var/www/pma/pma-SECRET/config.inc.php htpasswd -c /etc/nginx/.htpasswd USER

Add this block inside the server { ... } of your site. On Debian 12 the socket is php8.2-fpm.sock instead of php8.3-fpm.sock:

Nginx
1location ^~ /pma-SECRET/ { 2 allow ADMIN_IP; 3 deny all; 4 auth_basic 'Restricted area'; 5 auth_basic_user_file /etc/nginx/.htpasswd; 6 root /var/www/pma; 7 index index.php; 8 9 location ~ \.php$ { 10 include snippets/fastcgi-php.conf; 11 fastcgi_pass unix:/run/php/php8.3-fpm.sock; 12 } 13}
Bash
nginx -t && systemctl reload nginx

5. The safest option: an SSH tunnel

If you do not want any public exposure, keep the interface reachable only from the VPS and open a tunnel from your computer:

Bash
ssh -L 8080:127.0.0.1:80 USER@VPS_IP

While the session is open, browse to http://127.0.0.1:8080/pma-SECRET/. On Apache, restrict the block to Require local instead of Require ip ADMIN_IP; on Nginx, use allow 127.0.0.1;. This also solves the problem of a changing home IP.

6. Verify the protection

Bash
curl -sI http://VPS_IP/phpmyadmin | head -n 1 curl -sI http://VPS_IP/pma-SECRET/ | head -n 1

The first request must return 404. The second returns 403 from any IP other than ADMIN_IP, and 401 from yours until you provide the basic auth password. Also serve phpMyAdmin over HTTPS only, otherwise the passwords travel in clear text.

🛠️ Troubleshooting

404 Not Found. The alias or location name does not match the URL you typed, or the web server was not reloaded.

403 Forbidden for you. Your public IP changed. Update ADMIN_IP, or switch to the SSH tunnel.

"The mbstring extension is missing" or a blank page. Install php-mbstring, then run phpenmod mbstring (Apache) or restart php8.3-fpm (Nginx).

Access denied for root. This is expected and desirable. Log in with the dedicated user created in step 2.


🎉 phpMyAdmin is installed, hidden and restricted: only you can reach your databases.

Stay up to date with the latest offers, discounts and special promotions.

View promotions

We use cookies

We use analytics cookies to improve your experience on our site. No data is sold to third parties. Learn more in our privacy policy.