Error retrieving credentials from the instance profile metadata server. Laravel S3 - php

Issue
The same code, on almost identical servers, fails locally and on production, however works on our staging server. When we attempt to interact with an item in a bucket, we get an Error retrieving credentials....
- Both servers, staging and production, are deployed by Envoyer and provisioned by Forge to AWS EC2 instances.
- Both instances hit the same bucket with the same bucket policy.
- .env settings are same for all, minus the server name and debugging
Error on production:
Aws\Exception\CredentialsException
Error retrieving credentials from the instance profile metadata server. (cURL error 28: Connection timed out after 1003 milliseconds (see http://curl.haxx.se/libcurl/c/libcurl-errors.html))
Server settings
Staging
Ubuntu 16.04.2 LTS on AWS
PHP 7.1.3-3
NPM 3.10.10
Node v6.10.1
Production
Ubuntu 16.04.1 LTS on AWS EC2
PHP 7.1.6-1
npm 3.10.10
Node v6.10.1
Composer.json packages
"laravel/framework": "5.4.*", // 5.4.25
"aws/aws-sdk-php-laravel": "~3.0", // 3.1.0
"guzzlehttp/guzzle": "~6.0", // 6.2.3
Code sample
function getPhoto($personID)
{
$contents = '';
$id = $personID;
$cloudFront = env('AWS_CLOUDFRONT_PHOTO'); // d212rosgvhtylp.cloudfront.net
$fileKey = filePath($id) . '_t.jpg'; // 9ae299a1990e79d62f07c28bb60ecf6f_t.jpg
$fileURL = $cloudFront . '/' . filePath($id) . '_t.jpg'; // d212rosgvhtylp.cloudfront.net/9ae299a1990e79d62f07c28bb60ecf6f_t.jpg
// check if in remote storage then get contents
$contents = Storage::disk('s3photo')->get($fileKey); /* ****** FAILS HERE ****** */
// stream bioPhoto
header('Content-Type: image/jpeg');
echo $contents;
}

After ensuring your .env files contain the correct values for the AWS client, run the following command:
php artisan config:clear
This should clear up your issue if it is caused by initially having incorrect or missing env data, not sure when the cache is updated on it's own but the config cache seems to be pretty persistent.

I encountered this issue after I accedentially had entered the AWS_ACCESS_KEY_ID in the .env file twice.
.env:
AWS_ACCESS_KEY_ID=MYREALID
AWS_SECRET_ACCESS_KEY=myrealkey
...
...a lot of variables..
...
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
The AWS sdk therefor tries to search for these credentials elsewhere, at that's have the error occures.

I recently had this problem. In my case, it worked locally and not on the EC2 instance. I did not understand too much. In the end I realized that I had set up IAM locally in the default folder ~/.aws/credentials, so in local everything was good. So I poked in the laravel sources and I noticed that laravel was going to take the connection configs in the file services.php config folder.
Edit config/services.php and put in the AWS IAM keys.
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
],
'ses' => [
'key' => env('AWS_KEY'),
'secret' => env('AWS_SECRET'),
'region' => env('AWS_REGION'),
],
'sparkpost' => [
'secret' => env('SPARKPOST_SECRET'),
],
'stripe' => [
'model' => App\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
So I saw that my .env file did not have the AWS IAM login keys, those called in the config /services.php file.
After a small adjustment everything works great.

This issue may occur if you are passing the wrong ENV variables, check your config/filesystems.php:
'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'),
See: https://github.com/laravel/laravel/blob/master/config/filesystems.php#L60
And make sure the keys are matching in your .env.
Pretty sure they changed the name in the last couple updates.

Related

Laravel WebSockets. Issue with App key. How it fix?

I can start websocket on
php artisan websockets:serve
But when i try to open my site page it says that
New connection opened for app key websocketkey.
Exception `BeyondCode\LaravelWebSockets\WebSockets\Exceptions\UnknownAppKey` thrown: `Could not find app key `websocketkey`.`
Unknown app id: exception `BeyondCode\LaravelWebSockets\WebSockets\Exceptions\UnknownAppKey` thrown: `Could not find app key `websocketkey`.`.
Connection id sending message {"event":"pusher:error","data":{"message":"Could not find app key `websocketkey`.","code":4001}}
Connection id closed.
Exception `ErrorException` thrown: `Undefined property: Ratchet\Server\IoConnection::$app`
In config/websockets.php i got app key from env
'apps' => [
[
'id' => env('PUSHER_APP_ID'),
'name' => env('APP_NAME'),
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'enable_client_messages' => true,
'enable_statistics' => true,
],
],
I don't understand where getting websocketkey from. Because there are no such values in env.
I try php artisan config:clear and it didn't help.
Please share who knows how to solve this and why it happens at all.
Restarting the websocket worked for me, while php artisan config:clear did not.

Laravel beyondcode websockets do not connect

I'm using this Laravel websockets package to have my own websocket server.
As mentioned in package documentation, I have this configuration:
.env setting:
PUSHER_APP_ID=761772
PUSHER_APP_KEY=qwerty
PUSHER_APP_SECRET=secret
PUSHER_APP_CLUSTER=ap2
broadcasting.php:
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => true,
//'host' => '105.208.174.8', <--I did test this too
'host' => '127.0.0.1',
'port' => 6001,
'scheme' => 'https'//<--Tested with http
],
],
websockets.php:
'apps' => [
[
'id' => env('PUSHER_APP_ID'),
'name' => env('APP_NAME'),
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'enable_client_messages' => false,
'enable_statistics' => true,
],
],
bootstrap.js:
/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that are broadcast by Laravel. Echo and event broadcasting
* allows your team to easily build robust real-time web applications.
*/
import Echo from 'laravel-echo'
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: 'qwerty',
wsHost: window.location.hostname,
wsPort: 6001,
disableStats: true,
encrypted: true,
enabledTransports: ['ws', 'wss'] //This was added from issue 86
});
This is issue number 86 in package repository
I'm using letsencrypt with my directadmin control panel and this is my SSL part of websockets.php configuration:
'ssl' => [
/*
* Path to local certificate file on filesystem. It must be a PEM encoded file which
* contains your certificate and private key. It can optionally contain the
* certificate chain of issuers. The private key also may be contained
* in a separate file specified by local_pk.
*/
//'local_cert' => null,
'local_cert' => '/home/myDomain/domains/myDomain/public_html/vendor/react/socket/examples/localhost.pem',
//'local_cert' => '/usr/local/directadmin/data/users/myDomain/domains/myDomain.ir.cert',
/*
* Path to local private key file on filesystem in case of separate files for
* certificate (local_cert) and private key.
*/
//'local_pk' => null,
'local_pk' => '/usr/local/directadmin/data/users/myDomain/domains/myDomain.ir.key',
/*
* Passphrase for your local_cert file.
*/
'passphrase' => null,
],
But when I use php artisan websockets:serve, It seems there's something wrong about connection and the myDomain.com/laravel-websockets admin panel says:
Channel's current state is unavailable
and the console says:
Firefox can’t establish a connection to the server at wss://myDomain.ir:6001/app/qwerty?protocol=7&client=js&version=4.3.1&flash=false.
pusher.min.js:8:6335
The connection to wss://myDomain.ir:6001/app/qwerty?protocol=7&client=js&version=4.3.1&flash=false was interrupted while the page was loading.
Does anyone know what's my issue and how should I solve this?
I had the same issue and the problem was the read access of the local_cert and local_pk.
You can use sudo php artisan websocket:serve to try if this is the issue.
If it's the case, add read access to the files or use a user with the access in /etc/supervisor/conf.d/websockets.conf
I had the same problem, I was using Homestead, are you on homestead, if so you should be using supervisor(Debian based) or supervisord (REDHat based) OS to run the laravel socket without manually entering the command "php artisan websockets:serve" at all times.
You can refer to this documentation. https://docs.beyondco.de/laravel-websockets/1.0/basic-usage/starting.html#restricting-the-listening-host
For SSL I also followed this documentation with Valet: https://docs.beyondco.de/laravel-websockets/1.0/basic-usage/ssl.html#usage-with-laravel-valet
I had the same issue first you have to make sure that port you are trying to run is open or not. if you are running socket server on shared hosting then its not possible or you can talk with customer support and they will open port for you. if you have vps or dedicated server you can open port from your control panel. first try to run without ssl if its running fine it means that your port is open then config your ssl config.
If you are using Laravel < 8.0, try composer require pusher/pusher-php-server ^4.1.
my be you have not run server
php artisan websockets:serve
http://127.0.0.1:8000/laravel-websockets
I was struggling with 500 Error till I figured it out
Error message: Attempt to read property "key" on null
authEndpoint: `http://localhost:3060/laravel-websockets/auth`,
auth: {
headers: {
'x-app-id': '**App ID**', // => my issue was HERE
Authorization: 'Bearer jwt TOKEN',
'Access-Control-Allow-Origin': '*'
}
}
and I found it by looking into the file in vendor\beyondcode\laravel-websockets\src\Dashboard\Http\Controllers\AuthenticateDashboard.php
$app = App::findById($request->header('x-app-id'));
$broadcaster = new PusherBroadcaster(new Pusher(
$app->key,
$app->secret,
$app->id,
[]
));
and changed the middlware in App\Providers\BroadcastServiceProvider.php
// from
// Broadcast::routes();
// to
Broadcast::routes(['middleware' => ['auth:api']]);
another change in App\config\websockets.php
'middleware' => [
'api', // => changed it from web to api
Authorize::class,
],
hope this help :)

