Guides

Install phpMyAdmin on Ubuntu and Debian, and lock it down

Install phpMyAdmin on Ubuntu 24.04 or Debian 12/13: sudo apt install phpmyadmin, tick apache2 with Space (nginx: add a location block), then lock it down.

Published · Updated ~11 min read
On this page

Short answer: on Ubuntu 22.04, 24.04 or 26.04 and Debian 12 or 13, install the packaged phpMyAdmin with apt. When the installer asks which web server to configure, press Space to tick apache2 and only then Enter. Skipping the Space is the most common reason /phpmyadmin answers 404 afterwards. On Ubuntu 22.04, add libapache2-mod-php to the command: that release’s package installs Apache without its PHP module, and the browser then gets PHP code instead of the login page. On nginx, tick nothing and add the location block from the nginx section. Then log in with a database user of your own, not root, and close the page to everyone but you.

Ubuntu · Debian
sudo apt update
sudo apt install phpmyadmin

The packaged version gets security updates through apt, so you never have to remember to patch it. The rest of this guide covers the steps around that command, the nginx setup, and the part most guides skip: keeping the page away from the bots that request /phpmyadmin on every IP address they find.

Which error do you see?

Already installed and something is wrong? Find the text you see on the left. The strings are copied from the programs that print them, so you can search this page for them.

You seeCauseFix
The requested URL was not found on this server.Apache's 404 page: phpMyAdmin's config was never enabled, because apache2 was not ticked during installApache 404
ERROR: Conf phpmyadmin does not exist!a2enconf found no link in conf-available; the installer only creates it when apache2 was tickedApache 404
404 Not Foundnginx: no location for /phpmyadmin/ in the server blocknginx setup
403 Forbiddennginx: phpMyAdmin linked into the web root without index.php as an index file, or your address is not in the allow list403 and PHP code
The browser downloads index.php or shows PHP codeThe web server is not passing .php files to PHP; with Apache on Ubuntu 22.04, its PHP module was never installed403 and PHP code
502 Bad Gatewaynginx: fastcgi_pass names a PHP-FPM socket that does not exist, or PHP-FPM is stopped502 Bad Gateway
#1698 - Access denied for user 'root'@'localhost'The database root user logs in through the OS account, not a passwordCreate a login user
mysqli::real_connect(): (HY000/2002): No such file or directoryNo MySQL or MariaDB server is running on this machineDatabase not running
ERROR 1819 (HY000): Your password does not satisfy the current policy requirementsMySQL's password policy rejected the phpmyadmin user's password during installPassword policy
The mysqli extension is missing. Please check your PHP configuration.The PHP version that serves the page has no php-mysql modulephpMyAdmin messages
E: Unable to locate package phpmyadminUbuntu: the universe component is off, or apt's lists are staleBefore you start

What each release installs

Both distributions build the package from the same sources, so the installer asks the same questions everywhere. What differs is the phpMyAdmin and PHP version, the name of the PHP-FPM socket that nginx needs, and on Ubuntu 22.04 one dependency (see step 3). Checked on packages.debian.org and packages.ubuntu.com on 11 October 2026:

ReleasephpMyAdminPHPPHP-FPM socketComponent
Ubuntu 22.045.1.18.1/run/php/php8.1-fpm.sockuniverse
Ubuntu 24.045.2.18.3/run/php/php8.3-fpm.sockuniverse
Ubuntu 26.045.2.38.5/run/php/php8.5-fpm.sockuniverse
Debian 125.2.18.2/run/php/php8.2-fpm.sockmain
Debian 135.2.28.4/run/php/php8.4-fpm.sockmain

On all five, PHP-FPM also maintains /run/php/php-fpm.sock, a link to the socket of the newest PHP version that is running. The nginx examples below use that name, so they survive a PHP upgrade. Debian 13 ships phpMyAdmin in main; there is nothing to enable and no backport to add.

