Laravel
Deploy Laravel with a managed FrankenPHP container and CDN assets.
Nitroship detects Laravel when the deployment root contains artisan and a composer.json dependency on laravel/framework. The managed preset builds a container for you; you do not need to write a Dockerfile.
Deploy
Install the CLI
curl -fsSL https://nitroship.co/install.sh | bash
ntro loginAlready installed? Skip ahead. Full options, PATH setup, and updates: Install the CLI.
Choose a compute region and, if you want to select Laravel explicitly, add this file at the deployment root:
{
"build": {"framework": "laravel"},
"compute": {"regions": ["kr-icn"]}
}Set the production environment variables described below before deploying.
ntro apps create my-laravel-app
ntro deploy . --prodThe managed Laravel preset requires the hosted builder. If your command includes --local, remove it. A compute region is required because PHP requests run on a server.
What Nitroship builds
- Installs production PHP dependencies with
composer install --no-dev. - Builds frontend assets when
package.jsonhas abuildscript, using the managed Node 22 toolchain. - Uses FrankenPHP, a PHP application server, with
public/as the document root. It listens on0.0.0.0:$PORT, with3000as the default port. - Prepares Laravel's config, route, and view caches at startup, after runtime environment variables are available. Your app must support these cache commands.
- Places writable
storage/andbootstrap/cache/under/tmp/nitroship, seeding them at startup instead of relying on writes to the application directory.
Files with allowed browser-asset extensions under public/ are copied into /nitroship/static in the generated image. Nitroship automatically extracts that directory to the CDN, which serves those files before requests reach Laravel on compute. No build.outputDirectory setting is needed.
The extension allowlist is .css, .js, .mjs, .html, .txt, .webmanifest, .png, .jpg, .jpeg, .gif, .webp, .avif, .ico, .svg, .woff, .woff2, .ttf, .otf, .eot, .mp4, .webm, and .pdf. PHP files, symlinks, hidden paths, and the document root's vendor/ and node_modules/ are not copied.
The filter also skips directories named app, bootstrap, config, resources, routes, storage, src, templates, tests, test, bin, parts, or patterns; JS/MJS filenames containing config or server; *.blade.html and *.twig.html; and filenames beginning with readme, license, or changelog.
Extraction filters paths and extensions, not file contents. Keep server source, templates, secrets, and build configuration outside the public document root: a nonpublic file with an allowed extension can otherwise be published to the CDN.
PHP and toolchain versions
The preset first reads composer.json's PHP requirement (require.php), then falls back to a PHP declaration in .tool-versions. Supported PHP versions are 8.2, 8.3, 8.4, and 8.5; it selects the nearest supported version in the declared major version with a pinned FrankenPHP base/toolchain. Missing or unsupported declarations use the current default, PHP 8.5. A declaration does not install an arbitrary image tag or unsupported release. Use your own Dockerfile if the selected runtime or available extensions do not meet your app's requirements.
Production environment
Add secrets through Environment variables, not by committing a production .env file.
| Variable | What to set |
|---|---|
APP_KEY | Required: a stable Laravel application key generated for this app. Keep it across deployments. |
APP_ENV | production |
APP_DEBUG | false |
APP_URL | Your public HTTPS URL. |
DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD | The database settings your app reads, pointing to an external database. |
SESSION_DRIVER, CACHE_STORE | Prefer an external session/cache backend, such as Redis or a database. Set the connection variables your Laravel configuration expects. Older apps may use CACHE_DRIVER. |
The preset does not provision a database, Redis, or session storage. Local file sessions and caches are not shared between instances and are lost with ephemeral storage. Keep uploads in S3 or another object store; /tmp and Laravel's local storage are not durable upload storage.
Operational limits
The generated container runs as a non-root user. The instance filesystem is ephemeral; use /tmp for temporary writes, not data that must survive instance replacement.
Nitroship does not automatically run database migrations, queue workers, or schedulers. Run migrations from CI or your local machine against the external database, with the appropriate production credentials. Run queue workers separately. For scheduled HTTP work, see Cron jobs; deploying Laravel does not start schedule:work or queue:work.
Packages that need extra PHP extensions, operating-system packages, a custom document root, or a different startup sequence may need a custom image. Route and view caching must work in your application; the preset does not rewrite unsupported application code.
Use your own Dockerfile
Without build.framework, the builder chooses a configured build.dockerfile, then Dockerfile.nitroship, then Dockerfile, before Next.js, the highest-priority detected managed preset, and finally generic static output.
Setting build.framework: "laravel" explicitly selects this preset and overrides an automatically discovered Dockerfile. build.framework and build.dockerfile cannot be set together. To use your own image, remove build.framework and follow the Dockerfile guide.