Magento 2 Instaleation and Optimization

Magento 2 is an enterprise-grade e-commerce platform offering advanced features for complex product catalogs, multi-store operations, and sophisticated customer management. Instaleation requires careful preparation and understanding of dependencies. This comprehensive guide covers production-ready Magento 2 setup including Composer-based installation, Elasticsearch integration, Redis caching, Varnish reverse proxy caching, PHP-FPM tuning, background job processing with Cron, and production deployment strategies.

Tabla de contenidos

Requisitos del sistema and Prerequisites

Magento 2 is resource-intensive and requires modern infrastructure. Minimum VPS specifications should include 8GB RAM, 4 CPU cores, 50GB SSD storage, and modern PHP 8.1+.

Verifique system requirements:

# Check PHP version (8.1+ required)
php -v

# Check available memory
free -h

# Check disk space
df -h /

# Verify CPU cores
nproc

Actualice los paquetes del sistema:

sudo apt update
sudo apt upgrade -y
sudo apt install curl wget git zip unzip vim htop -y

Cree a Magento system user:

# Create dedicated user for security
sudo useradd -m -s /bin/bash magento
sudo usermod -aG www-data magento

# Create web root
sudo mkdir -p /var/www/magento
sudo chown -R magento:www-data /var/www/magento

LEMP Stack Instaleation

Magento 2 requires Linux, Nginx, MySQL/MariaDB, and PHP with specific extensions.

Instale Nginx:

sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx
sudo systemctl status nginx

Instale MariaDB:

sudo apt install mariadb-server mariadb-client -y
sudo systemctl start mariadb
sudo systemctl enable mariadb
sudo mysql_secure_installation

# Create Magento database
sudo mysql -u root -p << EOF
CREATE DATABASE magento;
CREATE USER 'magento'@'localhost' IDENTIFIED BY 'SecurePassword123!';
GRANT ALL PRIVILEGES ON magento.* TO 'magento'@'localhost';
FLUSH PRIVILEGES;
EXIT;
EOF

Instale PHP 8.2 with required extensions:

# Add PHP repository
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:ondrej/php -y
sudo apt update

# Install PHP and extensions
sudo apt install php8.2 php8.2-fpm php8.2-mysql php8.2-json php8.2-intl \
    php8.2-xml php8.2-bcmath php8.2-zip php8.2-curl php8.2-gd php8.2-mbstring \
    php8.2-opcache php8.2-cli php8.2-common php8.2-sodium -y

# Start PHP-FPM
sudo systemctl start php8.2-fpm
sudo systemctl enable php8.2-fpm

Configure PHP-FPM for Magento:

sudo nano /etc/php/8.2/fpm/pool.d/www.conf

Apply settings optimized for Magento:

[www]
user = www-data
group = www-data
listen = /run/php/php8.2-fpm.sock
listen.owner = www-data
listen.group = www-data

pm = dynamic
pm.max_children = 96
pm.start_servers = 24
pm.min_spare_servers = 12
pm.max_spare_servers = 48
pm.max_requests = 5000

request_terminate_timeout = 600
request_slowlog_timeout = 30s
slowlog = /var/log/php8.2-fpm-slow.log

Configure PHP settings for Magento:

sudo nano /etc/php/8.2/fpm/php.ini

Set essential parameters:

memory_limit = 2G
max_execution_time = 600
max_input_time = 600
upload_max_filesize = 256M
post_max_size = 256M
max_input_vars = 10000

; OPcache configuration
opcache.enable = 1
opcache.memory_consumption = 512
opcache.max_accelerated_files = 50000
opcache.validate_timestamps = 0
opcache.revalidate_freq = 0
opcache.interned_strings_buffer = 16
opcache.fast_shutdown = 1

; Realpath cache
realpath_cache_size = 4096K
realpath_cache_ttl = 86400

; Session configuration
session.save_path = "/var/lib/php/sessions"
session.gc_maxlifetime = 28800

Reinicie PHP-FPM:

sudo systemctl restart php8.2-fpm

Composer and Magento 2 Instaleation

Composer is the dependency manager for Magento 2 and handles all package installation.

Instale Composer:

curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
sudo chmod +x /usr/local/bin/composer

# Verify installation
composer --version

Generate Magento authentication keys:

# Log in to https://account.magento.com/
# Navigate to API Portal -> Integrations -> Tokens
# Create a new integration token
# Copy public and private keys

Configure Composer authentication:

sudo -u magento composer config -g http-basic.repo.magento.com {PUBLIC_KEY} {PRIVATE_KEY}

Descargue Magento 2 via Composer:

cd /var/www/magento
sudo -u magento composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition .

# For enterprise
# sudo -u magento composer create-project --repository-url=https://repo.magento.com/ magento/project-enterprise-edition .

Instale Magento 2:

