Laravel Production Stack
Production Laravel with Octane, Horizon, MySQL, and Redis.
[i]Overview
Laravel is a modern PHP web framework that revolutionized web development with its elegant syntax and rich ecosystem. Built around the MVC pattern, Laravel provides powerful features like Eloquent ORM, Blade templating, and robust routing out of the box. Originally created by Taylor Otwell in 2011, Laravel has become the most popular PHP framework, powering millions of applications worldwide from startups to enterprise systems.
This production stack combines Laravel with Octane for dramatically improved performance, Horizon for queue management and monitoring, MySQL as the primary database, Redis for caching and sessions, and NGINX for high-performance web serving. Octane uses Swoole to keep Laravel applications in memory between requests, eliminating the traditional PHP bootstrap overhead and delivering response times that rival Node.js applications. Horizon provides a beautiful dashboard and code-driven configuration for Redis queues, while the entire stack is orchestrated for maximum throughput and reliability.
This configuration targets production environments where performance and scalability are critical. Enterprises running high-traffic Laravel applications, SaaS platforms with demanding performance requirements, and API-heavy applications will benefit most from this setup. The combination of Octane's memory-resident application server, Redis-backed caching and queuing, and NGINX's efficient request handling creates a Laravel deployment capable of handling thousands of concurrent requests while maintaining sub-100ms response times.
[*]Key Features
- [+]Laravel Octane with Swoole server for persistent application instances and sub-50ms response times
- [+]Laravel Horizon dashboard for Redis queue monitoring, failed job management, and throughput metrics
- [+]MySQL 8.0 with InnoDB storage engine providing ACID compliance and JSON column support
- [+]Redis 7 Alpine for ultra-fast session storage, application caching, and queue backend
- [+]NGINX Alpine reverse proxy with SSL termination and static asset serving
- [+]Automated Laravel scheduler container running artisan commands every minute
- [+]Production-optimized environment variables for database connections and cache drivers
- [+]Isolated service networking with proper dependency management and health checks
[#]Common Use Cases
- [1]High-traffic Laravel SaaS applications requiring sub-100ms API response times
- [2]E-commerce platforms with heavy database operations and real-time inventory updates
- [3]Content management systems serving thousands of concurrent users
- [4]API backends for mobile applications with strict performance requirements
- [5]Multi-tenant Laravel applications with complex queue processing workflows
- [6]Enterprise web applications requiring 99.9% uptime and horizontal scalability
- [7]Laravel applications with heavy background job processing and scheduled tasks
[!]Prerequisites
- [!]Minimum 4GB RAM (2GB for MySQL, 1GB for Redis, 1GB for Laravel containers)
- [!]Docker Engine 20.10+ and Docker Compose v2 for multi-container orchestration
- [!]Generated Laravel APP_KEY and secure MySQL passwords in .env file
- [!]SSL certificates for NGINX HTTPS configuration (Let's Encrypt recommended)
- [!]Understanding of Laravel Octane limitations and stateful application considerations
- [!]Experience with Laravel queue workers and Horizon configuration
[!]
WARNING: For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
[$]docker-compose.yml
[docker-compose.yml]
1services: 2 mysql: 3 image: mysql:8.04 environment: 5 - MYSQL_DATABASE=laravel6 - MYSQL_USER=laravel7 - MYSQL_PASSWORD=${MYSQL_PASSWORD}8 - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}9 volumes: 10 - mysql_data:/var/lib/mysql11 networks: 12 - laravel_net1314 redis: 15 image: redis:7-alpine16 volumes: 17 - redis_data:/data18 networks: 19 - laravel_net2021 laravel: 22 build: 23 context: .24 dockerfile: Dockerfile25 command: php artisan octane:start --server=swoole --host=0.0.0.0 --port=800026 environment: 27 - APP_ENV=production28 - APP_KEY=${APP_KEY}29 - DB_CONNECTION=mysql30 - DB_HOST=mysql31 - DB_DATABASE=laravel32 - DB_USERNAME=laravel33 - DB_PASSWORD=${MYSQL_PASSWORD}34 - REDIS_HOST=redis35 - CACHE_DRIVER=redis36 - QUEUE_CONNECTION=redis37 - SESSION_DRIVER=redis38 volumes: 39 - laravel_storage:/app/storage40 depends_on: 41 - mysql42 - redis43 networks: 44 - laravel_net4546 horizon: 47 build: 48 context: .49 dockerfile: Dockerfile50 command: php artisan horizon51 environment: 52 - APP_ENV=production53 - APP_KEY=${APP_KEY}54 - DB_CONNECTION=mysql55 - DB_HOST=mysql56 - DB_DATABASE=laravel57 - DB_USERNAME=laravel58 - DB_PASSWORD=${MYSQL_PASSWORD}59 - REDIS_HOST=redis60 depends_on: 61 - mysql62 - redis63 networks: 64 - laravel_net6566 scheduler: 67 build: 68 context: .69 dockerfile: Dockerfile70 command: sh -c "while true; do php artisan schedule:run; sleep 60; done"71 environment: 72 - APP_ENV=production73 - APP_KEY=${APP_KEY}74 - DB_CONNECTION=mysql75 - DB_HOST=mysql76 - DB_DATABASE=laravel77 - DB_USERNAME=laravel78 - DB_PASSWORD=${MYSQL_PASSWORD}79 - REDIS_HOST=redis80 depends_on: 81 - mysql82 - redis83 networks: 84 - laravel_net8586 nginx: 87 image: nginx:alpine88 ports: 89 - "80:80"90 - "443:443"91 volumes: 92 - ./nginx.conf:/etc/nginx/nginx.conf:ro93 depends_on: 94 - laravel95 networks: 96 - laravel_net9798volumes: 99 mysql_data: 100 redis_data: 101 laravel_storage: 102103networks: 104 laravel_net: [$].env Template
[.env]
1# Laravel Production2MYSQL_PASSWORD=secure_mysql_password3MYSQL_ROOT_PASSWORD=secure_root_password4APP_KEY=base64:your_app_key_here56# Laravel at http://localhost7# Horizon dashboard at /horizon[i]Usage Notes
- [1]Laravel at http://localhost
- [2]Horizon dashboard at /horizon
- [3]Octane with Swoole for performance
- [4]Run migrations before start
- [5]Configure APP_KEY properly
Individual Services(6 services)
Copy individual services to mix and match with your existing compose files.
mysql
mysql:
image: mysql:8.0
environment:
- MYSQL_DATABASE=laravel
- MYSQL_USER=laravel
- MYSQL_PASSWORD=${MYSQL_PASSWORD}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
networks:
- laravel_net
redis
redis:
image: redis:7-alpine
volumes:
- redis_data:/data
networks:
- laravel_net
laravel
laravel:
build:
context: .
dockerfile: Dockerfile
command: php artisan octane:start --server=swoole --host=0.0.0.0 --port=8000
environment:
- APP_ENV=production
- APP_KEY=${APP_KEY}
- DB_CONNECTION=mysql
- DB_HOST=mysql
- DB_DATABASE=laravel
- DB_USERNAME=laravel
- DB_PASSWORD=${MYSQL_PASSWORD}
- REDIS_HOST=redis
- CACHE_DRIVER=redis
- QUEUE_CONNECTION=redis
- SESSION_DRIVER=redis
volumes:
- laravel_storage:/app/storage
depends_on:
- mysql
- redis
networks:
- laravel_net
horizon
horizon:
build:
context: .
dockerfile: Dockerfile
command: php artisan horizon
environment:
- APP_ENV=production
- APP_KEY=${APP_KEY}
- DB_CONNECTION=mysql
- DB_HOST=mysql
- DB_DATABASE=laravel
- DB_USERNAME=laravel
- DB_PASSWORD=${MYSQL_PASSWORD}
- REDIS_HOST=redis
depends_on:
- mysql
- redis
networks:
- laravel_net
scheduler
scheduler:
build:
context: .
dockerfile: Dockerfile
command: sh -c "while true; do php artisan schedule:run; sleep 60; done"
environment:
- APP_ENV=production
- APP_KEY=${APP_KEY}
- DB_CONNECTION=mysql
- DB_HOST=mysql
- DB_DATABASE=laravel
- DB_USERNAME=laravel
- DB_PASSWORD=${MYSQL_PASSWORD}
- REDIS_HOST=redis
depends_on:
- mysql
- redis
networks:
- laravel_net
nginx
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- laravel
networks:
- laravel_net
[>]Quick Start
[terminal]
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 mysql:5 image: mysql:8.06 environment:7 - MYSQL_DATABASE=laravel8 - MYSQL_USER=laravel9 - MYSQL_PASSWORD=${MYSQL_PASSWORD}10 - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}11 volumes:12 - mysql_data:/var/lib/mysql13 networks:14 - laravel_net1516 redis:17 image: redis:7-alpine18 volumes:19 - redis_data:/data20 networks:21 - laravel_net2223 laravel:24 build:25 context: .26 dockerfile: Dockerfile27 command: php artisan octane:start --server=swoole --host=0.0.0.0 --port=800028 environment:29 - APP_ENV=production30 - APP_KEY=${APP_KEY}31 - DB_CONNECTION=mysql32 - DB_HOST=mysql33 - DB_DATABASE=laravel34 - DB_USERNAME=laravel35 - DB_PASSWORD=${MYSQL_PASSWORD}36 - REDIS_HOST=redis37 - CACHE_DRIVER=redis38 - QUEUE_CONNECTION=redis39 - SESSION_DRIVER=redis40 volumes:41 - laravel_storage:/app/storage42 depends_on:43 - mysql44 - redis45 networks:46 - laravel_net4748 horizon:49 build:50 context: .51 dockerfile: Dockerfile52 command: php artisan horizon53 environment:54 - APP_ENV=production55 - APP_KEY=${APP_KEY}56 - DB_CONNECTION=mysql57 - DB_HOST=mysql58 - DB_DATABASE=laravel59 - DB_USERNAME=laravel60 - DB_PASSWORD=${MYSQL_PASSWORD}61 - REDIS_HOST=redis62 depends_on:63 - mysql64 - redis65 networks:66 - laravel_net6768 scheduler:69 build:70 context: .71 dockerfile: Dockerfile72 command: sh -c "while true; do php artisan schedule:run; sleep 60; done"73 environment:74 - APP_ENV=production75 - APP_KEY=${APP_KEY}76 - DB_CONNECTION=mysql77 - DB_HOST=mysql78 - DB_DATABASE=laravel79 - DB_USERNAME=laravel80 - DB_PASSWORD=${MYSQL_PASSWORD}81 - REDIS_HOST=redis82 depends_on:83 - mysql84 - redis85 networks:86 - laravel_net8788 nginx:89 image: nginx:alpine90 ports:91 - "80:80"92 - "443:443"93 volumes:94 - ./nginx.conf:/etc/nginx/nginx.conf:ro95 depends_on:96 - laravel97 networks:98 - laravel_net99100volumes:101 mysql_data:102 redis_data:103 laravel_storage:104105networks:106 laravel_net:107EOF108109# 2. Create the .env file110cat > .env << 'EOF'111# Laravel Production112MYSQL_PASSWORD=secure_mysql_password113MYSQL_ROOT_PASSWORD=secure_root_password114APP_KEY=base64:your_app_key_here115116# Laravel at http://localhost117# Horizon dashboard at /horizon118EOF119120# 3. Start the services121docker compose up -d122123# 4. View logs124docker compose logs -f[>]One-Liner
Run this command to download and set up the recipe in one step:
[terminal]
1curl -fsSL https://docker.recipes/api/recipes/laravel-production/run | bash[?]Troubleshooting
- [!]Octane memory leaks with static variables: Restart Octane workers periodically using OCTANE_WATCH=true
- [!]Horizon workers not processing jobs: Check Redis connection and run 'php artisan horizon:terminate' to restart
- [!]MySQL connection refused errors: Verify MYSQL_PASSWORD environment variable matches across all Laravel services
- [!]NGINX 502 Bad Gateway: Ensure Laravel Octane is binding to 0.0.0.0:8000, not localhost
- [!]Laravel sessions not persisting: Confirm SESSION_DRIVER=redis and REDIS_HOST=redis in environment
- [!]Scheduler not executing: Check that cron jobs are running every minute and APP_KEY is properly set
Community Notes
Loading...
Loading notes...
## Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
## Components
laraveloctanehorizonmysqlredisnginx
## Tags
#laravel#php#octane#horizon#production
## Category
Full Web StacksShortcuts: C CopyF FavoriteD Download