Laravel Scout production error with TNTSearch driver

Searching using the TNTSearch driver works in a Homestead environment however on production it returns error: the below error,
Symfony\Component\Debug\Exception\FatalThrowableError: Class
'AlgoliaSearch\Version' not found on
vendor/laravel/scout/src/EngineManager.php:31
However my .env has SCOUT_DRIVER=tntsearch and the config file scout.php has:
'driver' => env('SCOUT_DRIVER', 'tntsearch'),
'tntsearch' => [
'storage' => storage_path(),
'fuzziness' => env('TNTSEARCH_FUZZINESS', false),
'fuzzy' => [
'prefix_length' => 2,
'max_expansions' => 50,
'distance' => 2
],
'asYouType' => false,
'searchBoolean' => env('TNTSEARCH_BOOLEAN', false),
]
The problem is that I am not using Algolia search and my composer file has Scout and TNTSearch driver. The search works in my local Homestead environment just not on the production server.
Confirm that SCOUT_DRIVER=tntsearch has been added to your .env file.
For me personally, I had added SCOUT_DRIVER=tntsearch to my local .env file, but not my .env file for the environment with the issue. Don't forget to run php artisan config:clear after adding the env var.
Thanks to #m33bo for pointing me in the right direction!
I worked it out, I had uploaded my project but for some reason the .index file that is needed sync'd but did not work. If this happens to you on live make sure you Git or SVN or whatever the index or run php artisan scout:import App\\Your\\Model

