LEMP Stack
Classic Linux, NGINX, MySQL, PHP stack for hosting PHP applications.
Overview
NGINX is a high-performance web server and reverse proxy server that has become the backbone of modern web infrastructure, powering over 400 million websites worldwide. Originally developed by Igor Sysoev to solve the C10K problem (handling 10,000 concurrent connections), NGINX uses an event-driven, asynchronous architecture that dramatically outperforms traditional process-based servers under high load conditions. Its lightweight footprint and efficient resource utilization make it ideal for serving static content, handling SSL termination, and proxying requests to backend applications.
The LEMP stack combines NGINX's superior performance characteristics with MySQL's proven relational database capabilities and PHP-FPM's optimized process management for PHP applications. This configuration creates a highly efficient web application platform where NGINX handles incoming HTTP requests and serves static files directly, while forwarding PHP requests to the PHP-FPM process manager through FastCGI protocol. MySQL provides robust ACID-compliant data storage with InnoDB's advanced transaction support, making this stack particularly effective for database-driven web applications that require both speed and reliability.
This stack is ideal for developers migrating from traditional LAMP setups who need better performance, system administrators managing high-traffic PHP applications, and businesses running content management systems like WordPress or Drupal in production environments. The combination offers significant advantages over Apache-based stacks, including lower memory consumption, better concurrent connection handling, and superior static file serving performance, while maintaining full compatibility with existing PHP applications.
Key Features
- Event-driven, asynchronous NGINX architecture for handling thousands of concurrent connections with minimal memory usage
- PHP-FPM process manager with adaptive process spawning and built-in opcode caching support
- MySQL InnoDB storage engine with ACID compliance and row-level locking for high-concurrency applications
- FastCGI protocol integration between NGINX and PHP-FPM for efficient request processing
- NGINX reverse proxy capabilities with built-in load balancing algorithms and health checks
- MySQL Query Cache and full-text search capabilities for optimized database performance
- HTTP/2 support in NGINX for improved page load times and resource multiplexing
- PHP 8.3 JIT compilation and improved type system for enhanced application performance
Common Use Cases
- 1High-traffic WordPress or Drupal websites requiring better performance than traditional Apache setups
- 2E-commerce platforms built with PHP frameworks like Laravel, Symfony, or CodeIgniter
- 3Content management systems serving static assets and dynamic PHP content simultaneously
- 4Development environments for PHP applications that mirror production LEMP deployments
- 5Multi-tenant SaaS applications requiring efficient resource utilization and database isolation
- 6API backends for mobile applications using PHP frameworks with MySQL data persistence
- 7Legacy LAMP stack migrations seeking improved performance without application code changes
Prerequisites
- Minimum 1.5GB RAM available (256MB for NGINX, 512MB for PHP-FPM, 1GB for MySQL)
- Docker Engine 20.10+ and Docker Compose V2 for proper networking and volume support
- Port 80 available on host system for NGINX web server access
- Basic understanding of PHP-FPM configuration and FastCGI protocol for optimization
- Familiarity with NGINX server blocks and location directives for custom routing
- Knowledge of MySQL user management and database security practices
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 nginx: 3 image: nginx:alpine4 container_name: nginx5 restart: unless-stopped6 volumes: 7 - ./src:/var/www/html8 - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro9 ports: 10 - "80:80"11 depends_on: 12 - php13 networks: 14 - lemp1516 php: 17 image: php:8.3-fpm-alpine18 container_name: php19 restart: unless-stopped20 volumes: 21 - ./src:/var/www/html22 networks: 23 - lemp2425 mysql: 26 image: mysql:8.027 container_name: mysql28 restart: unless-stopped29 environment: 30 MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}31 MYSQL_DATABASE: ${MYSQL_DATABASE}32 MYSQL_USER: ${MYSQL_USER}33 MYSQL_PASSWORD: ${MYSQL_PASSWORD}34 volumes: 35 - mysql_data:/var/lib/mysql36 networks: 37 - lemp3839volumes: 40 mysql_data: 4142networks: 43 lemp: 44 driver: bridge.env Template
.env
1# MySQL Configuration2MYSQL_ROOT_PASSWORD=rootpassword3MYSQL_DATABASE=myapp4MYSQL_USER=appuser5MYSQL_PASSWORD=changemeUsage Notes
- 1Place PHP files in ./src directory
- 2Create nginx/default.conf with PHP-FPM config (fastcgi_pass php:9000)
- 3Access at http://localhost
- 4PHP connects to MySQL: host=mysql, port=3306
- 5Install PHP extensions: docker-compose exec php docker-php-ext-install pdo_mysql
- 6Classic LAMP alternative using NGINX instead of Apache
Individual Services(3 services)
Copy individual services to mix and match with your existing compose files.
nginx
nginx:
image: nginx:alpine
container_name: nginx
restart: unless-stopped
volumes:
- ./src:/var/www/html
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
ports:
- "80:80"
depends_on:
- php
networks:
- lemp
php
php:
image: php:8.3-fpm-alpine
container_name: php
restart: unless-stopped
volumes:
- ./src:/var/www/html
networks:
- lemp
mysql
mysql:
image: mysql:8.0
container_name: mysql
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
volumes:
- mysql_data:/var/lib/mysql
networks:
- lemp
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 nginx:5 image: nginx:alpine6 container_name: nginx7 restart: unless-stopped8 volumes:9 - ./src:/var/www/html10 - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro11 ports:12 - "80:80"13 depends_on:14 - php15 networks:16 - lemp1718 php:19 image: php:8.3-fpm-alpine20 container_name: php21 restart: unless-stopped22 volumes:23 - ./src:/var/www/html24 networks:25 - lemp2627 mysql:28 image: mysql:8.029 container_name: mysql30 restart: unless-stopped31 environment:32 MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}33 MYSQL_DATABASE: ${MYSQL_DATABASE}34 MYSQL_USER: ${MYSQL_USER}35 MYSQL_PASSWORD: ${MYSQL_PASSWORD}36 volumes:37 - mysql_data:/var/lib/mysql38 networks:39 - lemp4041volumes:42 mysql_data:4344networks:45 lemp:46 driver: bridge47EOF4849# 2. Create the .env file50cat > .env << 'EOF'51# MySQL Configuration52MYSQL_ROOT_PASSWORD=rootpassword53MYSQL_DATABASE=myapp54MYSQL_USER=appuser55MYSQL_PASSWORD=changeme56EOF5758# 3. Start the services59docker compose up -d6061# 4. View logs62docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/lemp-stack/run | bashTroubleshooting
- 502 Bad Gateway errors: Ensure PHP-FPM container is running and NGINX default.conf has correct fastcgi_pass php:9000 directive
- PHP extensions missing (like pdo_mysql): Run docker-compose exec php docker-php-ext-install pdo_mysql mysqli to install database connectors
- File permission errors in PHP: Check that ./src directory has proper ownership and PHP-FPM can read/write files with correct user mapping
- MySQL connection refused from PHP: Verify database host is set to 'mysql' (container name) not 'localhost' in PHP database configuration
- NGINX fails to start with port binding error: Ensure no other web server is using port 80 or modify port mapping in docker-compose.yml
- Slow MySQL queries on first startup: Allow time for MySQL 8.0 initialization and consider using mysql:8.0 specific configuration optimizations
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
Ad Space
Shortcuts: C CopyF FavoriteD Download