cd /var/www/magento

# Run installation command
sudo -u magento php bin/magento setup:install \
    --base-url="https://example.com/" \
    --db-host="localhost" \
    --db-name="magento" \
    --db-user="magento" \
    --db-password="SecurePassword123!" \
    --admin-firstname="Admin" \
    --admin-lastname="User" \
    --admin-email="[email protected]" \
    --admin-user="admin" \
    --admin-password="AdminPassword123!" \
    --language="en_US" \
    --currency="USD" \
    --timezone="America/Chicago" \
    --use-rewrites="1" \
    --elasticsearch-host="localhost" \
    --elasticsearch-port="9200"

Configure file permissions:

# Set ownership
sudo chown -R :www-data /var/www/magento

# Set permissions
sudo find /var/www/magento -type f -exec chmod 644 {} \;
sudo find /var/www/magento -type d -exec chmod 755 {} \;
sudo find /var/www/magento/var -type d -exec chmod 777 {} \;
sudo find /var/www/magento/pub/static -type d -exec chmod 777 {} \;
sudo find /var/www/magento/pub/media -type d -exec chmod 777 {} \;

Elasticsearch Configuration

Magento 2 requires Elasticsearch for catalog search functionality in production environments.

Instale Elasticsearch 7.x:

# Add Elasticsearch repository
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
sudo apt-get install apt-transport-https -y
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list

# Install Elasticsearch
sudo apt update
sudo apt install elasticsearch=7.17.0 -y

# Start service
sudo systemctl start elasticsearch
sudo systemctl enable elasticsearch

Configure Elasticsearch:

sudo nano /etc/elasticsearch/elasticsearch.yml

Apply Magento-optimized settings:

cluster.name: magento-cluster
node.name: node-1
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 127.0.0.1
http.port: 9200
discovery.type: single-node

# Performance tuning
indices.memory.index_buffer_size: 30%
thread_pool.bulk.queue_size: 300
thread_pool.bulk.size: 8

Reinicie Elasticsearch:

sudo systemctl restart elasticsearch
sudo systemctl status elasticsearch

Verifique Elasticsearch:

curl -X GET "localhost:9200/"
curl -X GET "localhost:9200/_cluster/health?pretty"

Configure Magento to use Elasticsearch:

cd /var/www/magento

sudo -u magento php bin/magento config:set catalog/search/engine "elasticsearch7"
sudo -u magento php bin/magento config:set catalog/search/elasticsearch7_server_hostname "localhost"
sudo -u magento php bin/magento config:set catalog/search/elasticsearch7_server_port "9200"

# Reindex catalog
sudo -u magento php bin/magento indexer:reindex

Redis Caching Setup

Redis dramatically improves performance by caching configuration, sessions, and temporary data.

Instale Redis:

sudo apt install redis-server redis-tools -y
sudo systemctl start redis-server
sudo systemctl enable redis-server

# Verify
redis-cli ping

Configure Redis:

sudo nano /etc/redis/redis.conf

Apply production settings:

bind 127.0.0.1
protected-mode yes
port 6379
timeout 0
tcp-keepalive 300
daemonize no

# Persistence
save 900 1
save 300 10
save 60 10000
appendonly yes
appendfsync everysec

# Memory
maxmemory 2gb
maxmemory-policy allkeys-lru

# Replication
databases 16

Reinicie Redis:

sudo systemctl restart redis-server

Configure Magento to use Redis:

cd /var/www/magento

# Set cache backend to Redis
sudo -u magento php bin/magento config:set system/full_page_cache/caching_application "2"
sudo -u magento php bin/magento config:set system/full_page_cache/redis/server "127.0.0.1"
sudo -u magento php bin/magento config:set system/full_page_cache/redis/port "6379"
sudo -u magento php bin/magento config:set system/full_page_cache/redis/database "0"

# Set session storage to Redis
sudo -u magento php bin/magento config:set system/redisq/redis/host "127.0.0.1"
sudo -u magento php bin/magento config:set system/redisq/redis/port "6379"

Or configure via app/etc/env.php:

cat >> /var/www/magento/app/etc/env.php << 'EOF'
'cache' => [
    'frontend' => [
        'default' => [
            'backend' => 'Cm_Cache_Backend_Redis',
            'backend_options' => [
                'server' => '127.0.0.1',
                'port' => '6379',
                'persistent' => '',
                'database' => '0',
            ]
        ]
    ]
],
'session' => [
    'save' => 'redis',
    'redis' => [
        'host' => '127.0.0.1',
        'port' => '6379',
        'password' => '',
        'timeout' => '2.5',
        'persistent_identifier' => '',
        'database' => '1',
        'compression_threshold' => '2048',
        'compression_library' => 'gzip',
        'log_level' => '3',
        'max_concurrency' => '6',
        'break_after_frontend' => '5',
        'break_after_adminhtml' => '30',
        'first_lifetime' => '600',
        'bot_first_lifetime' => '60',
        'bot_lifetime' => '7200',
        'disable_locking' => '0',
        'min_lifetime' => '60',
        'max_lifetime' => '2592000'
    ]
],
EOF