spatie/laravel-backup "mysqldump" doesn't recognized when I run it through Artisan class

I'm using spatie/laravel-backup in a WAMP localhost.
It works fine when I type manually in the windows cmd:
php artisan backup:run
But when I try to run the backup using the laravel Artisan class:
Artisan::call('backup:run');
It throw an error:
'mysqldump' not recognized ...
In the laravel mysql config I've also specified the path to the dumper:
'mysql' => [
'driver' => 'mysql',
// ...
'dump' => [
'dump_binary_path' => 'E:/wamp/wamp64/bin/mysql/mysql5.7.9/bin',
],
],
How can i fix that?
EDIT
Probably it's just support "bug" for windows (finded out thanks Loek's answer), as the author says, so can I run a backup in a controller without a command safely? maybe with something like:
use Spatie\Backup\Tasks\Backup\BackupJobFactory;
BackupJobFactory::createFromArray(config('laravel-backup'))->run();
As the command itself.
I believe it's the forward slashes. Try this:
'mysql' => [
'driver' => 'mysql',
// ...
'dump' => [
'dump_binary_path' => 'E:\\wamp\\wamp64\\bin\\mysql\\mysql5.7.9\\bin',
],
],
EDIT
Support for Windows is wonky at best, with multiple "This package doesn't support Windows" comments from the creators on GitHub issues. This one is the latest: https://github.com/spatie/laravel-backup/issues/311
It could also be a permission problem. Executing from the command line is probably happening from another user than executing from the web server, so Windows is denying access to mysqldump.
2nd edit
As long as you make sure the controller only gets called when it needs to be, I don't see why this wouldn't work!

