Base image for laravel projects
667
Production-ready Docker base image for Laravel applications — PHP 8.3, Nginx, Supervisor, and Redis, all on Alpine Linux.
Build one image, run it as any service: web server, queue worker, task scheduler, WebSocket server (Reverb), or high-performance app server (Octane) — controlled entirely by the container command.
web, queue, scheduler, cron, worker, or artisanexpose_php=Off, server_tokens off, hidden file blocking, sensitive path protectionAPP_ENV=production.dockerignore, non-root process execution, proper signal handlinggit clone https://github.com/aspect-suspended/laravel-docker.git
cd laravel-docker
docker build -t laravel-base .
This repository does not include a Laravel application. It provides only the Docker infrastructure. You bring your own Laravel app.
Create a Dockerfile in your Laravel project root:
FROM laravel-base:latest AS build
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --no-scripts --prefer-dist --optimize-autoloader
FROM laravel-base:latest
WORKDIR /app
COPY --from=build /app/vendor /app/vendor
COPY --chown=www-data:www-data . /app
RUN composer dump-autoload --optimize --no-dev \
&& php artisan package:discover --ansi
CMD ["web"]
# Web server (Nginx + PHP-FPM)
docker run -p 80:80 my-laravel-app web
# Queue worker
docker run my-laravel-app queue
# Task scheduler
docker run my-laravel-app scheduler
# One-off artisan command
docker run --rm my-laravel-app artisan migrate --force
The example/setup.sh script automates the full workflow — it clones a fresh Laravel project (or your own repo), copies in the Docker files, builds images, and starts the stack:
# Clone this repo
git clone https://github.com/aspect-suspended/laravel-docker.git
cd laravel-docker
# Run the setup script (creates a fresh Laravel project in example/app/)
cd example
./setup.sh
# Or point it at your existing project
./setup.sh https://github.com/your-user/your-laravel-app.git
./setup.sh /path/to/local/laravel-project
# Start the stack
docker compose up -d
The setup script will:
example/app/Dockerfile and .dockerignore templates into the applaravel-base image from this repo's rootlaravel-app image from the app directoryAPP_KEY if one isn't set# 1. Build the base image
git clone https://github.com/aspect-suspended/laravel-docker.git
cd laravel-docker
docker build -t laravel-base .
# 2. In your Laravel project, create a Dockerfile (see Quick Start above)
# 3. Build your app image
cd /path/to/your-laravel-app
docker build -t my-app .
# 4. Run
docker run -p 80:80 my-app web
Note: The Laravel framework is always installed externally (via
composer create-project,git clone, or your existing project). This repo stays lightweight and framework-agnostic — it only provides the Docker base image and configuration.
+------------------+
| laravel-base | <-- This repo (base image)
| PHP 8.3 + Nginx |
| + Supervisor |
+--------+---------+
|
+--------+---------+
| laravel-app | <-- Your app (extends base)
| App code + |
| Composer deps |
+--------+---------+
|
+--------------+--------------+
| | |
+-----+----+ +-----+----+ +------+-----+
| web | | queue | | scheduler |
| Nginx + | | artisan | | schedule: |
| PHP-FPM | | queue: | | run loop |
| port 80 | | work | | (60s) |
+----------+ +----------+ +------------+
All three services run the same image — only the command differs.
| Command | Description |
|---|---|
web | Starts Nginx + PHP-FPM (default) |
queue | Starts a Laravel queue worker |
scheduler | Runs artisan schedule:run in a 60-second loop |
cron | Starts the system cron daemon |
worker | Starts Supervisor managing queue + scheduler together |
artisan | Runs any artisan command (e.g., artisan migrate) |
| Variable | Default | Description |
|---|---|---|
APP_ENV | production | When production, caches config/routes/views on startup |
RUN_MIGRATIONS | false | Set to true to auto-run migrations on container start |
QUEUE_NAME | default | Queue name(s) for the worker |
QUEUE_TRIES | 3 | Number of times to retry a failed job |
QUEUE_TIMEOUT | 90 | Max seconds a job may run |
QUEUE_MAX_JOBS | 1000 | Worker restarts after processing this many jobs |
QUEUE_MAX_TIME | 3600 | Worker restarts after running this many seconds |
Key settings in docker/php/php.ini:
| Setting | Value | Notes |
|---|---|---|
memory_limit | 512M | Adjust per workload |
upload_max_filesize | 100M | Matched with Nginx client_max_body_size |
opcache.jit | 1255 | JIT tracing mode with 128 MB buffer |
opcache.validate_timestamps | 0 | Files never rechecked — deploy = restart |
expose_php | Off | Hides PHP version from response headers |
Key settings in docker/php/php-fpm.conf:
| Setting | Value | Notes |
|---|---|---|
pm | dynamic | Scales workers between min/max |
pm.max_children | 20 | ~30 MB per child; tune for container memory |
pm.max_requests | 1000 | Workers recycle to prevent memory leaks |
clear_env | no | Docker env vars pass through to PHP |
Security features in docker/nginx/:
server_tokens off — hides Nginx versionX-Frame-Options, X-Content-Type-Options, X-XSS-Protection, Referrer-Policy.env, .git)vendor/, storage/ directories/health endpoint for load balancer probesimmutable headersThe examples/ directory contains ready-to-use Docker setups for common Laravel service patterns:
| Example | Description |
|---|---|
basic/ | Standard web + queue + scheduler + MySQL + Redis |
reverb/ | Laravel Reverb WebSocket server |
octane/ | Laravel Octane with Swoole/FrankenPHP |
docker-compose.yml | Full stack combining all services |
See examples/README.md for detailed usage instructions.
cd examples/basic
./setup.sh # Clones Laravel, builds images
docker compose up -d # Starts web, queue, scheduler, mysql, redis
laravel-docker/
├── Dockerfile # Base image definition
├── .dockerignore # Build context exclusions
├── docker/
│ ├── entrypoint.sh # Multi-mode entrypoint script
│ ├── nginx/
│ │ ├── nginx.conf # Main Nginx config
│ │ └── default.conf # Laravel vhost config
│ ├── php/
│ │ ├── php.ini # PHP production settings
│ │ └── php-fpm.conf # FPM pool configuration
│ └── supervisor/
│ ├── supervisord.conf # Supervisor main config
│ └── conf.d/
│ ├── queue-worker.conf # Queue worker process
│ └── scheduler.conf # Scheduler process
├── examples/
│ ├── basic/ # Standard full-stack example
│ ├── reverb/ # Laravel Reverb WebSocket example
│ ├── octane/ # Laravel Octane example
│ └── docker-compose.yml # Combined services compose
├── CONTRIBUTING.md
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
└── LICENSE
Extend the base image in your project's Dockerfile:
FROM laravel-base:latest
# Example: add PostgreSQL support
RUN apk add --no-cache postgresql-dev \
&& docker-php-ext-install pdo_pgsql
FROM laravel-base:latest
COPY my-nginx.conf /etc/nginx/http.d/default.conf
FROM laravel-base:latest
COPY my-php.ini /usr/local/etc/php/conf.d/99-custom.ini
Contributions are welcome. Please read CONTRIBUTING.md before submitting a pull request.
This project follows the Contributor Covenant Code of Conduct. By participating, you agree to uphold this code.
This project is licensed under the MIT License. See LICENSE for details.
Content type
Image
Digest
sha256:b3a4d0af2…
Size
211.1 MB
Last updated
6 months ago
docker pull weboccult/laravel-base