Deploy Laravel on Your Own Server
Push your Laravel app and Temps takes it from there — installing Composer dependencies, caching config and routes, and starting Nginx + PHP-FPM with automatic HTTPS. You run database migrations yourself as a one-off step after each deploy (see below).
Quickstart
From your project root, deploy with your preferred package manager:
npx @temps-sdk/cli up
A composer.json on its own is not a detection signal, so set the nixpacks-php preset on the project first (or nixpacks to let Nixpacks choose). Without it the build stops with "Could not auto-detect project type from files".
With that preset selected, the build runs composer install and serves the app through Nginx and PHP-FPM, applying a Laravel-specific Nginx configuration and a prestart check for missing environment variables. PHP version comes from require.php in your composer.json, defaulting to 8.2.
What Temps handles automatically
| Feature | How Temps handles it |
|---|---|
| Install | composer install --no-dev --optimize-autoloader |
| Cache | php artisan config:cache && route:cache && view:cache |
| Web server | Nginx + PHP-FPM |
| HTTPS | Let's Encrypt, auto-renewed |
| Port | Binds to port 8000 by default |
| Health checks | HTTP health check on / |
Database migrations are not run automatically — see Run migrations below.
Run migrations
Temps does not have a remote "run one command" CLI action yet, so migrations are run directly against the container over SSH. Find the container name, then run the migration:
bunx @temps-sdk/cli projects show -p my-laravel-app --json # note the numeric "id"
bunx @temps-sdk/cli containers list -p <project-id> # note the container_name
ssh your-server 'docker exec <container_name> php artisan migrate --force'
Run this manually (or from your CI/CD pipeline right after the deploy step) every time a deploy includes a schema change. Do not add php artisan migrate --force to your Dockerfile's CMD, start command, or Procfile web process — with rolling deploys, restarts, or multiple replicas, that command can run more than once, and concurrent migration runs against the same database can conflict or corrupt data.
Environment variables
npx @temps-sdk/cli environments vars set APP_ENV production -e production npx @temps-sdk/cli environments vars set APP_KEY "$(php artisan key:generate --show)" -e production npx @temps-sdk/cli environments vars set APP_URL "https://yourdomain.com" -e production
Temps injects DATABASE_URL and REDIS_URL when managed services are attached.
Queue workers and scheduler
Add a Procfile to run queue workers alongside your web process:
web: nginx-unit
worker: php artisan queue:work --sleep=3 --tries=3
scheduler: php artisan schedule:work
Laravel Horizon
For Horizon, add it to your Procfile:
web: nginx-unit
horizon: php artisan horizon
Set the QUEUE_CONNECTION=redis environment variable and attach a Redis service.
Managed services
Add PostgreSQL and Redis from Project → Services → Add Service. Connection strings are injected automatically.
Platform behavior
These rules apply to every app deployed on Temps, regardless of framework.
The one requirement: your app must listen on the port in the PORT environment variable and bind to 0.0.0.0 — not localhost or 127.0.0.1. Temps runs your app in a container and routes traffic from the host, so an app bound to localhost only accepts connections from inside the container and will fail its health check.
Health checks
After your container starts, Temps sends HTTP GET requests to verify it is healthy before routing traffic to it.
- Path:
/(the root of your application) - Success: 2 consecutive responses with a 2xx or 3xx status code
- Timeout: 300 seconds (5 minutes) for the app to become healthy
- Retry interval: every 5 seconds
Connection errors while the app is still starting are retried without penalty. If the app returns 4xx or 5xx errors for 60 consecutive seconds, the deployment fails. Customize the check by adding a .temps.yaml to your repository root:
health:
path: /health
status: 200
interval: 30
timeout: 5
retries: 3/health endpoint that returns a simple 200. This avoids issues where / requires authentication or returns a redirect.Auto-injected environment variables
Temps injects these variables into every deployment automatically:
| Variable | Value | Description |
|---|---|---|
PORT | Resolved port | The port your app must listen on |
HOST | 0.0.0.0 | Bind address |
SENTRY_DSN | Auto-generated | Error tracking endpoint |
TEMPS_API_URL | Your Temps URL | Platform API endpoint |
TEMPS_API_TOKEN | Deployment token | Authentication for Temps SDKs |
OTEL_EXPORTER_OTLP_ENDPOINT | Your Temps OTLP URL | OpenTelemetry trace collection |
OTEL_SERVICE_NAME | Project name | Service identifier for traces |
You do not need to configure these manually. They are available in process.env (Node.js), os.environ (Python), os.Getenv (Go), and the equivalent in other languages.