Deploy Security-Hardened Laravel Starter
Hardened Laravel 13 starter — PHP 8.5.12, Postgres, Sanctum auth.
Just deployed
/var/lib/postgresql/data
laravel-starter-railway
Just deployed
Deploy and Host Security-Hardened Laravel Starter on Railway
A production-wired, security-hardened Laravel 13 starter: PHP 8.5.12 (exact pin) + Postgres + Sanctum API auth, behind php-fpm + nginx — no mod_php, no token guard, no demo stubs.
Security story — why this template exists
Two October 2026 disclosures make an unhardened Laravel deploy a bad default. php2shell is unauthenticated remote code execution in PHP itself: CVE-2026-109618 (OOM corruption) and CVE-2026-109619 (stale global state), both CVSS v4.0 9.2, fixed in PHP 8.5.12 (php.net advisory, 21 Oct 2026). This template pins php:8.5.12-fpm-alpine exactly in its Dockerfile and runs php-fpm + nginx, never mod_php, with only public/index.php as the PHP entry point. A follow-up, CVE-2026-115560 (23 Oct 2026), is mitigated with session.upload_progress.enabled=0 in docker/php/security.ini.
The TokenGuard bypass, CVE-2026-114509 (CVSS 9.2, Critical), lets an unauthenticated attacker log in as another user on apps using Laravel's token auth guard. It was fixed in laravel/framework 13.29.0+ (25 Aug 2026). This template uses Laravel 13.38.0 — well above that floor — and Sanctum only; the token guard is never configured anywhere in this repo.
About Hosting Security-Hardened Laravel Starter
Hosting this starter on Railway uses two services: the Laravel app, deployed from the GitHub repo with the Dockerfile builder, and a Postgres service. Railway builds the Dockerfile, runs php artisan migrate --force as the pre-deploy command, then healthchecks GET /api/health, which reports real database status and returns 503 if the database is unreachable. Set DB_CONNECTION=pgsql and DATABASE_URL as a reference to the Postgres service (DATABASE_URL=${{Postgres.DATABASE_URL}}). Generate a unique APP_KEY for each deploy with php artisan key:generate --show — never share one key across deploys — and set APP_URL to the deploy's public domain. APP_ENV stays production and APP_DEBUG stays false.
Common Use Cases
- Start a new Laravel 13 API on a production-wired, security-hardened base instead of a default scaffold.
- Build a Sanctum-authenticated API with validated register, login and logout routes and a protected /api/me endpoint.
- Ship a Laravel app with Postgres on Railway, with migrations run before the app starts and an honest healthcheck.
Dependencies for Security-Hardened Laravel Starter Hosting
- Postgres 18 (Railway Postgres service)
- PHP 8.5.12 (exact pin, php:8.5.12-fpm-alpine) and nginx via php-fpm
- Laravel framework 13.38.0 and Laravel Sanctum 4.3.3
- A unique APP_KEY generated per deploy and the deploy's public APP_URL
Implementation Details
App service: Dockerfile builder, start command /usr/local/bin/entrypoint.sh, healthcheck path /api/health, pre-deploy command php artisan migrate --force. Variables: DB_CONNECTION=pgsql, DATABASE_URL=${{Postgres.DATABASE_URL}}, APP_KEY (required, no default value), APP_URL (the deployer's public domain).
Why Deploy Security-Hardened Laravel Starter on Railway?
Railway is a singular platform to deploy your infrastructure stack. Railway will host your infrastructure so you don't have to deal with configuration, while allowing you to vertically and horizontally scale it.
By deploying Security-Hardened Laravel Starter on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.
Template Content
laravel-starter-railway
AdeelAhmedKhan/laravel-starter-railwayAPP_KEY
Required. Generate your own unique key with: php artisan key:generate --show — never reuse a key from another deploy.
APP_URL
The deploy's public domain — set this to the domain generated for the app service (Networking → Generate Domain).