Access denied for user 'bob'@'localhost' (using password: YES)
error whenever I attempted to access a route that required a db connection. The problem arises from using cPanel on Bluehost with shared hosting. The way that cPanel handles this is to prefix your database name and your user names with characters 2-9 of your domain name plus an underscore character. So, for example, my neighborhood
database was actually called obertrod_neighborhood
, and the user name bob
was actually obertrod_bob
. When I altered the DB_DATABASE
and DB_USERNAME
values in the .env
file to reflect this, I got access to the database.]
I have been over a number of posts where someone was attempting to deploy a Laravel site to bluehost. While it seems like plenty of people have had difficulty deploying Laravel to Bluehost, I haven’t found any posts that appear to address my specific situation.
- I have a fully working site that I developed on my own machine. I use
php artisan serve
to fire uplocalhost:8000
. On my browser, navigating tolocalhost:8000
fires up the landing page, which is exposed as a/
route. All the other routes (e.g./users
) run as expected. - The site’s routes access a MySQL datbase. I didn’t use migrations. I created the database directly on my machine with MySQL Workbench.
- Bluehost subdomain is
neighborhood.robertrodes.com
. - An
index.html
file that prints "test" to the screen runs correctly on the subdomain, so the subdomain itself is in working order. - I created the MySQL database on the Bluehost subdomain by dumping my local database to a .sql file, uploading it, and using phpMyAdmin to run the file. The database appears to be in working order; the schema is correct and I’m able to use phpMyAdmin to perform all CRUD operations without issue.
- I first tried installing the Laravel framework using Bluehost’s softacular service, and uploading all the model, views, controllers, routes and css files to the appropriate folders. I was able to get the landing page to display (the
/
route), but all the other routes give a 404 error after the site reroutes topublic
. - I tried not using the Bluehost installation, and just copying all of my files from the
localhost
version to the blank subdomain. This one sometimes comes up403 forbidden
, and sometimes reroutes toneighborhood/robertrodes.com/public/public
(go figure) and responds with a404
error. [Edit: This was a problem with caching. Now the site shows a test value correctly, and the main landing page navigating to thepublic
folder from the URL.] - The current state of the subdomain is that the local version of the site resides in the root folder of the subdomain.
Looks like I’m in over my head, and Bluehost doesn’t support Laravel. I haven’t been able to find anything relevant in the Laravel doc, either. Can someone give me a hand troubleshooting this?
In particular, I suspect that I have some files that are pointing things to wrong places. If I could get clear on where the files are that handle configurations and where to find things I can probably fix it from there.
For example, I can’t find a file where requests to neighborhood.robertrodes.com
get redirected to neighborhood.robertrodes.com/public/public
(that’s what happens). [Edit: not any more. This was a caching problem, resolved by clearing the cache.] There isn’t a .php file in the root folder. In the public
folder, index.php
doesn’t have the word public
in it.
2
Answers
In the end, this boiled down to two problems:
All of my routes are designed to reroute URL requests from
/[route]
to/public/[route]
. This works fine on my dev site, usingphp artisan serve
andlocalhost:8000/[route]
. But was not happening when deploying to my bluehost domain; any attempts to access a route resulted in a 404 error.Attempts to access data from the associated MySQL database resulted in the error
Access denied for user 'root'@'localhost' (using password: YES)
.Resolutions are as follows:
Created an
.htaccess
file (a file with Apache commands that gets run on access) in subdomain's root directory. The file contains the following code:The
RewriteRule
has the syntaxRewriteRule WhatToRewrite WhatToWriteItTo
. This one uses regular expressions and supports$1
to refer to capture groups. So,^(.*)$
captures the entire URL string (after the domain), and then plugs it into$1
in the second expression, thereby prefixing apublic/
to each URL. (E.g.https://neighborhood.robertrodes.com/users
gets rewritten ashttps://neighborhood.robertrodes.com/public/users
.On Bluehost shared hosting, database names and database user names are preceded with the cPanel user name, which is characters 2-9 of the domain name. So, my cPanel name is
obertrod
. Therefore, database nameneighborhood
becomesobertrod_neighborhood
, and user nameroot
becomesobertrod_root
. I added the superuserbob
(could have stuck with root, but), and then changed two values in the root's.env
file as follows:Things I tried for problem 1 before finding the
.htaccess
solution:Writing an
index.php
file in the root with this code:This rerouted any GET requests to the
public
folder, butPOST
requests wouldn't work until I changed theaction
attribute in my<form>
tags to includepublic
. It also changed the URL displaying in the browser to include thepublic
directory.Attempting to add a symlink. This got a bit interesting, because shared hosting on Bluehost doesn't allow use of a terminal. (Attempting to open a terminal provides the helpful
Error: The WebSocket handshake failed at XX:XX:XX XM.
Pushing theReconnect
button repeats the error. So you contact support, wait until they get to you, and have them tell you you can't use Terminal because you have a shared connection. Not my favorite Bluehost feature.)I tried putting the command
ln -s public_html/neighborhood/public_html/neighborhood/public
in a Cron job. No effect as far as I could see. I tried reversing target and link, also with no effect. I tried creating and running asymlink.php
file with thesymlink
command and various target and link arguments, all to no avail.I suspect that figuring out the right parameters for the symlink might work, but I'm actually glad I couldn't get it working, because
.htaccess
rewrite rules are clearly the right way to reroute these requests.I have one website deployed to Bluehost, simply copy your files to the server and create a symlink to the /public folder.
So, to do that:
ln -s your_laravel_folder/public public_html
Don’t forget to set the correct domain name in your .env file, create an app key, composer install and all the usual Laravel deployment commands.
Since you are deploying to a subdomain, your public_html may be different. Adjust the folder paths to whatever Bluehost created as a landing folder for that domain.