A Laravel production checklist for your own VPS
· 4 min read
When you run Laravel on your own VPS, nobody else is responsible for the details that managed platforms handle for you. This is the checklist to go through before launch, and again after any major change to the server. Each item is quick to verify.
Web server
- Document root points at
public/. Not the project folder. This is what keeps.env,vendor/and your source code off the internet. See how to check if your.envis exposed. - Dotfiles are blocked. Add a rule so
/.envand/.gitcan never be served, even if the root is wrong one day. - HTTPS everywhere, with automatic certificate renewal and an HTTP to HTTPS redirect. Check the renewal timer actually exists:
systemctl list-timers | grep certbot. - Security headers set on all responses, including errors. See security headers for Laravel on nginx.
Application configuration
APP_ENV=productionandAPP_DEBUG=false, confirmed withphp artisan config:show app.debug. See why debug mode is dangerous.- Config, route and view caches built during deploy:
php artisan optimize. Remember that once config is cached,.envis no longer read at runtime. APP_KEYset and stored somewhere safe outside the server. Losing it means losing anything encrypted with it.- Errors go somewhere you read: a log you check, or an error tracker. Not to the browser.
Files and permissions
.envis not world-readable.chmod 640 .env, owned by the deploy user with the web server's group.- Only
storage/andbootstrap/cache/are writable by the web server user. Everything else should be read-only to it. .envand.gitare not inside any deploy artifact published under a web root.
Server basics
- Firewall allows only what you need. On Ubuntu with ufw: allow SSH, 80 and 443, deny the rest.
sudo ufw statusshould be short. - SSH uses keys, not passwords, and root login is disabled (
PasswordAuthentication no,PermitRootLogin no). - Automatic security updates are on:
unattended-upgradeson Ubuntu or Debian. - PHP is a supported version. See how to check whether your PHP version is still supported.
- The database is not exposed to the internet. It should listen on localhost or a private network only.
Dependencies
composer auditis clean, and runs in CI so new advisories show up. See checking your Composer dependencies.composer install --no-dev --optimize-autoloaderon production, so dev tools are not deployed.
Background work
- Queue workers run under systemd or Supervisor and restart on failure. Deploys run
php artisan queue:restart. See monitoring a queue worker. - The scheduler is wired up: one cron entry,
* * * * * cd /var/www/myapp && php artisan schedule:run >> /dev/null 2>&1.
Backups and recovery
- Database and uploaded files are backed up automatically, off the server.
- You have restored a backup at least once on a different machine. A backup you have never restored is a hope, not a backup.
- Backup freshness is monitored. A backup job that silently stopped three weeks ago is worse than none, because you think you are covered.
Housekeeping
- Logs rotate, so a noisy error cannot fill the disk. Laravel's
dailylog channel with a retention limit works. - Disk, memory and swap are watched. Full disks take down databases and queues in ugly ways.
- Someone is told when something breaks, and it is not found out by customers.
Automate what you can
Most of this list is the kind of thing that is right on launch day and drifts afterwards. A config tweak drops a header, a deploy leaves debug on, a backup job fails quietly.
PHPGuard exists for exactly that gap: the free scan checks the external items (exposed files, headers, SSL), and the agent checks the inside of your server on a schedule, including APP_DEBUG, .env permissions, PHP end-of-life, dependency advisories, queue workers, backup freshness and disk space, and emails you when something turns critical.
Check your own site
The free PHPGuard scan checks for exposed .env and .git files, missing security headers and SSL problems in seconds. For continuous monitoring from inside your server, start the 14-day free trial (no card required).
More articles
-
Check your Laravel dependencies for known vulnerabilities with composer audit
Most breaches of PHP apps come through a vulnerable package, not your own code. How to run composer audit, read the output, wire it into CI, and handle packages that cannot be updated.
-
How to monitor a Laravel queue worker so it doesn't silently die
A dead queue worker looks like a healthy site: pages load, but emails and jobs never run. How to keep the worker alive with systemd, restart it on deploy, and get alerted when it stops.