Flush caches:

cd /var/www/magento
sudo -u magento php bin/magento cache:flush

Varnish HTTP Cache

Varnish provides HTTP-level caching for unauthenticated requests, significantly reducing server load.

Instale Varnish:

curl -L https://packagecloud.io/varnishcache/varnish60lts/gpgkey | sudo apt-key add -
echo "deb https://packagecloud.io/varnishcache/varnish60lts/ubuntu focal main" | sudo tee /etc/apt/sources.list.d/varnishcache_varnish60lts.list

sudo apt update
sudo apt install varnish -y

sudo systemctl start varnish
sudo systemctl enable varnish

Configure Varnish for Magento 2:

sudo nano /etc/varnish/default.vcl

Apply Magento 2 configuration:

vcl 4.1;

import std;
import xkey;

backend default {
    .host = "127.0.0.1";
    .port = "8080";
    .first_byte_timeout = 600s;
    .connect_timeout = 600s;
    .between_bytes_timeout = 600s;
}

acl purge {
    "127.0.0.1";
    "localhost";
}

sub vcl_recv {
    # Bypass cache for admin and API
    if (req.url ~ "^/admin" || req.url ~ "^/api") {
        return (pass);
    }

    # Cache only GET and HEAD requests
    if (req.method != "GET" && req.method != "HEAD") {
        return (pass);
    }

    # Remove cookies for cacheable requests
    if (!(req.url ~ "^/admin") && !(req.url ~ "^/customer") && !(req.url ~ "^/checkout")) {
        unset req.http.cookie;
    }

    # Purge cache on request
    if (req.method == "PURGE") {
        if (!client.ip ~ purge) {
            return (synth(405, "Not allowed"));
        }
        return (purge);
    }

    return (hash);
}

sub vcl_backend_response {
    # Cache static content for 1 year
    if (bereq.url ~ "\.(js|css|png|gif|jpg|jpeg|svg|ico|webp)$") {
        set beresp.ttl = 365d;
        set beresp.http.Cache-Control = "public, immutable";
    }

    # Cache HTML for 10 minutes
    if (beresp.http.Content-Type ~ "text/html") {
        set beresp.ttl = 10m;
        set beresp.http.Cache-Control = "public, max-age=600";
    }

    # Add xkey for smart purging
    if (beresp.status == 200) {
        set beresp.http.xkey = bereq.url;
    }

    return (deliver);
}

sub vcl_hash {
    hash_data(req.url);
    if (req.http.host) {
        hash_data(req.http.host);
    } else {
        hash_data(server.ip);
    }
    return (lookup);
}

sub vcl_deliver {
    # Add cache status header
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
    } else {
        set resp.http.X-Cache = "MISS";
    }
    set resp.http.X-Cache-Hits = obj.hits;
    return (deliver);
}

Update Varnish default port:

sudo nano /etc/varnish/varnish.params

Change to port 6081 (Varnish), Nginx will listen on 8080:

VARNISH_LISTEN_PORT=6081
VARNISH_ADMIN_LISTEN_PORT=6082
VARNISH_BACKEND_PORT=8080

Update Nginx to listen on 8080:

sudo nano /etc/nginx/sites-available/magento.conf

Change listen directive:

listen 8080;

Reinicie services:

sudo systemctl restart varnish
sudo systemctl restart nginx

Configure Magento to communicate with Varnish:

cd /var/www/magento

sudo -u magento php bin/magento config:set system/full_page_cache/caching_application "2"
sudo -u magento php bin/magento config:set system/full_page_cache/varnish/access_list "127.0.0.1"
sudo -u magento php bin/magento config:set system/full_page_cache/varnish/backend_host "127.0.0.1"
sudo -u magento php bin/magento config:set system/full_page_cache/varnish/backend_port "8080"

# Export configuration
sudo -u magento php bin/magento config:set system/full_page_cache/varnish/param_purge_button "1"

Test Varnish caching:

# Check cache status
curl -I http://localhost:6081/

# Monitor Varnish statistics
sudo varnishstat

# View real-time requests
sudo varnishlog

PHP-FPM and Nginx Optimization

Nginx configuration directly impacts Magento performance by handling requests efficiently.

Cree Nginx configuration for Magento:

sudo nano /etc/nginx/sites-available/magento.conf

Apply optimized settings:

upstream fastcgi_backend {
    server unix:/run/php/php8.2-fpm.sock;
}

