I am trying to run a copy of a website locally but for some reason none of the images work. They are stored on an S3 bucket.
In my config/filesystems.php the default is s3:
'default' => 's3',
My keys are the same as on the live site:
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID', 'key'),
'secret' => env('AWS_SECRET_ACCESS_KEY', 'key'),
'region' => 'eu-central-1',
'bucket' => 'storage.website.nl',
'cloud' => 'cloud.website.nl'
],
],
The only difference is my storage/app does not have a public folder with all the media in it like on the live site. But this should be created I think with something similar like php artisan storage:link except this command does not work in laravel 5.2.
What can I do to fix that?
I am facing image path problem in my Laravel Voyager admin panel.
User image is shown correctly. Here is an image with image path
But other images is not shown correctly. Here is an image with image path
If I change the image path from inspect element then that image is shown correctly.
So my question is where to change the image path for showing correct image in Voyager admin panel ?
Image upload in /storage folder. Here is the config/filesystem.php
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path(''),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
],
],
Anybody help please ? Thanks in advance
You have to update the APP_URL in .env File
APP_URL = "http://gotravelsglobal.com/travel/public"
I am attempting to get the dimensions of an image file that IS successfully uploading to my public/images folder which IS correctly symlinked via Laravel to the storage/public folder. I am using PHP's getimageinfo function.
To store the file, I have used the built in ->store('pathtodirectory', 'public') to save the file to the server, which is working. It correctly returns the path/filename associated with the image, and properly saves the file which I can confirm and view.
However! When I attempt to use the getimageinfo function it tells me 'failed to open stream:No such file or directory'. I have attempted to use the Storage::url, and the storage_path functions to grab a path to the file and pass that into getimageinfo. I have attempted to use the Laravel asset function as well. Nothing is working.
What am I missing?
Code:
$photo = $request->file('image');
$imageFilePath = $photo->store('images', 'public');
$imageDimensions = getImageSize(Storage::url($imageFilePath));<--Fails here
My config/filesystems.php:
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL').'/storage',
'visibility' => 'public',
],
's3' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET'),
'url' => env('AWS_URL'),
],
],
Ok. Gripes first... Laravel's documentation is garbage when you need anything other than the introduction (i.e. actually creating an application). This should not have taken me two days to track down this answer. Which is:
getImageSize(Storage::disk('public')->path($imageFilePath));
I wish Laravel would expose in its documentation the callable methods available for a resource.
My Laravel application needs to manipulate files present in multiple buckets simultaneously into a single session. So, I couldn't find a way to change several times the current bucket, since my .env file is like this:
S3_KEY='MY-KEY'
S3_SECRET='MySeCret'
S3_REGION='us-east-1'
S3_BUCKET='my-first-used-bucket'
I found somewhere that I could do this:
Config::set('filesystems.disks.s3.bucket', 'another-bucket');
but It works only once. What I need is something like:
Storage::disk('s3')->put('/bucket-name/path/filename.jpg', $file, 'public');
Where /bucket-name/ could be any bucket that I already create. What can I do? Thanks a lot!
You are correct in that Config::set(); only works once per request. My estimation is that this is done intentionally to stop the kind of thing you are attempting to do in your code example.
In config/filesystems.php you can list any number of "disks". These are locations of your file repositories. It looks like so:
'disks' => [
'local' => [
'driver' => 'local',
'root' => storage_path('app'),
],
'ftp' => [
'driver' => 'ftp',
'host' => 'ftp.example.com',
'username' => 'your-username',
'password' => 'your-password',
// Optional FTP Settings...
// 'port' => 21,
// 'root' => '',
// 'passive' => true,
// 'ssl' => true,
// 'timeout' => 30,
],
's3' => [
'driver' => 's3',
'key' => env('S3_KEY',''),
'secret' => env('S3_SECRET',''),
'region' => env('S3_REGION',''),
'bucket' => env('S3_BUCKET',''),
],
]
The Solution
The solution is to create a new disk of the extra buckets you want to use. Treat your buckets like different disks.
Note: The user that the S3_Key belongs to needs to have permissions to perform your required actions on the S3 buckets you are setting up as additional 'disks'.
'disks' => [
//All your other 'disks'
...
//My default bucket details.
's3' => [
'driver' => 's3',
'key' => env('S3_KEY',''),
'secret' => env('S3_SECRET',''),
'region' => env('S3_REGION',''),
'bucket' => env('S3_BUCKET',''),
],
's3MyOtherBucketName' => [
'driver' => 's3',
'key' => env('S3_KEY',''),
'secret' => env('S3_SECRET',''),
'region' => env('S3_REGION',''),
'bucket' => 'myOtherBucketName',
],
's3YetAnotherBucketName' => [
'driver' => 's3',
'key' => env('S3_KEY',''),
'secret' => env('S3_SECRET',''),
'region' => env('S3_REGION',''),
'bucket' => 'yetAnotherBucketName',
],
]
Then whenever you want to access the bucket of your choice call it like so:
Storage::disk('s3')->put($fileName, $data);
Storage::disk('s3MyOtherBucketName')->put($anotherFileName, $moreData);
Storage::disk('s3YetAnotherBucketName')->put($yetAnotherFileName, $evenMoreData);
If you have dynamic buckets you also can create a new instance like this:
$storage = Storage::createS3Driver([
'driver' => 's3',
'key' => 'your-key',
'secret' => 'your-secret',
'region' => 'us-east-1',
'bucket' => $bucketName,
]);
$storage->put('path/to/file.png', $content);
You can add the buckets to the filesystems config like so:
'disks' => [
's3' => [
'bucket1' => [
'driver' => 's3',
'key' => env('AWS_BUCKET1_ACCESS_KEY_ID'),
'secret' => env('AWS_BUCKET1_SECRET_ACCESS_KEY'),
'region' => env('AWS_BUCKET1_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET1_BUCKET'),
'url' => env('AWS_BUCKET1_URL'),
],
'bucket2' => [
'driver' => 's3',
'key' => env('AWS_BUCKET2_ACCESS_KEY_ID'),
'secret' => env('AWS_BUCKET2_SECRET_ACCESS_KEY'),
'region' => env('AWS_BUCKET2_DEFAULT_REGION'),
'bucket' => env('AWS_BUCKET2_BUCKET'),
'url' => env('AWS_BUCKET2_URL'),
],
],
],
Then you can access the server using the following:
\Storage::disk('s3.bucket1')->put('path/to/file.png', $content);
I have created a class for myself and named it StorageProxy. You can find it here.
Let's say you want to work with multiple drivers, one of which is an S3-Compatible Object Storage but you may need to change the storage driver on-the-fly, local for example. No problem, the StorageProxy deals with it! (similar to mc - MinIO Client)
Usage:
StorageProxy::touch(?string $disk, ?string $bucket)->{everyStorageMethod}();
If no disk is specified, it uses the default disk (it's defined in filesystem.php).
Example:
For the local driver our file exists in images/sample.jpg
For s3 driver our file exists in images bucket with the name of sample.jpg
Our filesystem.php file should look like this:
'localhost' => [
'driver' => 'local',
'root' => storage_path('/'),
],
'DO' => [
'driver' => 's3',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
// No need to specify the `bucket` property here
],
Since it's a proxy class, all Storage methods are available in StorageProxy too. Also, you don't need to remove the bucket name from the file path for s3 disks.
// For local disk
$disk = 'localhost';
StorageProxy::touch($disk)->exists("images/sample.jpg"); // true
// For S3 disk
$disk = 'DO';
StorageProxy::touch($disk)->exists("images/sample.jpg"); // true
StorageProxy::touch($disk, "images")->exists("images/sample.jpg"); // true
StorageProxy::touch($disk, "images")->bucketDetection(false)->exists("images/sample.jpg"); // false - the file path is considered as images/images/sample.jpg
StorageProxy::touch($disk, "images")->exists("sample.jpg"); // true
I want to configure the storage path in a Laravel 5.1 using the .env file. My bootstrap/app.php looks like this:
<?php
$app = new \Illuminate\Foundation\Application(
realpath(__DIR__.'/../')
);
$app->useStoragePath(getenv('STORAGE_PATH'));
and the relevant line in .env file is:
STORAGE_PATH=/var/www/storage
This doesn't work. I figured out the Dotenv library is initialised after the bootstrap is processed so the .env variables are not available in bootstrap.php.
Is there a different place where I can set the storage path and the .env variables are available?
In config/filesystems.php you can set your storage path. Try setting your storage path there and see if it works. Note that the example below is my suggestion as to how your config/filesystems.php should look. Don't mind the s3 setup. That's a part of my project.
Remember to remove $app->useStoragePath(getenv('STORAGE_PATH')); from app.php
return [
'default' => 's3',
'cloud' => 's3',
'disks' => [
'local' => [
'driver' => 'local',
'root' => env('STORAGE_PATH'),
],
's3' => [
'driver' => 's3',
'key' => env('AWS_KEY'),
'secret' => env('AWS_SECRET'),
'region' => env('AWS_REGION'),
'bucket' => env('AWS_BUCKET'),
],
'rackspace' => [
'driver' => 'rackspace',
'username' => 'your-username',
'key' => 'your-key',
'container' => 'your-container',
'endpoint' => 'https://identity.api.rackspacecloud.com/v2.0/',
'region' => 'IAD',
],
],
];