Before you start

  • A server running Ubuntu or Debian, and a user with sudo.
  • Port 80 (and 443 for HTTPS) open in your firewall.
  • On Ubuntu, the universe component enabled. It is on standard images; on minimal ones, apt answers E: Unable to locate package phpmyadmin until you run sudo add-apt-repository universe and sudo apt update. If that command is missing, see add-apt-repository: command not found. Other causes of the apt error are in Unable to locate package.

Install with Apache

  1. 1Update the system
    Ubuntu · Debian
    sudo apt update && sudo apt upgrade -y
  2. 2Install the database server

    Debian does not ship Oracle MySQL; its database server is MariaDB. Ubuntu offers both. phpMyAdmin works the same with either. Pick one block.

    Ubuntu: MySQL
    sudo apt install -y mysql-server
    sudo mysql_secure_installation
    Debian or Ubuntu: MariaDB
    sudo apt install -y mariadb-server
    sudo mariadb-secure-installation

    Say yes to removing anonymous users, disallowing remote root login and dropping the test database. On Ubuntu’s MySQL, root logs in through the OS account (auth_socket) rather than a password, so the script may skip the root password step. That is fine; leave it that way. If MySQL’s script offers the VALIDATE PASSWORD component and you accept it, note the policy level you pick; it matters in step 3.

  3. 3Install phpMyAdmin and answer the two questions
    Ubuntu 24.04 · 26.04 · Debian
    sudo apt install phpmyadmin
    Ubuntu 22.04
    sudo apt install phpmyadmin libapache2-mod-php

    If no web server is installed yet, apt pulls in Apache and its PHP module, because the package recommends libapache2-mod-php before any other web server. Ubuntu 22.04’s older package recommends apache2 alone, so there apt installs Apache without PHP and the page arrives as PHP code; naming the module avoids that. The installer then asks:

    • Web server to reconfigure automatically: the choices are apache2 and lighttpd. Press Space on apache2 so an asterisk appears, then Enter. Enter alone selects nothing, and nothing is configured.
    • Configure database for phpmyadmin with dbconfig-common? Yes. The next prompt, MySQL application password for phpmyadmin, may be left blank for a random password, unless you turned on MySQL’s password validation at MEDIUM or STRONG in step 2. The random password has no symbol and is refused there, so type one with upper and lower case, a digit and a symbol. This internal account stores phpMyAdmin’s own settings; you never log in with it.
  4. 4Open it

    Open http://YOUR_SERVER_IP/phpmyadmin. You should see the login page. Do not log in over plain HTTP from a public network, and do not leave it like this. The lock-down section is part of the install, not an optional extra.

Check that it works

From a shell on the server:

Ubuntu · Debian
curl -s http://127.0.0.1/phpmyadmin/ | grep -o '<title>[^<]*'

A title that contains phpMyAdmin means the web server found the files and PHP ran them. A title such as 404 Not Found or 403 Forbidden names the error, and no output at all usually means PHP code came back as text; the table above says which section to read. Then log in once with the user from the next section. A database list on the left means the connection to MySQL or MariaDB works too.

Create a user to log in with

Logging in as root fails with #1698 - Access denied for user 'root'@'localhost', often with mysqli::real_connect(): (HY000/1698): Access denied for user 'root'@'localhost' above it. That is the socket authentication from step 2 working as intended: root may log in only as the operating system’s root user, and a web page never is. Do not weaken root. Create a separate admin account instead:

Ubuntu · Debian
sudo mysql        # or: sudo mariadb
MySQL · MariaDB shell
CREATE USER 'dbadmin'@'localhost' IDENTIFIED BY 'A-LONG-RANDOM-PASSWORD';
GRANT ALL PRIVILEGES ON *.* TO 'dbadmin'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;

Log in to phpMyAdmin as dbadmin. For everyday work on a single application, a user limited to that application’s database is safer still. Resist switching root to mysql_native_password, as older guides suggest: MySQL 8.4, which Ubuntu 26.04 ships, disables that plugin by default. The background is in MySQL Access denied for root@localhost. A user created without a password is refused too, with Login without a password is forbidden by configuration (see AllowNoPassword). Give it a password rather than changing that setting. To see which accounts and databases already exist, use list MySQL users and databases.

