We may earn a referral fee at no additional cost to you when you shop through the links on this page.
You installed phpMyAdmin on an nginx server, browsed to /phpmyadmin, and got a 404. Nothing is broken: the package only configures Apache and lighttpd automatically, so nginx never learned the path. This DevAnswers guide fixes it with one tested location block, validated end to end on Ubuntu 22.04 through Debian 13.
The Nginx Location Block for phpMyAdmin
Open the server block file for your site. On a stock setup that is the default file; substitute your own if you use a per-domain config:
sudo nano /etc/nginx/sites-enabled/default
Paste the following inside the server { } block, just before its closing bracket. One line needs editing: the fastcgi_pass socket must match your PHP version, which the next section shows you how to check.
# Source: https://devanswers.net/nginx-phpmyadmin-configuration-template-for-nginx-conf/
location /phpmyadmin {
root /usr/share/;
index index.php;
# Official phpMyAdmin guidance: no web access to auxiliary folders
location ~ ^/phpmyadmin/(libraries|templates) {
deny all;
}
location ~ ^/phpmyadmin/(.+\.php)$ {
root /usr/share/;
# UPDATE the PHP version to match your server (next section)
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
include snippets/fastcgi-php.conf;
fastcgi_param HTTP_HOST $host;
}
}
Save and exit (press CTRL + X, press Y, then press ENTER)
/usr/share/phpmyadmin and the snippets/fastcgi-php.conf include exists. On RHEL-family systems (AlmaLinux, Rocky) the socket is under /run/php-fpm/, the server block lives in /etc/nginx/conf.d/, and there is no snippets/ include, so replace that line with include fastcgi_params; plus fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;. The deny rule is not decoration: phpMyAdmin’s own security guidance says to block web access to the auxiliary files under libraries/ and templates/, which protects against path exposure and cross-site scripting issues found in that code. Most templates floating around omit this.
Find Your PHP-FPM Socket
The fastcgi_pass line points nginx at PHP-FPM through a UNIX-domain socket. The socket path is whatever the listen directive in your PHP-FPM pool configuration says, and the file usually lives in /run/php/ with the PHP version in its name. List what is actually there:
ls /run/php/
Use the versioned .sock file you see (for example php8.3-fpm.sock) in the template’s fastcgi_pass line. If the directory is empty, PHP-FPM is not installed or not running, and you will want our nginx and PHP-FPM setup guide first.
Test and Reload Nginx
Validate the configuration before reloading; nginx prints the verdict to the terminal:
sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
sudo systemctl reload nginx
Now load http://devanswers.test/phpmyadmin in your browser (swap in your own domain or server IP). The phpMyAdmin login page should appear, styled and ready to sign in. (If signing in as root fails with Access denied for ‘root’@’localhost’, that’s an authentication-plugin issue, not your Nginx config.)
Why the Template Works
root /usr/share/;and not/usr/share/phpmyadmin. nginx’srootdirective appends the entire request URI to the path, so/phpmyadmin/index.phpbecomes/usr/share/phpmyadmin/index.php, exactly where the package puts the files. Setting root to the package directory itself would double the folder name. (The relatedaliasdirective does the opposite: it replaces the matched part of the URI instead of appending the whole thing, which is whyrootis the right fit here.)- The
denylocation. Straight from the official security guidance: auxiliary files underlibraries/andtemplates/should not be reachable over the web. Because it appears first, nginx matches it ahead of the PHP rule for anything inside those folders. - The nested PHP location. Only requests like
/phpmyadmin/….phpare sent to PHP-FPM, so the rest of your site’s PHP handling stays untouched. The includedfastcgi-php.confsnippet brings its owntry_files $uri =404, so do not add a second one in this block; nginx treats a duplicatetry_filesas a configuration error. fastcgi_param HTTP_HOST $host;comes from the phpMyAdmin FAQ for nginx setups, so the application sees the hostname the browser asked for.- Static assets need no extra block. CSS, icons and JavaScript fall through to the outer
location /phpmyadminand are served from the same root; the test run confirms the login page loads fully styled.
Secure the Installation
phpMyAdmin’s security guidance recommends requiring extra HTTP authentication at the web-server level for public installations, and serving the app over HTTPS, preferably with HSTS so you are protected from protocol downgrade attacks. On nginx that outer gate is auth_basic: add it inside location /phpmyadmin with an htpasswd file, exactly as covered in our guide to password-protecting a directory in nginx. Give the htpasswd user a strong, randomly generated password (the preset skips look-alike characters, since you type this one at a prompt).
Inside the app, cookie authentication mode is, per the same guidance, probably the best choice for shared hosting setups; it is also the Debian package default, so there is usually nothing to change.
Troubleshooting
Worked through everything and something still fails? The usual suspects:
- Still 404 at
/phpmyadmin. Check therootline: it must be/usr/share/with the trailing slash and WITHOUT the package folder, because root appends the whole URI. And remember why nothing worked out of the box: the package’s automatic web-server configuration covers Apache and lighttpd; nginx is not on that list. - 502 Bad Gateway. nginx reached the PHP location but could not connect to the FastCGI backend; in practice that is nearly always a
fastcgi_passsocket that does not exist. Re-runls /run/php/and fix the version. More depth in our nginx + PHP-FPM guide. - 403 errors while using phpMyAdmin. If the login works but actions inside the app return 403, that is typically a web application firewall false positive, covered in our phpMyAdmin 403 fix.
- The login page is unstyled. The outer location lost its
root(or you placed root only inside the PHP location), so static assets cannot resolve. Keeproot /usr/share/;at thelocation /phpmyadminlevel. - The installer asked about Apache and a database. Normal for the Debian package: it offers Apache/lighttpd configuration and sets up phpMyAdmin’s configuration storage through dbconfig-common. On an nginx server, select no web server; this article replaces that step.
Summary
One location block and the right PHP-FPM socket are all nginx needs to serve phpMyAdmin: root at /usr/share/, a scoped PHP handler, and the officially recommended deny rules for the auxiliary folders. Test with nginx -t, reload, and put auth_basic in front of it before you call it done.
Man, i’ve saved my entire day. Holy Jesus
Thanks….saved me hours of searching…the only modification I had to make was the socket…everything worked out of the box.
Hi, Thanks for your support, But I am facing the following error:
nginx: [emerg] “location” directive is not allowed here in /etc/nginx/conf.d/phpmyadmin.conf:1
nginx: configuration file /etc/nginx/nginx.conf test failed
Please guide after having look at the following phpmyadmin.conf file as per my system:
location /testvm {
root /var/www/html/phpmyadmin;
index index.php index.html index.htm;
location ~ ^/testvm/(.+\.php)$ {
try_files $uri =404;
root /var/www/html/;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
location ~* ^/testvm/(.+\.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt))$ {
root /var/www/html/;
}
}
In the above code: testvm is my hostname of the server
Direcotry path containing phpmyadmin: /var/www/html/phpmyadmin
Regards
You are the best!!!
after too much investigation just your code works for me
Thanks