Despite lack of compact guides in the internet, deploying Laravel 5.4 project in cheap shared hosting (with no SSH support) is actually quite simple. The steps are:
1. Import database to the shared hosting’s database using available tool such as phpMyAdmin
2. Upload the content of public directory in your Laravel project to public area of your shared hosting eg. ~/public_html
3. Upload your Laravel project (minus public directory) to another directory in shared hosting eg. ~/myproject
. You can further exclude another directories/files that aren’t needed for production (see tips below)
4. Adjust the configuration (database connection, email server, api key .etc) in ~/myproject/.env
5. Adjust ~/public_html/index.php
to match your Laravel project path:
require __DIR__.’/../bootstrap/autoload.php’; ... $app = require_once __DIR__.’/../bootstrap/app.php’;
into:
require __DIR__.’/../myproject/bootstrap/autoload.php’; ... $app = require_once __DIR__.’/../myproject/bootstrap/app.php’;
Well, at least that is in the nutshell
Here are some troubleshootings that I also needed to do during my first full Laravel 5.4 project deployment in shared hosting. I hope it may be useful:
Archiving directories and exporting SQL file for shared hosting
Since I need to deploy to production many times, I decided to create a simple shell script to speed up the process. It generates 3 files:
- MySQL dump
database.sql
- Project directory archive
app-shared.zip
- Public directory archive
public-shared.zip
#!/bin/bash dbname="myproject" dbuser="myuser" dbpass="mypass" #recreate database to reset auto-increment indexes mysqladmin -u"$dbuser" -p"$dbpass" --force=TRUE drop "$dbname" mysqladmin -u"$dbuser" -p"$dbpass" --force=TRUE create "$dbname" #migrate and seed db php artisan migrate:fresh --seed #export sql mysqldump -u"$dbuser" -p"$dbpass" "$dbname" -r database.sql #zip app and public directories zip -r app-shared.zip . -x .* -x *.zip -x *.xml -x *.sql -x *.sh -x .git/* -x public/* -x database/* -x tests/* -x webpack.mix.js -x package.json cd public zip -r ../public-shared.zip . -x index.php -x .htaccess -x *.json cd ..
Running queue/jobs processor in shared hosting
If you don’t have SSH support, you can run php artisan queue:work
using this simple cron job:
* * * * * /usr/bin/php -d register_argc_argv=On /home/user/laravel/artisan queue:work --once --timeout=30 --tries=2 >> /path/to/queue.log 2>&1
It will process an entry in the queue once every minute. IMO it’s the safest setup for a cheap shared hosting.
Creating symbolic link for storage in shared hosting
If you follow the shared hosting deployment steps above, most likely you won’t get any problem at the first time. But when you try to upload files through your web application, you will get 404 error for the new files. That is because symbolic link in ~/public directory
is replaced by copied directory from storage/app/public
. To fix this, you need to replace ~/public/storage
with symbolic link to ~/myproject/storage/app/public
using this cron job below (assuming you don’t have SSH support):
* * * * * ln -s /home/user/laravel/storage/app/public /home/user/public_html/storage
Fix import index length error on MariaDB (on common shared hosting)
If you dump your MySQL table using command such as mysqldump -u[user] -p[password] [dbname] -r [output file]
and import it to MariaDB on shared hosting, most likely you’ll hit:
[PDOException] SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes
To fix it, add one line (and use
statement) in \App\Providers\AppServiceProvider
:
use Illuminate\Support\Facades\Schema; class AppServiceProvider extends ServiceProvider { public function boot() { // fix issue with migration to MariaDB Schema::defaultStringLength(191); } ... }
Get path to disk storage’s template
This is not specific for shared hosting but I’ll just put it here anyway.
For instance, if our storage’s template is app
, calling storage_path
will return a path missing the app
. To overcome this, use this instead:
$filepath = Storage::disk('app')->getDriver()->getAdapter()->applyPathPrefix('category/file.ext');
or if it’s a default template:
$filepath = Storage::getDriver()->getAdapter()->applyPathPrefix('category/file.ext');
References
- https://idcloudhost.com/cara-upload-file-laravel-ke-cloud-shared-hosting/
- https://github.com/laravel/framework/issues/13610
- https://stackoverflow.com/questions/29594145/using-laravel-queue-fails-to-run-on-my-shared-hosting-solution
- https://laravel-news.com/laravel-5-4-key-too-long-error