Lock it down

Bots request /phpmyadmin on every IP address they find, and they try passwords there. Pick at least one of the following. The first is the strongest.

All Apache changes go into the <Directory /usr/share/phpmyadmin> block of /etc/phpmyadmin/apache.conf. The installer links /etc/apache2/conf-available/phpmyadmin.conf to that file, so editing either edits both. The block ships without a Require line of its own, so Apache’s rule for /usr/share applies, and that lets everyone in. Each option below adds one.

Option A: reachable only through SSH

/etc/phpmyadmin/apache.conf (inside the Directory block)
Require local
your computer · any OS
ssh -N -L 8080:127.0.0.1:80 USER@YOUR_SERVER_IP

Then open http://localhost:8080/phpmyadmin/ in your browser. phpMyAdmin now answers only requests that come from the server itself, and the SSH tunnel makes your browser one of them. Nothing is exposed, and no certificate is needed.

Option B: only from your IP address

inside the Directory block
Require ip YOUR_IP

The my IP tool shows the address the server will see. This works for a fixed address; a home connection whose address changes locks you out until you update the line.

Option C: a second password, over HTTPS

Ubuntu · Debian · Apache
sudo htpasswd -c /etc/apache2/.htpasswd YOUR_NAME
inside the Directory block
AuthType Basic
AuthName "Restricted"
AuthUserFile /etc/apache2/.htpasswd
Require valid-user

Basic auth sends the password with every request, so only use it over HTTPS. Point a (sub)domain at the server (see pointing a domain at your VPS) and get a free certificate:

Ubuntu · Debian · Apache
sudo apt install -y certbot python3-certbot-apache
sudo certbot --apache -d db.example.com

Also worth it: a different URL

Change Alias /phpmyadmin /usr/share/phpmyadmin at the top of the same file to something like Alias /db-7f3k /usr/share/phpmyadmin. That is not security on its own, but it removes you from the scripted scans. Apply any of these changes with:

Ubuntu · Debian · Apache
sudo apache2ctl configtest && sudo systemctl reload apache2

To confirm the lock works, request the page from somewhere other than the server, for example with the HTTP header checker. With option A or B it must answer 403 Forbidden, with option C 401 Unauthorized. From your own address, or through the tunnel, the login page must still open.

Install with nginx instead

Install the database server as in step 2, then nginx and PHP-FPM, before phpMyAdmin. With nginx already present, installing phpMyAdmin does not pull in Apache on any of the five releases.

Ubuntu · Debian
sudo apt install -y nginx php-fpm
sudo apt install phpmyadmin

When the installer asks which web server to configure, tick neither and press Enter. Answer Yes to dbconfig-common as before. Then confirm that dpkg -l apache2 reports no installed package. If Apache did get in, remove it, because it competes with nginx for port 80. nginx needs one of two setups.

At /phpmyadmin/ on an existing site

This is what most people want: http://YOUR_SERVER_IP/phpmyadmin/, next to whatever the server already serves. Put the locations in a snippet of their own:

/etc/nginx/snippets/phpmyadmin.conf
location = /phpmyadmin {
    absolute_redirect off;
    return 301 /phpmyadmin/;
}

location ^~ /phpmyadmin/ {
    root /usr/share;
    index index.php;
    try_files $uri $uri/ =404;

    # the server itself (for the SSH tunnel) and your address
    allow 127.0.0.1;
    allow YOUR_IP;
    deny all;

    location ~ ^/phpmyadmin/(libraries|templates|sql)/ {
        deny all;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php-fpm.sock;
    }
}

