How to deploy Laravel on your own server
A Laravel app that works on your laptop needs a few more things to run safely in production. Here they are, in order.
1. Point the web server at the public folder
This is the most important step. Only the public folder should be reachable from the internet. If you serve the whole project, visitors may be able to read your .env file and its passwords. (Our guide on blocking .env, .git and backup files shows how to check, and adds a safety net.) On Nginx:
root /var/www/example.com/public;
2. Use safe production settings
Set these in the .env file on the server:
APP_ENV=production
APP_DEBUG=false
APP_URL=https://example.com
Debug mode must stay off. When it's on, error pages can show visitors your settings and secrets.
Keep .env out of Git. Back up APP_KEY somewhere safe and don't change it by accident, because Laravel uses it to read encrypted data.
3. Run the deploy commands
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan optimize
--no-dev leaves out development tools, which don't belong on a live server. optimize caches your settings and routes so the app runs faster.
One thing often catches people out. Once settings are cached, env() only works inside your config files. Use config() everywhere else.
Always back up the database before you run migrations.
Want visitors to see no errors while you deploy? See how to deploy Laravel with no downtime using release folders.
4. Let Laravel write only where it needs to
The web server user needs write access to two folders and no others:
chown -R example:www-data storage bootstrap/cache
chmod -R ug+rwX storage bootstrap/cache
Replace example with the site's own user. Never use 777 to make an error go away.
One catch: files that example creates later, like a new log file from an artisan command, are only writable by example, and the web server can't log errors any more. In our test, that hid errors completely. Our Laravel 500 error guide shows how ACLs keep new files writable for both users.
5. Start the scheduler
If your app uses scheduled tasks, one cron job runs them all. Add it to the site user's crontab:
* * * * * cd /var/www/example.com && php artisan schedule:run >> /dev/null 2>&1
See the Laravel scheduling docs for more.
6. Keep queue workers running
Queue workers send emails and do other background jobs. (To keep those emails out of spam, see how to stop your PHP site's emails from landing in spam.) They need a tool that restarts them if they stop. The Laravel queue docs suggest Supervisor:
[program:example-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/example.com/artisan queue:work --sleep=3 --tries=3 --max-time=3600
user=example
numprocs=2
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
stopwaitsecs=3600
Workers keep your old code in memory. After every deploy, tell them to restart:
php artisan queue:restart
Prefer systemd, which every Ubuntu and Debian server already has? See our step-by-step guide to running Laravel queue workers and the scheduler.
7. Keep logs under control
Laravel's default log file grows until you clear it, and it can fill the disk. Set LOG_CHANNEL=daily in .env, or rotate the file with logrotate. Our guide to stop logs from filling the disk shows how, step by step.
8. Check for known security holes
Run this regularly to see whether any of your packages have known problems:
composer audit
Our guide to keeping Composer packages safe and up to date shows how to run this check every day and update packages safely.
Keep Laravel on a version that still gets security fixes, and keep PHP supported too. See which PHP versions still get security fixes.
In the ServerNest preview, you can install Laravel with one click, deploy from GitHub or Bitbucket, and run the scheduler and queue workers from the dashboard. The product is still in development. Join early access to try it first, or see all platforms.