I'm trying to delete some files located in storage/framework/cache/data using php artisan cache:clear. This is silently failing, because the user trying to perform the action does not have write access to these files.
The files are located on a linux server running Nginx - the folders have the following permissions/owner/group:
drwxr-xr-x www-data www-data
and the files have:
-rw-r--r-- www-data www-data
The user I am trying to delete the cached files with is called deploy, and is a member of the www-data group. I can't use sudo because this command happens during a deploy script.
I have found this pull request, https://github.com/laravel/framework/pull/31579, which seems to describe my exact problem, and I have also looked at https://laravel.com/docs/7.x/filesystem#the-local-driver (under the permissions section). Based on this, I tried adding the following to filesystems.php:
'permissions' => [
'file' => [
'public' => 0775,
'private' => 0775,
],
'dir' => [
'public' => 0775,
'private' => 0775,
],
]
under both the public and local disk sections, to see if Laravel created the cache files with these permissions, rather than the ones shown above, however it didn't seem to affect anything. I'm guessing this only applies to files stored or created with the File facade, and not automatically generated cache files?
How can I set the permissions that Laravel creates these files with?
Thanks in advance for any help
Related
I am still not very clear in which folder to save the files uploaded by the user such as avatars, or the images of a post etc.
I've already read the guide https://laravel.com/docs/8.x/filesystem but couldn't figure out the best solution.
I can safely upload files to:
storage / app / folder
Or in
storage / app / public / folder
For example, I use the following code to load avatars and it is saved in storage/app/avatars:
$path = $request->file('avatar')->store('avatars');
If they need to be publicly accessible they need to end up in public some where. If you have setup the storage link then the public disk which is set as its root to storage/app/public will be accessible via yoursite.blah/storage as it is symlinked to the public/storage folder
normally in this route: storage/app/public/folder
Just remind you that if you create a folder, example: avatar and you want to save there all the avatars
you have to register that folder in the filesystems configuration file: config/filesystems.php
you have also more examples, in the filesystem documentation
I entered the second line for the avatars, in my controller I save the file like this:
$path = $request->file('avatar')->store('avatars');
But keep uploading it to storage/app/avatars
'links' => [
public_path('storage') => storage_path('app/public'),
public_path('avatars') => storage_path('app/public/avatars'),
],
I'm trying to backup a gallery folder stored in storage/app/public/gallery so I added
'include' => [
base_path('storage/app/public/gallery'),
],
to the backup config and run 'php artisan backup:run', it gives the error
Backup failed because There are no files to be backed up..
I tried a different approach and change it to
'include' => [
base_path('storage'),
],
The backup works but I get everything inside the storage folder except the public folder. It somehow excludes the public directory.
in my shared hosting (without SSH) my laravel installation save file from form only in storage/app/public/namefolder but not in storage/namefolder and this causes the files not to be displayed.
How can I solve it? Is there anything I need to change in the filesystem of the online site on shared hosting? or do I have to do anything else?
thanks a lot
this is where i store my file
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
i think your problem that you can not make the symlink command for storage as you do not has a SSH
php artisan storage:link
this command will create a symlink - a shortcut- to storage directory inside public directory,
there is several ways to apply this command with out accessing server via SSH
Route::get('artisan-command', function(){
Artisan::call('storage:link');
});
or you can call it with in a class
after you run the command every thing will work just fine , and no need to change config more than usual stuff.
I store files in storage.
No I tried to generate link that open file like:
http://[temp.com]/storage/tests/de139607636857fade861a3c2c472643.txt
But it does not work.
How to open file from storage by URL address?
Files in the storage are not accessible by url by default
You could use Public Disk. For that you need to create symbolic link from public/storage to storage/app/public
From Larvel 5.3 and up, you have artisan command that will help you to create symlink
php artisan storage:link
If you are using older version of Laravel, you can find an answer how to create symbolic link here
Another approach would be to create new disk "uploads", by editing the file config/filesystems.php
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path(),
],
'uploads' => [
'driver' => 'local',
'root' => public_path() . '/uploads',
],
]
To store files in this location
Storage::disk('uploads')->put($file_name, $file_content);
And to get the file
asset('uploads/'. $file_name)
The storage directory exists outside the web root, as some of the stuff in there shouldn't necessarily be publicly accessible.
https://laravel.com/docs/5.5/filesystem#the-public-disk
The public disk is intended for files that are going to be publicly accessible. By default, the public disk uses the local driver and stores these files in storage/app/public. To make them accessible from the web, you should create a symbolic link from public/storage to storage/app/public. This convention will keep your publicly accessible files in one directory that can be easily shared across deployments when using zero down-time deployment systems like Envoyer.
I strongly recommend not to modify the Laravel's directory structure.
What I would do is to create a URL to download the file, for example:
Route::get('download/{file}', 'DownloadsController#index');
And in that method's controller, put some logic to assert that the file exists and serve it with a response download, for example
public function index($file)
{
$filePath = storage_path('tests/'.$file);
if (! file_exists($filePath)) {
// Some response with error message...
}
return response()->download($filePath);
}
Then you can download your file with a link like this
http://[temp.com]/download/de139607636857fade861a3c2c472643.txt
The controller's way allows you to make some authentication checks before serving the file for example, or to count how many times the file was downloaded.
I know this question has been and answered before, but none of the answers apply in my situation. Essentially, I have a Laravel install. I try to run
php artisan migrate
I get the following error:
Access denied for user 'homestead'#'localhost'
Now here's the deal. I am not using homestead. It's a standard LAMP install and I have changed the database settings in config/database.php and in the .env file to reflect the correct username and password for my database. I can find no logical reason for artisan to still be attempting to use the homestead user. My APP_ENV is set to local and there is no production folder in either the app or config folders. I'm at a loss as to where it is pulling the homestead user.
ETA:
I have restarted apache, and run both
php artisan config:clear
and
php artisan cache:clear
It's still pulling the homestead user from something, but I simply cannot figure out where.
This is a good task to practice debugging skills! :)
So, it's obvious that Laravel gets 'homestead' username from somewhere – which could be a config file, a default value in the code (in reality this is unlikely but we are debugging), etc.
So my first step would be to execute this while in the base folder of your Laravel app:
find . -type f -size -30k -exec grep -H "homestead" \{\} \;
Which would look for files smaller than 30 kilobytes containing 'homestead' anywhere inside, and in case if found – show filename and the line containing this pattern. We can safely assume that 'homestead' is not stored anywhere in the database because it's used to access the database, so it's necessary beforehand.
Once you find the place, fixing the bug may be as easy as editing the file!
If find returns no results, there are still possibilities:
If your Linux user is 'homestead' and you try to connect to MySQL with no username specified, 'homestead' will be used automatically. Which would mean that Laravel for some reason cannot access your configuration files (permissions? wrong path?)
Check storage/logs/laravel.log and see the last error in more details. Go through the code file by file (list of files is given in the error, start from the top) and see how it fetches MySQL username.
I truly have no idea what happened with that particular build, but I am closing this question just to be done with it. I trashed the build and started over without any problem whatsoever. What happened there will forever remain a mystery.
You can have multiple database.php config files. The config file that is loaded is dependent upon the context in which the application is executed.
For example, I have three different database.php config files in my project:
app/config/database.php
app/config/local/database.php
app/config/testing/database.php
In my "testing" config file, I have two different connections defined:
return [
'default' => 'sqlite',
'connections' => array(
'mysql' => array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'test',
'username' => 'user',
'password' => 'secret',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
),
'sqlite' => array(
'driver' => 'sqlite',
'database' => ':memory:',
'prefix' => ''
),
)
];
Notice that the default key references sqlite, so it does not matter what credentials I enter into the mysql definition. (Unless I override the default value at runtime using Config::set('database.default', 'mysql'))
Search your config/ directory for the string 'homestead'. You'll find the config file that your application is loading. Change the default parameter to match the connection that you want to use.