Laravel — Blueprint
Fullstack web app with PHP 8.2, Laravel 11, and PostgreSQL
Fullstack web application built with PHP 8.2+, Laravel 11, and PostgreSQL. Serves a Blade-rendered HTML page and a JSON API. Intended as a starting point for Kubernetes-deployed services: one table, one API endpoint, full Docker support out of the box.
Tech stack:
| Layer | Technology |
|---|---|
| Language | PHP 8.2+ |
| Framework | Laravel 11 |
| Database | PostgreSQL |
| Migrations | Laravel migrations (Eloquent) |
| ORM | Eloquent |
| Web server | Apache (mod_rewrite) |
The application runs on port 80. The root / serves an HTML page; the API is available under /api/.
Project Structure
app/
├── Http/Controllers/
│ ├── SpaceTargetController.php # GET /api/targets
│ └── InfoController.php # GET /api/info
└── Models/
└── SpaceTarget.php # Eloquent model (table: space_target)
routes/
├── api.php # /api/targets, /api/info
└── web.php # / → Blade home view
resources/views/
└── home.blade.php # HTML page with space targets table
config/
└── database.php # Custom connection config (DATABASE_URL or DB_*)
database/migrations/
└── 2025_01_01_000000_create_space_targets_table.php # Creates table + seed data
docker/
└── entrypoint.sh # Runs php artisan migrate --force, then starts ApacheKey design decisions:
config/database.phpparsesDATABASE_URL(thepostgres://format from managed services) or falls back to individualDB_*variables. This replaces the default Laravel.env-only approach, which does not understand thepostgres://scheme natively.APP_KEYis required for Laravel to start. In the Docker Compose file a development key is pre-set. For production, generate a real one:php artisan key:generate --show.- Migrations run automatically on container startup via
docker/entrypoint.sh(php artisan migrate --force). There is no separate migration job. SpaceTargetis the demo entity with$timestamps = falsesince the table has nocreated_at/updated_atcolumns. To add your own domain: create a model inapp/Models/, a migration indatabase/migrations/, and a controller inapp/Http/Controllers/. Register routes inroutes/api.php.- The demo files can be deleted once you no longer need them.
Environment Variables
The application runs on port 80 and requires a PostgreSQL database.
| Variable | Required | Description |
|---|---|---|
APP_KEY | yes | Laravel app key — generate with php artisan key:generate --show |
APP_ENV | no | production or local (default: production) |
APP_DEBUG | no | true / false (default: false) |
APP_URL | no | Full URL of the app, e.g. https://example.com |
Database connection is configured via one of two approaches:
Option A — Single connection URL (recommended for managed services)
| Variable | Required | Example |
|---|---|---|
DATABASE_URL | yes | postgres://user:pass@host:5432/dbname?sslmode=require |
Option B — Individual variables
| Variable | Required | Default | Description |
|---|---|---|---|
DB_HOST | no | 127.0.0.1 | Database host |
DB_PORT | no | 5432 | Database port |
DB_NAME | no | laravel | Database name |
DB_USER | no | postgres | Database user |
DB_PASSWORD | no | (empty) | Database password |
DB_SSL_MODE | no | prefer | SSL mode, e.g. require or disable |
DATABASE_URL takes precedence. If it is set, the individual DB_* variables are ignored.
Running Locally
With Docker Compose
docker compose upStarts the application together with a PostgreSQL instance. APP_KEY and DATABASE_URL are set automatically. No additional configuration needed.
Standalone
Requires PHP 8.2+, Composer, and a running PostgreSQL instance.
# install dependencies
composer install
# run — Option A
DATABASE_URL=postgres://postgres:postgres@localhost:5432/spacedb \
APP_KEY=base64:$(openssl rand -base64 32) \
php artisan migrate
php artisan serve
# run — Option B
DB_HOST=localhost DB_USER=postgres DB_PASSWORD=secret \
APP_KEY=base64:$(openssl rand -base64 32) \
php artisan migrate
php artisan serve