server {
    listen 8080;
    server_name example.com;
    set $MAGE_ROOT /var/www/magento;

    access_log /var/log/nginx/magento_access.log;
    error_log /var/log/nginx/magento_error.log warn;

    root $MAGE_ROOT/pub;

    # 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;

    # Caching headers
    expires 365d;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    location /setup {
        root $MAGE_ROOT;
        location ~ ^/setup/index.php {
            fastcgi_pass fastcgi_backend;
            fastcgi_param SCRIPT_FILENAME $request_filename;
            include fastcgi_params;
        }
    }

    location /pub/static/ {
        expires 365d;
        add_header Cache-Control "public, immutable";
    }

    location /pub/media/ {
        expires 30d;
        add_header Cache-Control "public, proxy-revalidate";
    }

    location ~ \.php$ {
        fastcgi_pass fastcgi_backend;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_index index.php;
    }

    location ~ /\. {
        deny all;
    }
}

Enable the Nginx configuration:

sudo ln -s /etc/nginx/sites-available/magento.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Cron Jobs and Background Processing

Magento 2 requires cron jobs for indexing, cache cleaning, and background tasks.

Configure system cron:

# Edit crontab for www-data user
sudo crontab -u www-data -e

Add Magento cron entries:

*/1 * * * * cd /var/www/magento && php bin/magento cron:run | grep -v "Ran jobs" >> var/log/magento.cron.log
*/1 * * * * cd /var/www/magento && php bin/magento queue:consumers:start exportProcessor &
*/1 * * * * cd /var/www/magento && php bin/magento queue:consumers:start productAttributesProcessor &
*/1 * * * * cd /var/www/magento && php bin/magento queue:consumers:start asyncOpRedis &

Verifique cron is working:

# Check cron history
tail -f /var/www/magento/var/log/magento.cron.log

# Check scheduled jobs
sudo -u magento php bin/magento cron:run

Production Mode Implementement

Magento 2 requires specific configuration and compilation for production environments.

Set production mode:

cd /var/www/magento

# Generate static files
sudo -u magento php bin/magento setup:static-content:deploy en_US -f

# Compile DI code
sudo -u magento php bin/magento setup:di:compile

# Set mode to production
sudo -u magento php bin/magento deploy:mode:set production

# Verify mode
sudo -u magento php bin/magento deploy:mode:show

Configure environment.php:

cat > /var/www/magento/app/etc/env.php << 'EOF'
<?php
return [
    'backend' => [
        'frontName' => 'admin_custom_path'
    ],
    'crypt' => [
        'key' => 'GeneratedEncryptionKey'
    ],
    'db' => [
        'table_prefix' => '',
        'connection' => [
            'default' => [
                'host' => 'localhost',
                'dbname' => 'magento',
                'username' => 'magento',
                'password' => 'SecurePassword123!',
                'model' => 'mysql4',
                'engine' => 'innodb',
                'initStatements' => 'SET NAMES utf8;',
                'active' => '1',
            ]
        ]
    ],
    'resource' => [
        'default_setup' => [
            'connection' => 'default'
        ]
    ],
    'x-frame-options' => 'SAMEORIGIN',
    'MAGE_MODE' => 'production',
    'session' => [
        'save' => 'redis',
        'redis' => [
            'host' => '127.0.0.1',
            'port' => '6379',
            'password' => '',
            'timeout' => '2.5',
            'database' => '1',
            'compression_threshold' => '2048',
            'compression_library' => 'gzip',
        ]
    ],
];
EOF

Verifique production deployment:

# Check for errors
cd /var/www/magento && tail -f var/log/system.log

# Monitor performance
iostat -x 1
vmstat 1 10

Performance Tuning

Fine-tune Magento for maximum performance in your specific environment.

Enable HTTP/2 in Nginx:

sudo nano /etc/nginx/sites-available/magento.conf

# Update listen directive
listen 8080 http2;

Optimize MySQL for Magento:

mysql -u root -p << EOF
USE magento;
ANALYZE TABLE catalog_product_entity;
ANALYZE TABLE catalog_product_entity_media_gallery;
ANALYZE TABLE sales_order;
ANALYZE TABLE sales_order_item;
EOF

Monitor real-time performance:

# Install monitoring tools
sudo apt install nethogs iotop -y

# Monitor I/O
sudo iotop

# Monitor network
sudo nethogs

# Check memory usage
ps aux --sort=-%mem | head -20

Conclusión

Magento 2 installation and optimization requires attention to infrastructure, caching layers, and background processing. A properly configured Magento 2 environment includes optimized PHP-FPM, MySQL tuning, Elasticsearch for search, Redis for caching, Varnish for HTTP caching, and proper static file compilation. Implement these technologies in progression, monitoring performance improvements at each step. Regular maintenance including cache clearing, log rotation, and database optimization ensures sustained performance as your store grows and customer traffic increases.