Deploy by framework

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 login

Already 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:

nitroship.json
{
  "build": {"framework": "laravel"},
  "compute": {"regions": ["kr-icn"]}
}

Set the production environment variables described below before deploying.

ntro apps create my-laravel-app
ntro deploy . --prod

The 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.json has a build script, using the managed Node 22 toolchain.
  • Uses FrankenPHP, a PHP application server, with public/ as the document root. It listens on 0.0.0.0:$PORT, with 3000 as 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/ and bootstrap/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.

VariableWhat to set
APP_KEYRequired: a stable Laravel application key generated for this app. Keep it across deployments.
APP_ENVproduction
APP_DEBUGfalse
APP_URLYour public HTTPS URL.
DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORDThe database settings your app reads, pointing to an external database.
SESSION_DRIVER, CACHE_STOREPrefer 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.

Environment variables · Cron jobs · Dockerfile deployments

On this page