Deploy Laravel | PHP 8.4 on FrankenPHP with Postgres
Laravel 13 on FrankenPHP with Postgres and runtime config caching
Just deployed
Just deployed
/var/lib/postgresql/data
Deploy and Host Laravel on Railway
Laravel 13 on PHP 8.4, served by FrankenPHP in a single container, with Postgres.
About Hosting Laravel
The Laravel template on Railway builds from a repository last updated in October 2024 - Laravel 11.9, when 13 is current - and about one deployment in eight does not come up.
This one is a current scaffold in a container that gets two things right. Both are easy to get wrong, and both fail in ways that are hard to read.
Config caching happens at runtime, not during the build. php artisan config:cache writes the values of environment variables into a PHP file. Railway injects variables at runtime, so a config cache built during the image build freezes in whatever existed then - nothing - and your database credentials are silently empty in production. The entrypoint caches after the environment is present.
APP_KEY has no default and the container refuses to start without one. Laravel uses it to encrypt sessions and cookies. A template that ships a fixed key hands the same one to every deployment made from it.
Common Use Cases
- A Laravel application with a real database, migrations and queues ahead of it
- An admin or internal tool where Blade and Eloquent are most of the work
- A starting point that already handles caching, health checks and shutdown
Dependencies for Laravel Hosting
- Postgres, included in this template, on a persistent volume
- Nothing else. Add Redis when you want queues or a cache store outside the database.
Deployment Dependencies
- Laravel: https://laravel.com/docs
- FrankenPHP: https://frankenphp.dev/docs
- Source: https://github.com/ak40u/laravel-railway-starter
Implementation Details
FrankenPHP replaces the nginx and php-fpm pair with one process - fewer moving parts, and no two config files to keep in sync.
| Variable | Why |
|---|---|
| APP_KEY | Generated per deployment; encrypts sessions and cookies |
| DB_* | Wired to the bundled Postgres over the private network |
| APP_URL | The public domain, used for generated links |
| SESSION_DRIVER, CACHE_STORE | database, so both survive a container being replaced |
| LOG_CHANNEL | stderr, so logs reach the platform rather than a file nobody reads |
Migrations run in the pre-deploy step - after the build, before the new version takes traffic. The build has no database to connect to.
The health check is /up, which is Laravel own health endpoint: it boots the framework, so a failing check means the application genuinely cannot start.
One build detail worth keeping if you fork this: bootstrap/cache/*.php is removed during the build. A scaffold created locally with dev dependencies leaves a package manifest listing providers a --no-dev install does not have, and every artisan command then dies on a missing class.
Why Deploy Laravel on Railway?
A database, a domain and TLS from one deploy, migrations applied before each release takes traffic, and a container that starts warm rather than compiling config on the first request.
Template Content