AWS code deploy after install whoami issues - laravel

I'm migrating away from Envoyer to AWS code deploy to auto-deploy my Laravel app.
So I added this to my afterInstall script:
cd /project directory
composer install
if [ -f artisan ]
then
php artisan migrate --force
fi
if [ -f artisan ]
then
php artisan config:cache
php artisan queue:restart
fi
But the deployment fails with this error
MessageScript at specified location: scripts/after-install.sh run as
user user failed with exit code 1 Log TailLifecycleEvent -
AfterInstall Script - scripts/after-install.sh [stderr]No passwd entry
for user 'user'
which is weird. The AMI instance I've created already has the default user login as well as ubuntu as sudoers:
grep -Po '^sudo.+:\K.*$' /etc/group
ubuntu,forge
So why is it asking for a password?

I had to change the runAs section in the appspec file
in the script specified in "location".
AfterInstall:
- location: scripts/after-install.sh
runas: forge // used to be 'user'

Related

Cannot write to images directory | cloud hosting with Laravel forge

I have a problem when deploying Laravel an application using Laravel forge. I try to generate fake images using faker package in Laravel but,
Cannot write to directory "/home/forge/my.domain/public/storage/images/products/cover_img"
at vendor/fakerphp/faker/src/Faker/Provider/Image.php:98
94▕ ) {
95▕ $dir = null === $dir ? sys_get_temp_dir() : $dir; // GNU/Linux / OS X / Windows compatible
96▕ // Validate directory path
97▕ if (!is_dir($dir) || !is_writable($dir)) {
➜ 98▕ throw new \InvalidArgumentException(sprintf('Cannot write to directory "%s"', $dir));
99▕ }
100▕
101▕ // Generate a random filename. Use the server address so that a file
102▕ // generated at the same time on a different server won't have a collision.
in the factory file,
'cover_img' => $this->faker->image(public_path('storage/images/products/cover_img'), 640, 480, null, false),
This is my first time using cloud hosting. when using shared hosting I can give permission to create a folder or can create a folder manually. please help me to solve this problem. Thank You!
***UPDATE ***
I change a few codes and again tried.
if(!File::exists(public_path().'/storage/images/products/cover_img'))
{ File::makeDirectory(public_path().'/storage/images/products/cover_img', 0777,true);
}
Now it has error when deploy using Laravel forge,
ErrorException
mkdir(): Permission denied
If someone can help me to solve this I really appreciate it.
Finally, I've figured out the issue, I think First I did the total wrong way because I tried to seed when deploying using forge with php artisan migrate:fresh --seed code. Then came that error. below has the wrong code.
cd /home/forge/dev.mydomain.com
git pull origin $FORGE_SITE_BRANCH
$FORGE_COMPOSER install --no-interaction --prefer-dist --optimize-autoloader
( flock -w 10 9 || exit 1
echo 'Restarting FPM...'; sudo -S service $FORGE_PHP_FPM reload ) 9>/tmp/fpmlock
if [ -f artisan ]; then
$FORGE_PHP artisan migrate --seed
fi
So, finally, I did just deploy with default settings in the forge and I log in to serve using terminal, Then I run the php artisan migrate --seed command and I was successful without any error. This was the step I followed,
Generate SSH key using git bash
ssh-keygen
Added ssh key into the forge
run this command in git bash terminal
ssh forge#ip address in the server
then installed the oh my zsh using this code,
sh -c "$(curl -fsSL
https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
then went to my directory in the host using terminal,
cd dev.maydomain.com
and final run seed,
php artisan migrate --seed

Problem with executing laravel migrations on Elastic Beanstalk

I deployed my laravel application using Elastic beanstalk, and I need to execute php artisan:migrate command on the remote database.
Based on Maximilian's tutorial I created init.config file inside .ebextensions with contents:
container_commands:
01initdb:
command: "php artisan migrate"
The status of the deployment is Healthy, but it didn't create any table!
any clues, please?
run php artisan config:cache then run migrate command
As you did not include any relevant logs. I am guessing you need to run your migration within the staging folder.
An example of how you can run migrations:
04_run_migrations:
command: "php artisan migrate --force"
cwd: "/var/app/staging"
leader_only: true
--force is needed cause php artisan migrate asks you if you are sure to run it on a production environment
leader_only is needed if you use horizontal scaling.
Source:
https://github.com/rennokki/laravel-aws-eb/blob/master/.ebextensions/01_deploy.config

Laravel Aws Elastic-Beanstalk deployment with EbCommands

I am familiar with deployments using laravel apps to Aws Elastic Beanstalk, but today when trying to deploy another app (Laravel 5.7), I get this annoying exception error:
InvalidArgumentException - Please provide a valid cache path.
I have done my research, and I have tried the usual suggestions = creating folders under storage, and giving permissions, without success. Aws even tells me the following folders exist: storage/framework/[sessions, views, cache]
During deployment, everything runs perfectly, env file copied, migrations and seed is done, then deployment stops because of this error.
Here are the commands I run when deploying (ebCommands) :
commands:
01_update_composer:
command: export HOME=/root && export COMPOSER_HOME=/root && /usr/bin/composer.phar self-update 1.0.0-alpha11
option_settings:
aws:elasticbeanstalk:container:php:phpini:
document_root: /public
memory_limit: 512M
users:
ec2-user:
groups:
- webapp
files:
"/opt/elasticbeanstalk/hooks/appdeploy/post/02_configure_environment_file.sh":
mode: "000777"
owner: root
group: root
content: |
#!/bin/bash
if [ ! -f /var/www/html/.env ] ; then
cp /var/www/html/.env.example /var/www/html/.env
fi
php /var/www/html/artisan migrate:refresh
php /var/www/html/artisan db:seed
mkdir -p /var/www/html/storage/framework/cache/data
mkdir -p /var/www/html/storage/framework/sessions
mkdir -p /var/www/html/storage/framework/views
mkdir -p /var/www/html/storage/app
mkdir -p /var/www/html/storage/logs
mkdir -p /var/www/html/bootstrap/cache
chmod -R 775 /var/www/html/bootstrap/cache
chmod -R 775 /var/www/html/storage
chmod -R 775 /var/www/html/storage/logs
php /var/www/html/artisan config:clear
php /var/www/html/artisan cache:clear
php /var/www/html/artisan config:cache
It should deploy and I should be able to see my website.
Instead, Aws logs show :
InvalidArgumentException : Please provide a valid cache path.
The website shows the same error message.
I have tried various things online, but I'm stuck !
It is not the first laravel app I'm deploying.
I do the deployment with CodePipeline and github automatically.
For me the issue is probably a permission issue...
Thank you !!
The error usually occurs when the storage folders are missing from the document root. You need to ensure the following folders are present:
./storage/framework/cache
./storage/framework/sessions
./storage/framework/views

Laravel - AWS Beanstalk - Storage symlink not working (403 error)

I am using elastic beanstalk to deploy my laravel application. Everything is working fine except for my images as I need to create a symbolic link with storage to access it publicly.
P.S. Works fine on my local
My .ebextensions file is as follows -
commands:
composer_update:
command: export COMPOSER_HOME=/root && /usr/bin/composer.phar self-update
option_settings:
- namespace: aws:elasticbeanstalk:application:environment
option_name: COMPOSER_HOME
value: /root
container_commands:
01-install_dependencies:
command: "php /usr/bin/composer.phar install"
cwd: "/var/app/ondeck"
02_storage_sym_link:
command: "php artisan storage:link"
cwd: "/var/app/ondeck"
leader_only: true
Below is the log from my ec2 instance to confirm that the command worked just fine and the link was created successfully.
[2019-04-21T15:47:16.899Z] INFO [21538] - [Application update symlink alt2#208/AppDeployStage0/EbExtensionPostBuild/Infra-EmbeddedPostBuild/postbuild_0_Synchro/Test for Command 02_storage_sym_link] : Starting activity...
[2019-04-21T15:47:16.903Z] INFO [21538] - [Application update symlink alt2#208/AppDeployStage0/EbExtensionPostBuild/Infra-EmbeddedPostBuild/postbuild_0_Synchro/Test for Command 02_storage_sym_link] : Completed activity. Result:
Completed successfully.
[2019-04-21T15:47:16.903Z] INFO [21538] - [Application update symlink alt2#208/AppDeployStage0/EbExtensionPostBuild/Infra-EmbeddedPostBuild/postbuild_0_Synchro/Command 02_storage_sym_link] : Starting activity...
[2019-04-21T15:47:17.014Z] INFO [21538] - [Application update symlink alt2#208/AppDeployStage0/EbExtensionPostBuild/Infra-EmbeddedPostBuild/postbuild_0_Synchro/Command 02_storage_sym_link] : Completed activity. Result:
The [public/storage] directory has been linked.
The error I am getting is as follows which makes the images unavailable for public access.
Forbidden
You don't have permission to access /storage/blog/images/8Yhb4OZJQIKwlMGaGE803niTxyjfzNSVTj2BiPaP.gif on this server.
Any help guiding me to the right path is appreciated. Cheers!
EDIT 1 :
container_commands:
01-install_dependencies:
command: "php /usr/bin/composer.phar install"
cwd: "/var/app/ondeck"
02_storage_sym_link:
command: "ln -s storage/app/public public/storage"
cwd: "/var/app/ondeck"
03_give_ec2_user_perm_1:
command: "sudo chown -R ec2-user /var/app/current"
03_give_ec2_user_perm_2:
command: "sudo chmod -R 777 /var/app/current"
Tried creating the symlink manually plus gave permission to the ec2-user. But still no luck :(
Putting down an alternate option which does the job for people who are/might have a similar issue -
Use S3 for file storage in your Laravel application.
To make it happen -
Create a public S3 bucket.
Create an IAM user which has full access to
S3 bucket. (With the access key, the application will have
permissions to read and write in the S3 bucket.)
Update the config file filesystems.php to use the S3 bucket. (This config handles the storage config of the application.)
Refer the Laravel Doc for more info.
Thanks to #PranavanSp for his suggestion.
Container commands are run as root, that is why when you tried to run it as the ec2-user you couldn't. The ec2-user is not in the root user group.
Then when you create symlinks, try to do it in the actual app directory(current):
container_commands:
01-install_dependencies:
command: "php /usr/bin/composer.phar install"
cwd: "/var/app/ondeck"
02_storage_sym_link:
command: "ln -s storage/app/public public/storage"
cwd: "/var/app/current"
Or try to link directly as so:
container_commands:
01-install_dependencies:
command: "php /usr/bin/composer.phar install"
cwd: "/var/app/ondeck"
02_storage_sym_link:
command: "ln -s /var/app/ondeck/storage/app/public /var/app/current/public/storage"
EBS Files can be annoying to get right at first but worth it in the end. If this still doesn't work, maybe the user(appache I assume) that runs the server does not have access to that folder. To just quickly verify this just do a:
sudo chmod -R 755 /var/app/ondeck/storage/app/public

Heroku and Laravel Passport

I try to install my app on heroku. This app is a php-laravel app with the "passport" for the authentication. All is running fine in my local machine (mac os).
When I try to do a simple 'post' with postman, I have this error :
2018-03-17T17:05:22.059708+00:00 app[web.1]: [17-Mar-2018 17:05:22 UTC] [2018-03-17 17:05:22] production.ERROR: Key path "file:///app/storage/oauth-private.key" does not exist or is not readable {"exception":"[object] (LogicException(code: 0): Key path \"file:///app/storage/oauth-private.key\" does not exist or is not readable at /app/vendor/league/oauth2-server/src/CryptKey.php:45)"} []
To setup passport, I generated the keys with :
php artisan passport:install
And I see the keys in my database in heroku. So the command worked properly.
So what is this error ?
I tried also to regenerate the keys, to stop and restart the application. Without successes.
Thanks for your suggestions.
Merci
Dominique
EDIT : in fact, the key files are not generated in the folder app/storage, that's why there is this error. But why these files are not generated ?
The solution is here: https://github.com/laravel/passport/issues/267
Add these few lines into your composer.json under the "scripts" property, then commit and deploy into Heroku:
"post-install-cmd": [
"php artisan clear-compiled",
"chmod -R 777 storage",
"php artisan passport:keys"
]
But, after that you have to delete the keys from the table "oauth-clients", then regenerate these keys with :
php artisan passport:install
About the #Dom answer, It will log out your users with every deployment, so if you're really using Heroku and not Dokku (as in my case), I recommend you to generate the keys by using that command: php artisan passport:keys and then via Nano copy the keys generated in storage/oauth-public.key and storage/oauth-private.key into multiline env variables, then you can use this post install script in composer.json:
"post-install-cmd": [
"php artisan clear-compiled",
"chmod -R 777 storage",
"echo -n $OAUTH_PRIVATE_KEY > storage/oauth-private.key",
"echo -n $OAUTH_PUBLIC_KEY > storage/oauth-public.key" ]
That will regenerate the keys from ENV with every deployment and keep your users logged in.
If that solution doesn't work, you could still remove '/storage/*.key' line from .gitignore
Laravel Passport has a configuration that allows to set public and private keys as environment variables.
You can run php artisan vendor:publish --tag=passport-config on your local machine and commit the change.
Then set PASSPORT_PRIVATE_KEY and PASSPORT_PUBLIC_KEY on Heroku config.
Found from this blog
My solution was quite straight forward:
go to your .gitignore file
comment out /storage/*.key
re-deploy to heroku
It appears that the oauth-keys are ignored by default in Laravel (v.7)
Loading Keys From The Environment
Alternatively, you may publish Passport's configuration file using the vendor:publish Artisan command:
php artisan vendor:publish --tag=passport-config
After the configuration file has been published, you may load your application's encryption keys by defining them as environment variables:
PASSPORT_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
<private key here>
-----END RSA PRIVATE KEY-----"
PASSPORT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----
<public key here>
-----END PUBLIC KEY-----"
Passport documentation
I have a better solution to the problem that does not require making your keys public
connect to your heroku account via you terminal
Run heroku ps:exec
Run php artisan passport:keys

Resources