Laravel
Recipe Features Explained
Let's breakdown the recipe to deploy a new Laravel site.
See Full Deployment Script
source: clear
root: public_html/public
features:
- php latest
- mysql
nginx:
fastcgi: "on"
locations:
- match: /
try_files: $uri $uri/ /index.php$is_args$args
- match: ~ \.[^\/]+(?<!\.php)$
try_files: $uri =404
commands:
- composer create-project laravel/laravel .
- cp .env.example .env
- sed -ri "s/(# )?DB_CONNECTION=.*/DB_CONNECTION=mysql/g" .env
- sed -ri "s/(# )?DB_HOST=.*/DB_HOST=localhost/g" .env
- sed -ri "s/(# )?DB_PORT=.*/DB_PORT=3306/g" .env
- sed -ri "s/(# )?DB_DATABASE=.*/DB_DATABASE=${DATABASE}/g" .env
- sed -ri "s/(# )?DB_USERNAME=.*/DB_USERNAME=${USERNAME}/g" .env
- sed -ri "s/(# )?DB_PASSWORD=.*/DB_PASSWORD=${PASSWORD}/g" .env
- sed -ri "s/APP_URL=.*/APP_URL=https:\/\/${DOMAIN}/g" .env
- php artisan migrate:fresh
- php artisan key:generate
- php artisan storage:link
- npm install
- npm run build
- rm -f public/hot
- chmod 0750 -R storage || true
source: clear
features:
- php latest
- mysql
commands:
- composer create-project laravel/laravel .
This script clears ~/public_html and changing active PHP version to latest installed and create default mysql database and creates a new blank laravel project via composer create-project.
When you upload an existing laravel project, the composer create-project part is omitted.
root: public_html/public
nginx:
fastcgi: "on"
locations:
- match: /
try_files: $uri $uri/ /index.php$is_args$args
- match: ~ \.[^\/]+(?<!\.php)$
try_files: $uri =404
This script declare NGINX Configuration. It means two thing:
-
root: public_html/publicmeans all static files are put topublicfolder. This is the recommended way to serve Laravel for reverse proxy like NGINX. -
fastcgi: "on"means PHP processing is turned on. -
match: /means for all requests, dotry_files: $uri $uri/ /index.php$is_args$args. It means try static files first then process root/index.phpif nothing found. -
match: ~ \.[^\/]+(?<!\.php)$means for requests only to URLs ending with.php, dotry_files: $uri =404. This disables PHP processing for non PHP URLs, known as FastCGI - Safe Config.
commands:
- cp .env.example .env
- sed -ri "s/(# )?DB_CONNECTION=.*/DB_CONNECTION=mysql/g" .env
- sed -ri "s/(# )?DB_HOST=.*/DB_HOST=localhost/g" .env
- sed -ri "s/(# )?DB_PORT=.*/DB_PORT=3306/g" .env
- sed -ri "s/(# )?DB_DATABASE=.*/DB_DATABASE=${DATABASE}/g" .env
- sed -ri "s/(# )?DB_USERNAME=.*/DB_USERNAME=${USERNAME}/g" .env
- sed -ri "s/(# )?DB_PASSWORD=.*/DB_PASSWORD=${PASSWORD}/g" .env
- sed -ri "s/APP_URL=.*/APP_URL=https:\/\/${DOMAIN}/g" .env
This script copies the sample .env.example to .env and changing the database connection to MySQL and sets APP_URL to https://$DOMAIN.
commands:
- php artisan migrate:fresh || true
- php artisan key:generate
- php artisan storage:link
- npm install
- npm run build
- rm -f public/hot
- chmod 0750 -R storage || true
This script executes good practices when initializing a laravel project.
-
php artisan migrate:freshMigrates your laravel project. It's fine if it fail (hence|| true), you can rerun migration again in SSH if it fails. -
php artisan key:generatesets APP_SECRET to.env -
php artisan storage:linkputstoragefolder link topublic/storage. -
npm install&npm run buildinstall and compile frontend tooling, if any. -
rm -f public/hotremoveshotfile that confuses laravel thinking if it still in development mode. -
chmod 0750 -R storage || trueset 0750 tostoragefolder, making sure that NGINX can really reads them.
Updating Laravel
Usually, There are reasons why your changes doesn't reflected in the server:
- Laravel caches if you have route/config/view changes, which you need to clean by:
php artisan route:clear
php artisan config:clear
php artisan view:clear
- Frontend changes that requires frontend tooling, which you need to rebuild by
npm run build - Other stuff related to PHP/NGINX configuration
Enabling Laravel Queue
To enable Laravel Queue via cronjob, open SSH and run EDITOR=nano crontab -e:
@hourly cd public_html && php artisan queue:work --once &>> ./logs/cron.log
Note that this php refers to /bin/php, which always uses latest version. If you need other version, try use such as php83.
To make it always standby, consider implementing timeout:
@hourly cd public_html && timeout 1h php artisan queue:work &>> ./logs/cron.log
Do not omit --once or timeout! In doing so you're risking the whole server to get OOM.
Enable Laravel UI
commands:
- composer require laravel/ui
- php artisan ui bootstrap --auth
- npm install
- npm run build
This enables Laravel UI with Bootstrap and authentication.
Fix 404 NGINX Page when opening page other than index
You may have default NGINX settings applied. You need to fix it to suit laravel need.
root: public_html/public
nginx:
fastcgi: "on"
locations:
- match: /
try_files: $uri $uri/ /index.php$is_args$args
- match: ~ \.[^\/]+(?<!\.php)$
try_files: $uri =404
Fix 404 NGINX Page when opening dynamic media
By default the laravel template uses FastCGI Safe routing, which refuses PHP processing for any URLs with dot. To allow it, use FastCGI normal routing.
root: public_html/public
nginx:
fastcgi: "on"
locations:
- match: /
try_files: $uri $uri/ /index.php$is_args$args
Run Development Mode In Server
You need to open VS Code and run php artisan serve and yarn dev.
Before that, make sure to unset APP_URL from .env. VS Code will set up a local port forwarding so localhost:8000 can be opened directly in your browser.