Then add the line include snippets/phpmyadmin.conf; inside the server block that answers for the server, on a fresh install the one in /etc/nginx/sites-available/default. The ^~ keeps a \.php$ location elsewhere in that server block from taking phpMyAdmin’s requests, and root /usr/share maps /phpmyadmin/ to /usr/share/phpmyadmin/ without a symlink. absolute_redirect off keeps the redirect relative, so it does not drop the port when you come through the SSH tunnel on 8080. The libraries and templates rule is the one the Debian package sets for Apache.

On a subdomain of its own

/etc/nginx/sites-available/phpmyadmin
server {
    listen 80;
    server_name db.example.com;

    root /usr/share/phpmyadmin;
    index index.php;

    allow 127.0.0.1;
    allow YOUR_IP;
    deny all;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ ^/(libraries|templates|sql)/ {
        deny all;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php-fpm.sock;
    }
}
Ubuntu · Debian · nginx
sudo ln -s /etc/nginx/sites-available/phpmyadmin /etc/nginx/sites-enabled/

For either setup, test and reload, then get a certificate for the subdomain:

Ubuntu · Debian · nginx
sudo nginx -t && sudo systemctl reload nginx
Ubuntu · Debian · nginx
sudo apt install -y python3-certbot-nginx
sudo certbot --nginx -d db.example.com

For a second password on nginx, htpasswd comes from the small apache2-utils package, which does not install Apache:

Ubuntu · Debian · nginx
sudo apt install -y apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd YOUR_NAME

Then add auth_basic "Restricted"; and auth_basic_user_file /etc/nginx/.htpasswd; next to the allow lines, and test and reload as above.

Troubleshooting

404 Not Found at /phpmyadmin (Apache)

Apache’s page reads Not Found and The requested URL was not found on this server. The installer creates the link in conf-available and enables it only for the web servers you ticked. That is also why the often-quoted sudo a2enconf phpmyadmin fails on such a system with ERROR: Conf phpmyadmin does not exist!. Run the dialog again and tick apache2 with Space this time:

Ubuntu · Debian
sudo dpkg-reconfigure phpmyadmin

dbconfig-common asks its questions first. Answer No to Reinstall database for phpmyadmin? to keep the existing one. Or create the link by hand:

Ubuntu · Debian
sudo ln -s /etc/phpmyadmin/apache.conf /etc/apache2/conf-available/phpmyadmin.conf
sudo a2enconf phpmyadmin
sudo systemctl reload apache2

403 Forbidden, or PHP code instead of the login page

With the snippet above, a 403 means the address you came from is not in an allow line; compare it with the my IP tool.

Without the snippet, the cause is usually a symlink. Many guides symlink /usr/share/phpmyadmin into /var/www/html. On a stock Debian or Ubuntu nginx, that fails twice: the default site lists only index.html index.htm index.nginx-debian.html as index files, so /phpmyadmin/ answers 403 Forbidden (the error log says directory index of "/var/www/html/phpmyadmin/" is forbidden), and its PHP location is commented out, so /phpmyadmin/index.php is sent to the browser as a file. Remove the symlink and use the snippet above, which sets its own index and PHP handling.

On Apache, PHP code in the browser means the PHP module is missing, which is what a plain sudo apt install phpmyadmin leaves behind on Ubuntu 22.04. Install it with sudo apt install libapache2-mod-php, then restart Apache.

502 Bad Gateway (nginx)

nginx reached no PHP-FPM. The error log (/var/log/nginx/error.log) names the socket it tried, as in connect() to unix:/run/php/php8.1-fpm.sock failed (2: No such file or directory) while connecting to upstream. The path came from a guide for another release, or PHP-FPM is not running. See which sockets exist:

Ubuntu · Debian
ls -l /run/php/

No .sock file at all means PHP-FPM is stopped. Start the service for your release’s PHP version from the table, for example on Ubuntu 24.04:

Ubuntu 24.04 (PHP 8.3)
sudo systemctl enable --now php8.3-fpm

The general case is in nginx 502 Bad Gateway. If PHP-FPM runs but every worker is busy, nginx answers 502 or 504; Apache answers 503 Service Unavailable.

