Linux Server Setup
Server Requirements
# Minimum requirements
RAM: 4GB (8GB+ recommended)
CPU: 2 cores (4+ recommended)
Disk: 80GB SSD (200GB+ recommended)
OS: Ubuntu 22.04 LTS or CentOS 8
Initial Server Setup
# Update system
sudo apt update && sudo apt upgrade -y
# Install essential packages
sudo apt install -y curl wget git unzip software-properties-common
# Create deploy user
sudo adduser deploy
sudo usermod -aG sudo deploy
# Setup SSH key
sudo mkdir -p /home/deploy/.ssh
sudo cp ~/.ssh/authorized_keys /home/deploy/.ssh/
sudo chown -R deploy:deploy /home/deploy/.ssh
sudo chmod 700 /home/deploy/.ssh
sudo chmod 600 /home/deploy/.ssh/authorized_keys
# Firewall setup
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
Install Nginx
# Install Nginx
sudo apt install -y nginx
# Start and enable
sudo systemctl start nginx
sudo systemctl enable nginx
# Verify
sudo systemctl status nginx
curl http://localhost
Install PHP-FPM
# Install PHP 8.1 and extensions
sudo apt install -y php8.1-fpm php8.1-cli php8.1-mysql \
php8.1-xml php8.1-mbstring php8.1-intl php8.1-gd \
php8.1-curl php8.1-zip php8.1-redis php8.1-bcmath
# Start PHP-FPM
sudo systemctl start php8.1-fpm
sudo systemctl enable php8.1-fpm
Install MySQL
# Install MySQL 8
sudo apt install -y mysql-server
# Secure installation
sudo mysql_secure_installation
# Create Magento database
sudo mysql -u root -p
CREATE DATABASE magento_db;
CREATE USER 'magento'@'localhost' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON magento_db.* TO 'magento'@'localhost';
FLUSH PRIVILEGES;
Install Redis
# Install Redis
sudo apt install -y redis-server
# Configure Redis
sudo sed -i 's/maxmemory .*/maxmemory 1GB/' /etc/redis/redis.conf
sudo sed -i 's/maxmemory-policy .*/maxmemory-policy allkeys-lru/' /etc/redis/redis.conf
# Restart
sudo systemctl restart redis-server
Key Takeaway
Linux server setup: update system, install Nginx, PHP-FPM, MySQL, Redis. Create deploy user with SSH access and configure firewall.
Nginx Configuration for Magento
Basic Nginx Configuration
# /etc/nginx/sites-available/magento
server {
listen 80;
server_name www.example.com;
root /var/www/magento/pub;
index index.php;
# Logs
access_log /var/log/nginx/magento-access.log;
error_log /var/log/nginx/magento-error.log;
# Max body size for uploads
client_max_body_size 100M;
# PHP-FPM
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# Timeout settings
fastcgi_read_timeout 300s;
fastcgi_send_timeout 300s;
}
# Static files
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
# Deny access to sensitive files
location ~ /\. {
deny all;
}
}
Magento-Specific Configuration
# /etc/nginx/sites-available/magento
server {
listen 80;
server_name www.example.com;
root /var/www/magento/pub;
index index.php;
# Magento rewrites
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
# API endpoints
location /rest/ {
try_files $uri $uri/ /index.php$is_args$args;
}
# Static assets
location /static/ {
expires 1y;
add_header Cache-Control "public";
try_files $uri $uri/ =404;
}
# Media files
location /media/ {
expires 1y;
add_header Cache-Control "public";
try_files $uri $uri/ =404;
}
# PHP processing
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# Magento specific
fastcgi_param MAGE_MODE production;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
}
Enable Site
# Create symlink
sudo ln -s /etc/nginx/sites-available/magento /etc/nginx/sites-enabled/
# Remove default site
sudo rm /etc/nginx/sites-enabled/default
# Test configuration
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
Key Takeaway
Nginx configuration for Magento: set root to pub/, configure PHP-FPM, handle rewrites for routing, and add security headers.
Performance Tuning
Nginx Performance
# /etc/nginx/nginx.conf
worker_processes auto;
worker_rlimit_nofile 65535;
events {
worker_connections 4096;
multi_accept on;
use epoll;
}
http {
# Basic settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# Buffering
client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 100m;
large_client_header_buffers 4 8k;
# Gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript \
application/json application/javascript application/xml+rss \
application/atom+xml image/svg+xml;
# Open file cache
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
}
Connection Tuning
# Upstream configuration
upstream php-fpm {
server unix:/var/run/php/php8.1-fpm.sock;
keepalive 32;
}
# FastCGI tuning
location ~ \.php$ {
fastcgi_pass php-fpm;
fastcgi_buffer_size 128k;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_read_timeout 300s;
fastcgi_send_timeout 300s;
}
Static File Optimization
# Static files with long cache
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public";
access_log off;
# Enable gzip for static
gzip_static on;
# Enable brotli if available
brotli_static on;
}
Rate Limiting
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
# API rate limiting
location /rest/ {
limit_req zone=api burst=20 nodelay;
try_files $uri $uri/ /index.php$is_args$args;
}
# Login rate limiting
location /customer/account/login/ {
limit_req zone=login burst=3 nodelay;
try_files $uri $uri/ /index.php$is_args$args;
}
Key Takeaway
Performance tuning: enable gzip, tune worker connections, configure fastcgi buffering, enable static file caching, and implement rate limiting.
Virtual Hosts and Security
Multiple Sites Virtual Hosts
# Site 1: www.store1.com
server {
listen 80;
server_name www.store1.com;
root /var/www/store1/pub;
# ... configuration ...
}
# Site 2: www.store2.com
server {
listen 80;
server_name www.store2.com;
root /var/www/store2/pub;
# ... configuration ...
}
SSL Configuration
server {
listen 443 ssl http2;
server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/www.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name www.example.com;
return 301 https://$host$request_uri;
}
Security Hardening
# Hide Nginx version
server_tokens off;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self' https: http:" always;
# Deny access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Deny access to sensitive files
location ~* \.(env|htaccess|htpasswd|ini|log|sh|sql)$ {
deny all;
}
# Block access to app directory
location /app/ {
deny all;
}
location /app/etc/ {
deny all;
}
location /lib/ {
deny all;
}
location /pkginfo/ {
deny all;
}
location /var/ {
deny all;
}
location /vendor/ {
deny all;
}
Enable SSL with Let's Encrypt
# Install Certbot
sudo apt install -y certbot python3-certbot-nginx
# Get certificate
sudo certbot --nginx -d www.example.com
# Auto-renewal
sudo systemctl status certbot.timer
# Test renewal
sudo certbot renew --dry-run
Key Takeaway
Virtual hosts enable multiple sites on one server. SSL with Let's Encrypt provides free certificates. Security hardening hides version, blocks sensitive files, and adds security headers.
Quiz
1. What is the Magento root directory in Nginx?
2. What does fastcgi_pass do in Nginx?
3. Why enable gzip in Nginx?
4. What does server_tokens off do?
5. Why use worker_processes auto?
Flashcards
Question
What is the Magento Nginx root?
Click to reveal answer
Answer
/var/www/magento/pub - Magento serves from the pub/ directory
Question
What does fastcgi_pass do?
Click to reveal answer
Answer
Directs PHP requests to PHP-FPM for processing
Question
Why enable gzip?
Click to reveal answer
Answer
Compresses responses to reduce bandwidth and improve load times
Question
What is server_tokens off?
Click to reveal answer
Answer
Hides Nginx version in response headers for security
Question
What does try_files do?
Click to reveal answer
Answer
Checks if files exist, falls back to index.php for Magento routing
Question
Why use keepalive in Nginx?
Click to reveal answer
Answer
Reuses connections to PHP-FPM for better performance
Question
What is rate limiting?
Click to reveal answer
Answer
Limits requests per second from a client to prevent abuse
Question
How to enable SSL with Let's Encrypt?
Click to reveal answer
Answer
certbot --nginx -d domain.com for free SSL certificates
Revision Notes
Key Takeaways
- 1. Magento root in Nginx is /var/www/magento/pub
- 2. Use try_files for Magento routing
- 3. Enable gzip, keepalive, and static file caching
- 4. Add security headers and hide server version
- 5. Use Let's Encrypt for free SSL certificates
Interview Tips
- • Explain Nginx configuration for Magento
- • Discuss performance tuning techniques
- • Describe security hardening measures
- • Explain virtual host setup for multiple sites
Cheat Sheet
Nginx for Magento
Root: /var/www/magento/pub
PHP: fastcgi_pass to PHP-FPM socket
Routing: try_files $uri $uri/ /index.php$is_args$args
Performance:
- gzip on
- keepalive 32
- worker_processes auto
- open_file_cache
Security:
- server_tokens off
- Security headers
- Block /app/, /var/, /vendor/
SSL:
certbot --nginx -d domain.com