Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Bervetuna's avatar

Deployment of Laravel 10 project on shared hosting - symlink problem

I know it's not the most ideal way to deploy a Laravel project, but this particular one is a small temporary project and I would like to deploy it via my reseller package.

Everything works perfect on development server and I deployed the way it did many times in the past:

  • In the root directory of the webserver, I made a folder with the name of the project.
  • I ftp'ed everything in that folder, except for the Laravel public folder
  • I copied the files from the public folder to the public_html folder
  • I did the necessary adjustments to the index.php file inside the public_html folder.
  • in the appServiceProvider I added the following to the boot method:
 public function boot(): void
    {
         $this->app->bind('path.public',function(){
    return base_path('public_html');
    });
    }

I created the database and imported a database dump from my local machine.

Everything works perfectly, apart from the symlink that doesn't seem to work. I supposed it should work out of the box, since it did on the local machine, but that is not the case.

I tried to establish the link with the following route:

Route::get('/linkstorage', function () { $targetFolder = base_path().'/storage/app/public'; $linkFolder = $_SERVER['DOCUMENT_ROOT'].'/storage'; symlink($targetFolder, $linkFolder); });

Images that are uploaded using a form in the application are getting stored in the storage/app/public folder, but are not displayed on the site.

Can anyone help me out here?

Thanks!

UPDATE: Addition: I do have ssh access to the server...

0 likes
23 replies
vincent15000's avatar

The symbolic links are not automatically followed by the server.

You have to specify the FollowSymlink option in the apache configuration (assuming you are using the apache server), for example in the .htaccess file.

Snapey's avatar

I would seriously consider a better hosting provider

You should NOT mess about moving stuff around because that will become a big hassle in the future when you want to deploy new code. All my projects are deployed in less than 10 seconds (once setup) and don’t use any third party tooling. Some use GitHub actions to trigger deployment but most, I ssh to the server and run one command.

I have a site with loads of tips for deploying on shared hosting and you might pick up some tips from there

https://laravelsharedhosting.novate.co.uk/

It’s a tutorial based on SiteGround hosting but techniques can be applied to any shared hosting that provides ssh access

3 likes
Bervetuna's avatar

@Snapey

Thanks, I'll give that a try.

From what I understand, you keep the Laravel document/file structure intact and make a symlink from public_html to the public folder of the Laravel project.

Is that correct?

1 like
Snapey's avatar

@Bervetuna yes, that is correct. The web server still thinks it is serving public_html but the contents of that folder are the public folder, therefore exactly the same as your local development.

1 like
Bervetuna's avatar

@tisuchi

Thansk!

But you seem to put the entire Laravel project in the public folder. Is that correct? (the public_html folder, I mean)

1 like
vincent15000's avatar

@tisuchi You are saying that putting the entire Laravel project in the public folder (public_html) is a good idea ? Are you sure ?

According to me, it's not a good idea because you will have some security problems, for example by exposing the .env file.

vincent15000's avatar

@tisuchi Ok that's true ... but I'm not sure that it's a good pratice to put all files in the public_html folder.

Bervetuna's avatar

I'm stil trying to get this work...

I did the test with another Laravel project that I uploaded to the server, moved the public folder to public_html, adjusted the path in index.php and made the link using the function

Route::get('/linkstorage', function () { $targetFolder = base_path().'/storage/app/public'; $linkFolder = $_SERVER['DOCUMENT_ROOT'].'/storage'; symlink($targetFolder, $linkFolder); });

Works perfectly, including the storing and display of images.

The project I used to test is a Laravel 8 project.

The project that gives the problem is a Laravel 10 project.

Could it be that the way to make this work changed in Laravel 10?

1 like
Bervetuna's avatar

@Snapey

Shure!

You mean the logfiles in the storage folder? How can I send them to you?

1 like
Bervetuna's avatar

I'm still trying to make this work.

Just for the sake of trying to find out what might be the problem, I've put the entire Laravel project in the public_html folder and added a .htaccess file to link public_html to the Laravel public folder. I did that on another domain I use for testing.

The result is the same: images are getting uploaded to the storage folder, but are not getting displayed on the site, although putting the whole Laravel project in the public_html folder is not changing the directory structure compared with my development environment.

I also ssh'ed to the domain, deleted the existing storage link en ran the php artisan storage:link command again.

When checking the content of the public folder the link is there:

drwxr-xr-x 3 burg21 burg21 105 20 jul 11:35 . drwxr-xr-x 15 burg21 burg21 4096 20 jul 11:21 .. drwxr-xr-x 3 burg21 burg21 41 17 jul 15:40 build -rw-r--r-- 1 burg21 burg21 0 7 jun 15:20 favicon.ico -rw-r--r-- 1 burg21 burg21 603 7 jun 15:20 .htaccess -rw-r--r-- 1 burg21 burg21 1710 7 jun 15:20 index.php -rw-r--r-- 1 burg21 burg21 24 7 jun 15:20 robots.txt lrwxrwxrwx 1 burg21 burg21 61 20 jul 11:35 storage -> /home/burg21/domains/mydomain/public_html/storage/app/public

Does anybody might have a clue what causes this problem?

Thanks a lot!

1 like
NoLAstNamE's avatar

Why not use DigitalOcean with Laravel Forge? Or if you want to learn it the hard way, don't use Laravel Forge.

1 like
Bervetuna's avatar

UPDATE (for in case anyone has the same issue): since my project was small (some forms and tables) and I need to have it online quick (and after two days of trying to make it work without success I didn't know what to do)...

...I rebuild it in Laravel 8.* and ftp'ed to the server, same procedure and everything works fine.

Must have something to do with the architecture of Laravel 10 (and maybe 9).

I hope to find out in the future...

1 like
Bervetuna's avatar

Problem solved!

Had to do with the permissions on the folders in the storage/app/public folder. They were not set to public.

2 likes

Please or to participate in this conversation.