This guide covers deploying Avalúo Vehicular to a production server using Docker and Docker Compose. The application ships with a fully self-contained multi-stageDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/alber1802/AvaluoVehicular/llms.txt
Use this file to discover all available pages before exploring further.
Dockerfile that compiles React/Vite frontend assets, installs PHP production dependencies via Composer, and assembles a final PHP 8.4 FPM + Nginx + Supervisor image — no separate Node.js or Composer installation required on the host. All application state (SQLite database, uploaded files, and logs) is persisted via Docker volumes so container rebuilds and updates are non-destructive.
Requirements
| Requirement | Minimum Version |
|---|---|
| Docker Engine | 20.x or later |
| Docker Compose | v2.x (compose plugin) |
| Available RAM | 512 MB |
| Disk space | ~1 GB (image + data) |
Dockerfile Architecture (Multi-Stage Build)
TheDockerfile uses a four-stage multi-stage build to produce a lean, production-ready image. Each stage performs a single responsibility and only its artifacts are carried forward to the next stage.
Stage 1 — composer-builder
--no-dev). The --optimize-autoloader flag generates a classmap for faster class resolution in production. The --ignore-platform-reqs flag is required because the Composer image does not include all PHP extensions (those are installed in the final stage).
Stage 2 — wayfinder-generator
resources/js/routes/ and resources/js/actions/). These generated files must exist before Vite compiles the frontend.
Stage 3 — frontend-builder
npm ci followed by Vite’s production build (npm run build). The SKIP_WAYFINDER=true env var prevents the Vite plugin from attempting to regenerate Wayfinder types (PHP is not available in this Node-only stage). The compiled output lands in public/build/.
Stage 4 — production (Final Image)
php:8.4-fpm-alpine and bundles:
- PHP 8.4 FPM — processes PHP requests forwarded by Nginx
- Nginx — serves static assets directly, proxies dynamic requests to PHP-FPM
- Supervisor — keeps PHP-FPM, Nginx, and the Laravel queue worker running as supervised processes
- OPcache — pre-compiles PHP files into shared memory for faster execution
- SQLite + PDO — the database driver used in production
- GD + BCMath — required for image processing and financial calculations
Docker Compose Configuration
Thedocker-compose.yml defines a single app service that maps host port 8080 to container port 80, mounts three persistent volumes, and loads environment variables from .env.docker.
The default host port is
8080. To change it, update the left-hand side of "8080:80" in docker-compose.yml — for example, "443:80" for a reverse-proxy setup, or "80:80" if no other web server is running on the host.Environment Variables
Production environment variables are defined in.env.docker. Copy this file and customize before the first build.
| Variable | Production Value | Notes |
|---|---|---|
APP_ENV | production | Disables debug-only service providers |
APP_DEBUG | false | Never true in production |
APP_URL | http://127.0.0.1:8080 | Used for asset URLs and email links; update to your domain in production |
DB_CONNECTION | sqlite | SQLite file path set in DB_DATABASE |
SESSION_DRIVER | database | Session table must exist (run migrations) |
QUEUE_CONNECTION | database | Queue jobs stored in SQLite |
CACHE_STORE | database | Cache entries stored in SQLite |
LOG_LEVEL | error | Only errors logged in production |
AUTO_MIGRATE | false | Migrations run manually, not on startup |
Persistent Volumes
The three bind-mount volumes ensure your data survives container rebuilds, image upgrades, anddocker-compose down operations.
| Host Path | Container Path | Contents |
|---|---|---|
./database/database.sqlite | /var/www/html/database/database.sqlite | All application data (SQLite database) |
./storage/logs | /var/www/html/storage/logs | laravel.log and other log files |
./storage/app | /var/www/html/storage/app | Uploaded vehicle images and PDF reports |
docker-compose up, create the SQLite file on the host so Docker mounts it as a file (not a directory):
First-Time Setup
Build the Docker image
The multi-stage build compiles frontend assets and installs all dependencies. This may take several minutes on the first run.
Generate the application key
base64:... value to APP_KEY in the running container. For a persistent key, update .env.docker with the generated value and rebuild.Run database migrations
--force flag bypasses the production confirmation prompt. This creates all tables including sessions, jobs, and cache_locks (required for SESSION_DRIVER=database and QUEUE_CONNECTION=database).Update Procedure
Stop the running container
Rebuild the image
--no-cache if you need a completely clean rebuild (e.g., after changing system-level dependencies):Supervisor Process Management
Supervisor runs inside the container and manages three processes:nginx, php-fpm, and the Laravel queue worker. The configuration is loaded from docker/supervisor/supervisord.conf.
Check the status of all supervised processes:
Health Check
Docker Compose monitors the container’s health using the built-in health check:/health endpoint returns an HTTP 200 when the application is running. The start_period: 40s gives the entrypoint script time to complete before health checks begin. You can query the health status manually with:
Production Optimizations
The Docker image includes the following production optimizations out of the box:| Optimization | How It’s Configured |
|---|---|
| OPcache | Enabled with validate_timestamps=0 — PHP files are never re-checked on disk |
| OPcache memory | memory_consumption=256 (MB), interned_strings_buffer=16, max_accelerated_files=10000 |
| Autoloader classmap | composer dump-autoload --optimize --no-dev --classmap-authoritative |
| No dev dependencies | composer install --no-dev removes ~60% of packages |
| Vite production build | Assets are minified, tree-shaken, and content-hashed |
| Nginx gzip | Configured in docker/nginx/default.conf |
| Static file caching | Nginx serves public/build/ assets with a 1-year Cache-Control header |
| PHP upload limits | upload_max_filesize=20M, post_max_size=20M, memory_limit=256M |