#2002 and “No such file or directory” at login

mysqli::real_connect(): (HY000/2002): No such file or directory and #2002 - No such file or directory — The server is not responding (or the local server's socket is not correctly configured). mean phpMyAdmin found no database socket. The server is not installed, or not running. Check with systemctl status mysql or systemctl status mariadb, and install or start it as in step 2.

ERROR 1819 during install

ERROR 1819 (HY000): Your password does not satisfy the current policy requirements appears when MySQL’s VALIDATE PASSWORD component is on. At its MEDIUM level a password needs at least 8 characters with upper and lower case, a digit and a symbol. Leaving the password blank does not help: dbconfig-common’s random password is 12 letters and digits, with no symbol. Choose retry in the error dialog and type a password that meets the policy.

phpMyAdmin’s own error and warning messages

  • The mysqli extension is missing. Please check your PHP configuration. phpMyAdmin shows this on an error page instead of the login form. nginx points at a PHP version without the MySQL module, typical after adding a second PHP version. Install the module for the version in your fastcgi_pass line (for PHP 8.3, sudo apt install php8.3-mysql) and restart that PHP-FPM.
  • The configuration file needs a valid key for cookie encryption., shown at the bottom of the main page (Ubuntu 22.04’s phpMyAdmin 5.1 says The configuration file now needs a secret passphrase (blowfish_secret).): PHP cannot read /var/lib/phpmyadmin/blowfish_secret.inc.php, which the installer creates for group www-data. If the file is gone, sudo dpkg-reconfigure phpmyadmin writes a new one. If it exists, the PHP-FPM pool runs as a user outside that group.
  • The $cfg['TempDir'] (/var/lib/phpmyadmin/tmp/) is not accessible. The same user problem for the template cache. The installer gives the directory to www-data; give it to the pool’s user if that differs.

Imports fail on size

PHP’s defaults are upload_max_filesize = 2M and post_max_size = 8M. Raise both in the PHP ini your server uses (/etc/php/8.x/apache2/php.ini or /etc/php/8.x/fpm/php.ini), then restart Apache or PHP-FPM. nginx refuses bodies over 1 MB by default and answers 413 Request Entity Too Large before PHP sees the file; add client_max_body_size 64M; to the phpMyAdmin location. Behind Cloudflare, an upload over the plan’s request size limit gets a 413 from Cloudflare instead (more in 413 Request Entity Too Large). For really large dumps, import on the shell with sudo mysql DBNAME < dump.sql instead.

Rather not maintain a database panel at all? VMHeaven’s Plesk hosting plans include phpMyAdmin, kept up to date for you. On your own VPS, the steps above get you the same thing in about ten minutes.

Frequently asked

Is phpMyAdmin available on Debian 13 (trixie)?

Yes. Debian 13 ships phpMyAdmin 5.2.2 in its main component, so 'sudo apt install phpmyadmin' works without extra repositories. It runs on Debian 13's PHP 8.4; with nginx, point fastcgi_pass at /run/php/php8.4-fpm.sock or the version-independent /run/php/php-fpm.sock.

Why is phpMyAdmin not working after installation?

Most often apache2 was not ticked with Space in the installer, so /phpmyadmin answers 404: run 'sudo dpkg-reconfigure phpmyadmin' and tick it. On Ubuntu 22.04, PHP code instead of the login page means Apache's PHP module is missing: 'sudo apt install libapache2-mod-php'. On nginx you need your own location block; a 502 there means fastcgi_pass names a PHP-FPM socket that does not exist.

How do I secure phpMyAdmin?

Best: allow only local requests ('Require local' in /etc/phpmyadmin/apache.conf, or 'allow 127.0.0.1; deny all;' on nginx) and reach it through an SSH tunnel. Otherwise limit it to your IP or add HTTP basic auth over HTTPS, and log in with your own database user, never root.

Related articles

All guides