Integrate amazon AWS with yii 2.0

How do I integrate my Yii 2.0 project with Aws ?
I have installed it using composer
"aws/aws-sdk-php": "2.*",
and included the
require '../vendor/aws/aws-autoloader.php';
But when I try to instantiate my S3 client, it keeps telling me that Aws does not exist.
You can refer the following link on github
https://github.com/JDpawar/yii2-aws-s3-sdk
It has the exact details how to use the S3 SDK along with the Yii 2 App.
AWS SDK for Yii2 - Use Amazon Web Services in your Yii2 project
This extension provides the AWS SDK 3 integration for the Yii2 framework
Installation
The preferred way to install this extension is through composer.
Either run
php composer.phar require --prefer-dist fedemotta/yii2-aws-sdk "*"
or add
"fedemotta/yii2-aws-sdk": "*"
to the require section of your composer.json file.
Note: You can still use AWS version 2 if you specify fedemotta/yii2-aws-sdk "1.*"
Usage
To use this extension, simply add the following code in your application configuration:
<?php
return [
//....
'components' => [
'awssdk' => [
'class' => 'fedemotta\awssdk\AwsSdk',
'credentials' => [ //you can use a different method to grant access
'key' => 'your-aws-key',
'secret' => 'your-aws-secret',
],
'region' => 'your-aws-region', //i.e.: 'us-east-1'
'version' => 'your-aws-version', //i.e.: 'latest'
],
],
];
?>
Getting all balancer names from AWS:
<?php
$aws = Yii::$app->awssdk->getAwsSdk();
$elb = $aws->createElasticloadbalancing();
$load_balancers = $elb->describeLoadBalancers()->toArray();
if (isset($load_balancers['LoadBalancerDescriptions'])){
foreach ($load_balancers['LoadBalancerDescriptions'] as $balancer){
if (isset($balancer['LoadBalancerName'])){
echo $balancer['LoadBalancerName'];
}
}
}
?>
Download an object from S3:
<?php
//specify the region if it is different than the main configuration region
Yii::$app->awssdk->region = 'sa-east-1';
$aws = Yii::$app->awssdk->getAwsSdk();
//use s3
$s3 = $aws->createS3();
$result = $s3->listObjects(['Bucket' => 'your-bucket-id',
"Prefix" => "your-path"])->toArray();
//get the last object from s3
$object = end($result['Contents']);
$key = $object['Key'];
$file = $s3->getObject([
'Bucket' => 'your-bucket-id',
'Key' => $key
]);
//download the file
header('Content-Type: ' . $file['ContentType']);
echo $file['Body'];
?>
Run the Composer command to install s3 extension. composer require frostealth/yii2-aws-s3 ~1.0#stable
Open common/config/main.php file and add below code into "components" section. "s3bucket" => [ "class" => \frostealth\yii2\aws\s3\Storage::className(), "region" => "Your region", "credentials" => [ "key" => "your aws s3 key", "secret" => "your aws s3 secret", ], "bucket" => "your aws s3 bucket", "defaultAcl" => \frostealth\yii2\aws\s3\Storage::ACL_PUBLIC_READ, "debug" => false, // bool|array ],
Use below code to upload image on s3 $s3 = Yii::$app->get('s3bucket')->upload('upload image name', 'path of local folder where image located');
After uploading you get status code and image url. you can get like below $status = $s3["#metadata"]["statusCode"]; $imageUrl = $s3["#metadata"]["effectiveUri"];
I reimport my extension using composer,
and adding
require (\Yii::getAlias('#vendor/autoload.php'));
Somehow I got it working by adding 'autoload' in json composer
"autoload": {
"psr-4": {
"vendor\\aws\\" :""
}
}
and then run
php composer.phar dumpautoload
Was looking around for this for a few hours and only found other packages to solve the issue. Wanted to implement the AWS package directly. So from
Installed the latest aws-sdk via composer.
I am using
"aws/aws-sdk-php": "^3.259"
Make sure aws source and location is correct in the vendor/composer/autoload_psr4.php
'Aws\\' => array($vendorDir . '/aws/aws-sdk-php/src')
After that ran composer update as mentioned by #Karate_Dog
php composer.phar dumpautoload

Categories