How To Install LEMP Stack on Debian 13
The LEMP stack represents one of the most powerful and efficient web development environments available today. This comprehensive stack combines Linux, Nginx (Engine-X), MariaDB/MySQL, and PHP to create a robust foundation for hosting dynamic websites and web applications. Unlike the traditional LAMP stack that uses Apache, LEMP leverages Nginx’s superior performance characteristics, making it ideal for high-traffic websites and resource-constrained servers.
Debian 13 (codenamed “Trixie”) provides an excellent foundation for LEMP stack deployment, offering stability, security, and up-to-date packages. This guide will walk you through the complete installation process, from initial system preparation to final testing and optimization. Whether you’re a system administrator, web developer, or hosting provider, this tutorial will help you build a production-ready LEMP environment that can handle modern web applications efficiently.
Prerequisites and System Requirements
Before beginning the LEMP stack installation on Debian 13, ensure your system meets the minimum requirements for optimal performance. Your server should have at least 2GB of RAM, 2 CPU cores, and 20GB of available storage space. These specifications provide adequate resources for a basic web hosting environment while allowing room for growth.
Access to a fresh Debian 13 installation with root privileges or a user account with sudo access is essential. The server should have a stable internet connection for downloading packages and updates. If you plan to host live websites, consider configuring a domain name with appropriate DNS records pointing to your server’s IP address.
Essential system packages including curl, wget, and gnupg should be available for the installation process. Most Debian 13 installations include these by default, but we’ll verify their presence during the initial system update phase.
Updating Debian 13 System
System updates form the foundation of a secure LEMP installation. Begin by updating the package repositories to ensure access to the latest software versions:
sudo apt update && sudo apt upgrade -y
This command refreshes the package database and installs any available security updates. The process may take several minutes depending on your internet connection and the number of packages requiring updates.
Install essential development tools and utilities that will be needed throughout the LEMP installation:
sudo apt install curl wget gnupg2 software-properties-common apt-transport-https -y
Verify your Debian version to ensure compatibility with the installation procedures:
lsb_release -a
Installing and Configuring Nginx Web Server
Installation Process
Nginx installation on Debian 13 is straightforward using the default package repositories. The included version provides excellent stability and performance for most use cases:
sudo apt install nginx -y
Verify the installation by checking the Nginx version:
nginx -v
This should display the installed Nginx version, confirming successful installation. Enable Nginx to start automatically at system boot:
sudo systemctl enable nginx
sudo systemctl start nginx
Check the service status to ensure Nginx is running correctly:
sudo systemctl status nginx
The output should show “active (running)” status, indicating that Nginx is operational and ready to serve web content.
Initial Configuration
Configure the system firewall to allow web traffic through HTTP and HTTPS ports. If using UFW (Uncomplicated Firewall), execute these commands:
sudo ufw allow 'Nginx Full'
sudo ufw enable
Test the default Nginx installation by accessing your server’s IP address in a web browser. You should see the default Nginx welcome page, confirming that the web server is responding to requests properly.
Create a backup of the default Nginx configuration before making modifications:
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.backup
Security Hardening
Enhance Nginx security by hiding version information from HTTP headers. Edit the main configuration file:
sudo nano /etc/nginx/nginx.conf
Add the following directive within the http block:
server_tokens off;
Set appropriate file permissions for Nginx configuration files:
sudo chmod 640 /etc/nginx/nginx.conf
sudo chown root:root /etc/nginx/nginx.conf
These security measures help protect your server from information disclosure and unauthorized access attempts.
Installing and Securing MariaDB Database Server
MariaDB Installation
MariaDB serves as the database component of the LEMP stack, offering enhanced performance and features compared to traditional MySQL. Install MariaDB server using the default Debian repositories:
sudo apt install mariadb-server mariadb-client -y
Start and enable the MariaDB service for automatic startup:
sudo systemctl start mariadb
sudo systemctl enable mariadb
Verify that MariaDB is running correctly:
sudo systemctl status mariadb
Check the installed MariaDB version:
mysql --version
Database Security Configuration
Secure your MariaDB installation by running the security script or performing manual security hardening. Connect to MariaDB as the root user:
sudo mysql -u root
Set a strong password for the root user:
ALTER USER 'root'@'localhost' IDENTIFIED BY 'your_strong_password';
Remove anonymous users that could pose security risks:
DELETE FROM mysql.user WHERE User='';
Disable remote root login for enhanced security:
DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1', '::1');
Remove the test database and associated privileges:
DROP DATABASE IF EXISTS test;
DELETE FROM mysql.db WHERE Db='test' OR Db='test\\_%';
Flush privileges to apply all changes:
FLUSH PRIVILEGES;
EXIT;
Create a dedicated database user for web applications:
sudo mysql -u root -p
CREATE DATABASE example_database;
CREATE USER 'example_user'@'localhost' IDENTIFIED BY 'secure_password';
GRANT ALL PRIVILEGES ON example_database.* TO 'example_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Basic Database Management
Configure MariaDB for optimal performance by editing the main configuration file:
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
Add performance-oriented settings under the [mysqld] section:
innodb_buffer_pool_size = 512M
innodb_log_file_size = 128M
max_connections = 200
query_cache_limit = 2M
query_cache_size = 64M
Restart MariaDB to apply the configuration changes:
sudo systemctl restart mariadb
Installing and Configuring PHP 8.4 with PHP-FPM
PHP and PHP-FPM Installation
PHP-FPM (FastCGI Process Manager) provides superior performance when integrated with Nginx compared to traditional mod_php. Install PHP 8.4 and essential extensions:
sudo apt install php8.4-fpm php8.4-mysql php8.4-curl php8.4-gd php8.4-mbstring php8.4-xml php8.4-zip php8.4-opcache php8.4-json php8.4-cli -y
Start and enable PHP-FPM service:
sudo systemctl start php8.4-fpm
sudo systemctl enable php8.4-fpm
Verify PHP-FPM is running:
sudo systemctl status php8.4-fpm
Check the installed PHP version and loaded modules:
php -v
php -m
PHP-FPM Configuration Optimization
Optimize PHP-FPM performance by editing the pool configuration file:
sudo nano /etc/php/8.4/fpm/pool.d/www.conf
Configure process management settings for optimal resource utilization:
pm = dynamic
pm.max_children = 20
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 8
pm.process_idle_timeout = 10s
pm.max_requests = 500
Edit the main PHP configuration for security and performance:
sudo nano /etc/php/8.4/fpm/php.ini
Apply these security-focused settings:
cgi.fix_pathinfo = 0
expose_php = Off
max_execution_time = 300
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
Restart PHP-FPM to apply configuration changes:
sudo systemctl restart php8.4-fpm
Integration with Nginx
Configure Nginx to process PHP files through PHP-FPM by creating a new server block:
sudo nano /etc/nginx/sites-available/default
Replace the default configuration with this optimized setup:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html index.htm;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
Test the Nginx configuration for syntax errors:
sudo nginx -t
Reload Nginx to apply the new configuration:
sudo systemctl reload nginx
Integrating Components and Configuration
Nginx Virtual Host Setup
Create a more comprehensive server block configuration for production use. Generate a new site configuration:
sudo nano /etc/nginx/sites-available/example.com
Configure a robust virtual host with security headers and performance optimizations:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com;
index index.php index.html index.htm;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
# Gzip compression
gzip on;
gzip_vary on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/run/php/php8.4-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Enable the site by creating a symbolic link:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Create the document root directory:
sudo mkdir -p /var/www/example.com
Testing LEMP Stack Integration
Create a PHP information page to test the complete integration:
echo "" | sudo tee /var/www/html/info.php
Set appropriate ownership and permissions:
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html
Create a database connection test script:
sudo nano /var/www/html/dbtest.php
Add this PHP database connection test:
<?php
$servername = "localhost";
$username = "example_user";
$password = "secure_password";
$dbname = "example_database";
try {
$pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Database connection successful!";
} catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
?>
Access these test pages through your web browser using your server’s IP address or domain name followed by /info.php
and /dbtest.php
.
File Permissions and Ownership
Establish proper file permissions for security and functionality:
sudo chown -R www-data:www-data /var/www
sudo find /var/www -type d -exec chmod 755 {} \;
sudo find /var/www -type f -exec chmod 644 {} \;
Secure sensitive configuration files:
sudo chmod 600 /etc/php/8.4/fpm/pool.d/www.conf
sudo chmod 600 /etc/mysql/mariadb.conf.d/50-server.cnf
Security Best Practices
Firewall Configuration
Configure UFW to allow only necessary network traffic:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw enable
Application Security
Implement additional security measures for your LEMP stack components. Configure fail2ban to protect against brute force attacks:
sudo apt install fail2ban -y
Create a custom jail configuration:
sudo nano /etc/fail2ban/jail.local
Add these security rules:
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 3
[sshd]
enabled = true
[nginx-http-auth]
enabled = true
[nginx-noscript]
enabled = true
System Security
Enable automatic security updates for critical packages:
sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure -plow unattended-upgrades
Configure log rotation for web server logs:
sudo nano /etc/logrotate.d/nginx
Implement regular backup procedures for your databases and web content using automated scripts.
Performance Optimization
Nginx Performance Tuning
Optimize Nginx worker processes and connections:
sudo nano /etc/nginx/nginx.conf
Configure performance settings in the main configuration:
worker_processes auto;
worker_connections 1024;
keepalive_timeout 65;
client_max_body_size 64M;
PHP-FPM Performance
Enable and configure PHP OPCache for improved performance:
sudo nano /etc/php/8.4/fpm/conf.d/10-opcache.ini
Add these OPCache settings:
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=4000
opcache.revalidate_freq=2
MariaDB Optimization
Fine-tune MariaDB configuration for better performance:
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
Add these performance optimizations:
innodb_buffer_pool_size = 1G
innodb_log_buffer_size = 32M
innodb_flush_log_at_trx_commit = 2
query_cache_size = 128M
Troubleshooting Common Issues
Address frequent installation and configuration problems that may arise during LEMP stack setup. Service startup failures often result from configuration syntax errors or permission issues. Always verify configuration file syntax using built-in testing commands before restarting services.
Permission-related errors typically occur when web files have incorrect ownership or access rights. Ensure the www-data user can read web content and PHP-FPM can access socket files properly. Check error logs located in /var/log/nginx/
and /var/log/php8.4-fpm.log
for detailed diagnostic information.
Database connection issues may stem from incorrect credentials, firewall restrictions, or service connectivity problems. Verify MariaDB is running and accepting connections on the localhost interface. Test database connectivity using command-line tools before troubleshooting PHP applications.
Maintenance and Monitoring
Establish regular maintenance procedures to keep your LEMP stack secure and performant. Schedule weekly system updates and security patches using automated tools or cron jobs. Monitor system resources including CPU usage, memory consumption, and disk space to identify potential performance bottlenecks.
Configure log monitoring to track unusual access patterns, error rates, and security incidents. Implement automated backup solutions for databases and web content, storing backups in secure off-site locations. Create system health check scripts to verify service availability and performance metrics regularly.
Advanced Configuration Options
Explore advanced LEMP stack features for enhanced functionality and performance. Multiple PHP version support allows testing applications with different PHP releases simultaneously. SSL certificate integration using Let’s Encrypt provides encrypted HTTPS connections for improved security and SEO rankings.
Consider implementing advanced Nginx modules like nginx-extras for additional functionality such as real-time image resizing or geographic IP restrictions. Database clustering and replication can provide high availability and improved performance for high-traffic applications.
Congratulations! You have successfully installed LEMP. Thanks for using this tutorial to install the latest version of the LEMP Stack on Debian 13 “Trixie” system. For additional help or useful information, we recommend you check the official Debian website.