No menu items!
No menu items!
More

    Tối ưu performance WordPress

    1. Tổng quan.

    Việc thiết lập một máy chủ web tối ưu để chạy WordPress là một bước quan trọng nếu bạn muốn có một hệ thống nhanh, bảo mật và ổn định.

    Trong bài viết này, mình sẽ hướng dẫn chi tiết cách cài đặt và tối ưu Nginx, MySQL, PHP, Redis và WordPress trên Ubuntu.

    3. Cài đặt.

    3.1. Cập Nhật Hệ Thống Và Cài Đặt Các Gói Cần Thiết

    Trước khi bắt đầu, hãy đảm bảo hệ thống đã được cập nhật đầy đủ:

    apt update
    apt upgrade -y

    3.2. Cài đặt các gói phần mềm cần thiết.

    apt install -y nginx mysql-server \
        php-fpm php-mysql php-xml php-gd php-curl php-zip \
        php-mbstring php-imagick unzip php-intl php-bcmath php-exif \
        redis-server php-redis

    Lệnh trên sẽ giúp cài đặt Nginx, MySQL, PHP cùng các module cần thiết, cũng như Redis để tăng tốc bộ nhớ đệm (cache).

    3.3. Cấu Hình MySQL Và Tạo Database Cho WordPress

    Sau khi cài đặt MySQL, chúng ta cần thiết lập tài khoản và cơ sở dữ liệu cho WordPress:

    mysql -u root -e "CREATE DATABASE wiki CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
    mysql -u root -e"" "CREATE USER 'hoanghd'@'localhost' IDENTIFIED BY 'Hoanghd164';"
    mysql -u root -e "GRANT ALL PRIVILEGES ON wiki.* TO 'hoanghd'@'localhost';"
    mysql -u root -e "FLUSH PRIVILEGES;"

    Lưu ý: Bạn nên thay đổi mật khẩu Hoanghd164 bằng một mật khẩu mạnh hơn để bảo mật hệ thống.

    Xác minh lại kết quả sau khi tạo xong thông tin database sử dụng lệnh mysql -u root -e "SHOW GRANTS FOR 'hoanghd'@'localhost';"

    shell> mysql -u root -e "SHOW GRANTS FOR 'hoanghd'@'localhost';"
    +-----------------------------------------------------------+
    | Grants for hoanghd@localhost                              |
    +-----------------------------------------------------------+
    | GRANT USAGE ON *.* TO `hoanghd`@`localhost`               |
    | GRANT ALL PRIVILEGES ON `wiki`.* TO `hoanghd`@`localhost` |
    +-----------------------------------------------------------+

    3.4. Khởi Động Và Kích Hoạt Các Dịch Vụ

    Bây giờ, chúng ta sẽ khởi động và kích hoạt các dịch vụ cần thiết:

    systemctl restart mysql && systemctl enable mysql --now
    systemctl restart nginx && systemctl enable nginx --now
    systemctl restart php8.1-fpm && systemctl enable php8.1-fpm --now
    systemctl restart redis && systemctl enable redis --now

    Lệnh trên đảm bảo các dịch vụ này sẽ tự động chạy mỗi khi hệ thống khởi động.

    3.5. Cấu Hình Nginx Để Chạy WordPress

    Cài Đặt phiên bản mới nhất của WordPress, tải source WordPress và giải nén nó vào /tmp.

    wget https://wordpress.org/latest.tar.gz -O /tmp/latest.tar.gz
    tar xf /tmp/latest.tar.gz -C /tmp

    Tạo thư mục chứa website và move source code sau khi giải nén vào /var/www/wiki.hoanghd.com/ và phân quyền cho nó.

    mkdir -p /var/www/wiki.hoanghd.com/
    mv /tmp/wordpress/* /var/www/wiki.hoanghd.com
    chown -R www-data: /var/www/wiki.hoanghd.com

    Config Nginx.

    mkdir -p /etc/nginx/ssl

    Mình sẽ lưu cert ssl tại đây.

    cat > /etc/nginx/ssl/wiki.hoanghd.com.pem << 'OEF'
    -----BEGIN CERTIFICATE-----
    
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    
    -----END CERTIFICATE-----
    -----BEGIN PRIVATE KEY-----
    
    -----END PRIVATE KEY-----
    OEF

    Tạo thư mục cache và thiết lập quyền truy cập và sở hữu cho các thư mục. Lệnh dưới đây sẽ tạo tất cả các thư mục cần thiết trong một lệnh `mkdir -p` và sau đó thiết lập quyền sở hữu và quyền truy cập cho tất cả các thư mục trong các lệnh `chown` và `chmod` tương ứng.

    mkdir -p /etc/nginx/cache_fastcgi /etc/nginx/cache_proxy /var/cache/nginx/client_temp /var/cache/nginx/static_cache /var/cache/nginx/proxy_cache
    chown -R www-data:www-data /var/cache/nginx /etc/nginx/cache_fastcgi /etc/nginx/cache_proxy
    chmod -R 755 /var/cache/nginx /etc/nginx/cache_fastcgi /etc/nginx/cache_proxy

    Sau đó, tạo file cấu hình Nginx /etc/nginx/nginx.conf.

    cat > /etc/nginx/nginx.conf << 'OEF'
    user www-data;
    worker_processes auto;
    pid /run/nginx.pid;
    include /etc/nginx/modules-enabled/*.conf;
    
    events {
        worker_connections 10240;
        multi_accept on;
    }
    
    http {
        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 4096;
    
        include /etc/nginx/mime.types;
        default_type application/octet-stream;
    
        gzip on;
        gzip_disable "msie6";
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    
        fastcgi_cache_path /etc/nginx/cache levels=1:2 keys_zone=WORDPRESS:100m inactive=60m use_temp_path=off;
        fastcgi_cache_path /etc/nginx/cache_fastcgi levels=1:2 keys_zone=FCGI_CACHE:100m inactive=60m use_temp_path=off;
        proxy_cache_path /var/cache/nginx/static_cache levels=1:2 keys_zone=STATIC_CACHE:10m inactive=7d max_size=1g;
        proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2 keys_zone=PROXY_CACHE:100m inactive=30m max_size=5g;
        fastcgi_cache_path /var/cache/nginx levels=1:2 keys_zone=PHP_CACHE:100m inactive=60m;
    
        include /etc/nginx/conf.d/*.conf;
    }
    OEF

    Tạo tiếp file wiki.hoanghd.com.conf

    cat > /etc/nginx/conf.d/wiki.hoanghd.com.conf << 'OEF'
    server {
        listen 80;
        server_name wiki.hoanghd.com;
    
        # Redirect HTTP to HTTPS
        return 301 https://$host$request_uri;
    }
    
    server {
        listen 443 ssl http2;
        server_name wiki.hoanghd.com;
    
        ssl_certificate /etc/nginx/ssl/wiki.hoanghd.com.pem;
        ssl_certificate_key /etc/nginx/ssl/wiki.hoanghd.com.pem;
        ssl_trusted_certificate /etc/nginx/ssl/wiki.hoanghd.com.pem;
    
        root /var/www/wiki.hoanghd.com;
        index index.php index.html index.htm;
    
        # Ghi log truy cập và lỗi
        access_log /var/log/nginx/wiki_access.log combined;
        error_log /var/log/nginx/wiki_error.log warn;
        
        fastcgi_cache_key "$scheme$request_method$host$request_uri";
    
        location / {
            try_files $uri $uri/ /index.php?$args;
        }
    
        # Cấu hình xử lý PHP-FPM
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
    
            # Bật FastCGI Cache
            fastcgi_cache PHP_CACHE;
            fastcgi_cache_valid 200 301 30m;
            fastcgi_cache_use_stale updating error timeout invalid_header http_500;
            fastcgi_cache_lock on;
            fastcgi_cache_min_uses 2;
            fastcgi_cache_methods GET HEAD;
            
            # Bỏ qua cache nếu có Set-Cookie hoặc nếu user đăng nhập
            fastcgi_cache_bypass $http_cookie;
            fastcgi_no_cache $http_cookie;
    
            # Debug trạng thái cache
            add_header X-FastCGI-Cache $upstream_cache_status;
        }
    
        # Caching file tĩnh (CSS, JS, ảnh, fonts)
        location ~* \.(?:css|js|gif|jpe?g|png|ico|woff2?|ttf|svg|eot|mp4|webm|ogg|ogv|zip|pdf)$ {
            expires 365d;
            add_header Cache-Control "public, max-age=31536000, immutable";
        }
    
        # Chặn truy cập file ẩn
        location ~ /\. {
            deny all;
        }
    
        # Trang lỗi tùy chỉnh
        error_page 403 /error403.html;
        location = /error403.html {
            internal;
            root /var/www/wiki.hoanghd.com;
        }
    }
    OEF

    Kiểm tra cú pháp Nginx.

    shell> nginx -t
    nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
    nginx: configuration file /etc/nginx/nginx.conf test is successful

    Áp dụng cấu hình mới.

    nginx -s reload

    Config Redis.

    Mở Redis cho WordPress:

    sed -i 's/supervised no/supervised systemd/' /etc/redis/redis.conf

    Cho phép kết nối từ xa

    sed -i 's/protected-mode yes/protected-mode no/' /etc/redis/redis.conf

    Xác minh thay đổi config Redis thành công.

    shell> grep -E '^supervised|^protected-mode' /etc/redis/redis.conf
    protected-mode no
    supervised systemd

    Khởi động lại Redis.

    systemctl restart redis

    Xác minh Redis khởi động không có lỗi.

    shell> systemctl is-active redis
    active

    Cài đặt và config WP-CLI.

    curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
    chmod +x wp-cli.phar
    mv wp-cli.phar /usr/local/bin/wp

    Kiểm tra WP-CLI đã hoạt động chưa:

    shell> wp --info
    OS:	Linux 5.15.0-43-generic #46-Ubuntu SMP Tue Jul 12 10:30:17 UTC 2022 x86_64
    Shell:	/bin/bash
    PHP binary:	/usr/bin/php8.1
    PHP version:	8.1.2-1ubuntu2.20
    php.ini used:	/etc/php/8.1/cli/php.ini
    MySQL binary:	/usr/bin/mysql
    MySQL version:	mysql  Ver 8.0.41-0ubuntu0.22.04.1 for Linux on x86_64 ((Ubuntu))
    SQL modes:	ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
    WP-CLI root dir:	phar://wp-cli.phar/vendor/wp-cli/wp-cli
    WP-CLI vendor dir:	phar://wp-cli.phar/vendor
    WP_CLI phar path:	/root
    WP-CLI packages dir:
    WP-CLI cache dir:	/root/.wp-cli/cache
    WP-CLI global config:
    WP-CLI project config:
    WP-CLI version:	2.11.0

    Cài đặt plugin Redis Object Cache.

    cd /var/www/wiki.hoanghd.com/wp-content/plugins/
    wget https://downloads.wordpress.org/plugin/redis-cache.zip
    unzip redis-cache.zip
    chown -R www-data:www-data redis-cache

    Sử dụng lệnh WP-CLI để config thông tin DB.

    shell> wp core config --dbname=wiki --dbuser=hoanghd --dbpass='Hoanghd164' --path="/var/www/wiki.hoanghd.com" --allow-root
    Success: Generated 'wp-config.php' file.

    Sử dụng lệnh WP-CLI để config thông tin Site.

    shell> wp core install --skip-email --url=https://wiki.hoanghd.com --title='Wordpress demo caching' --admin_user=hoanghd --admin_email=hoanghd164@gmail.com --admin_password='Hoanghd164' --path="/var/www/wiki.hoanghd.com" --allow-root
    Success: WordPress installed successfully.

    Phần này tùy chọn, bạn có thể thêm thông tin bổ sung vào /var/www/wiki.hoanghd.com/wp-config.php

    define( 'WP_CACHE', true ); // Added by WP Rocket
    define( 'WP_MEMORY_LIMIT', '8192M' );
    define( 'ALTERNATE_WP_CRON', true );
    define( 'WP_AUTO_UPDATE_CORE', false );
    define( 'WP_REDIS_HOST', '127.0.0.1' );
    define( 'WP_REDIS_PORT', 6379 );
    define( 'WP_REDIS_DATABASE', 0 );
    define( 'WP_REDIS_TIMEOUT', 1 );
    define( 'WP_REDIS_READ_TIMEOUT', 1 );
    define( 'WP_REDIS_SCHEME', 'tcp' );
    define( 'WP_REDIS_GLOBAL_GROUPS', ['users', 'userlogins'] );
    define( 'WP_REDIS_NON_PERSISTENT', true );

    Hãy chắc chắn có kết nối đến Redis.

    shell> telnet 127.0.0.1 6379
    Trying 127.0.0.1...
    Connected to 127.0.0.1.
    Escape character is '^]'.
    quit
    +OK
    Connection closed by foreign host.

    Truy cập WordPress.

    Sau đó, bạn có thể truy cập WordPress thông qua url http://wiki.hoanghd.com mà không cần phải config thêm thông tin gì nữa.

    Login đúng tài khoản bạn vừa config ở trên và bạn có kết quả.

    Cài Đặt Và Cấu Hình Plugin Redis Cache

    WordPress có thể sử dụng Redis để tăng tốc độ tải trang. Đầu tiên, cài đặt plugin Redis Cache:

    shell> wp plugin install redis-cache --activate --path="/var/www/wiki.hoanghd.com" --allow-root
    Warning: redis-cache: Plugin already installed.
    Activating 'redis-cache'...
    Plugin 'redis-cache' activated.
    Success: Plugin already installed.

    Tiếp theo hãy enable Redis Object Cache.

    shell> wp redis enable --path="/var/www/wiki.hoanghd.com" --allow-root
    Success: Object cache enabled.

    Sau đó, kiểm tra Redis đã hoạt động hay chưa:

    shell> redis-cli ping
    PONG

    Nếu hiển thị PONG, Redis đã chạy thành công!

    Nếu bạn cài plugin Redis Object Cache, chạy lệnh dưới và nếu thấy “Connected”, tức là đang cache đúng.

    wp redis status --path="/var/www/wiki.hoanghd.com" --allow-root

    Ví dụ.

    shell> wp redis status --path="/var/www/wiki.hoanghd.com" --allow-root
    Status: Connected
    Client: PhpRedis (v5.3.5)
    Drop-in: Valid
    Disabled: No
    Ping: 1
    Errors: []
    PhpRedis: 5.3.5
    Relay: Not loaded
    Predis: Not loaded
    Credis: Not loaded
    PHP Version: 8.1.2-1ubuntu2.20
    Plugin Version: 2.5.4
    Redis Version: 6.0.16
    Multisite: No
    Metrics: Enabled
    Metrics recorded: 1
    Filesystem: Writable
    Global Prefix: "wp_"
    Blog Prefix: "wp_"
    Timeout: 1
    Read Timeout: 1
    Retry Interval:
    WP_REDIS_PREFIX: "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~B"
    WP_CACHE_KEY_SALT: "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~B"
    WP_REDIS_PLUGIN_PATH: "/var/www/wiki.hoanghd.com/wp-content/plugins/redis-cache"
    Global Groups: [
        "blog-details",
        "blog-id-cache",
        "blog-lookup",
        "global-posts",
        "networks",
        "rss",
        "sites",
        "site-details",
        "site-lookup",
        "site-options",
        "site-transient",
        "users",
        "useremail",
        "userlogins",
        "usermeta",
        "user_meta",
        "userslugs",
        "redis-cache",
        "blog_meta",
        "image_editor",
        "network-queries",
        "site-queries",
        "theme_files",
        "translation_files",
        "user-queries"
    ]
    Ignored Groups: [
        "counts",
        "plugins",
        "theme_json",
        "themes"
    ]
    Unflushable Groups: []
    Groups Types: {
        "blog-details": "global",
        "blog-id-cache": "global",
        "blog-lookup": "global",
        "global-posts": "global",
        "networks": "global",
        "rss": "global",
        "sites": "global",
        "site-details": "global",
        "site-lookup": "global",
        "site-options": "global",
        "site-transient": "global",
        "users": "global",
        "useremail": "global",
        "userlogins": "global",
        "usermeta": "global",
        "user_meta": "global",
        "userslugs": "global",
        "redis-cache": "global",
        "blog_meta": "global",
        "image_editor": "global",
        "network-queries": "global",
        "site-queries": "global",
        "theme_files": "global",
        "translation_files": "global",
        "user-queries": "global",
        "counts": "ignored",
        "plugins": "ignored",
        "theme_json": "ignored",
        "themes": "ignored"
    }
    Drop-ins: [
        "Redis Object Cache Drop-In v2.5.4 by Till Krüss"
    ]

    4. Verify.

    Kiểm tra số lượng cache hiện có trong Redis, chạy lệnh sau trong Redis CLI. Nếu bạn thấy kết quả như dưới tức là chưa có dữ liệu cache.

    shell> redis-cli
    127.0.0.1:6379> INFO keyspace
    # Keyspace

    Hãy vào trình duyệt bấm F5 vài lần để tải lại trang chạy lại lệnh INFO keyspace ta có kết quả.

    shell> redis-cli
    127.0.0.1:6379> INFO keyspace
    # Keyspace
    db0:keys=11,expires=4,avg_ttl=3075096
    127.0.0.1:6379>

    Liệt kê các key hiện có trong Redis, nếu danh sách trống ((empty array)), có thể là WordPress chưa ghi cache hoặc dữ liệu đã bị xóa.

    shell> redis-cli
    127.0.0.1:6379> KEYS *
     1) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:posts:3"
     2) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:useremail:hoanghd164@gmail.com"
     3) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:transient:doing_cron"
     4) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:userslugs:hoanghd"
     5) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:translation_files:ea60d35625a69021f47570aae7aa356b"
     6) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:options:notoptions"
     7) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:site-transient:wp_theme_files_patterns-aa52aaf8f1287466ec0ba9e913bcfc59"
     8) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:translation_files:89eb930351b616535414d06fccd9ebe7"
     9) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:transient:wp_core_block_css_files"
    10) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:user_meta:1"
    11) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:post_meta:3"
    12) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:redis-cache:metrics"
    13) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:userlogins:hoanghd"
    14) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:translation_files:93144c9296a5677513b77ae6fc91e571"
    15) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:default:is_blog_installed"
    16) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:options:alloptions"
    17) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:site-options:1-notoptions"
    18) "a (#eHiBcT?/8GUz(_wEbJ}o:LPTrPtsvOgJ0;G+n-J$X09,aw=!98b :s{9a(~Bwp:users:1"
    127.0.0.1:6379>

    Chạy lệnh sau để kiểm tra header phản hồi từ server Nginx.

    shell> curl -I https://wiki.hoanghd.com/
    HTTP/2 200
    server: nginx/1.18.0 (Ubuntu)
    date: Sun, 09 Mar 2025 08:02:26 GMT
    content-type: text/html; charset=UTF-8
    link: <https://wiki.hoanghd.com/index.php?rest_route=/>; rel="https://api.w.org/"
    x-fastcgi-cache: HIT

    Hoặc nếu trang có PHP (để kiểm tra FastCGI cache):

    shell> curl -I https://wiki.hoanghd.com/index.php
    HTTP/2 301
    server: nginx/1.18.0 (Ubuntu)
    date: Sun, 09 Mar 2025 08:03:06 GMT
    content-type: text/html; charset=UTF-8
    location: https://wiki.hoanghd.com/
    x-redirect-by: WordPress
    x-fastcgi-cache: HIT

    Bạn có thể kiểm tra xem Nginx có lưu cache không bằng cách:

    shell> ls -l /var/cache/nginx/
    total 16
    drwx------ 3 www-data www-data 4096 Mar  9 08:04 4
    drwx------ 3 www-data www-data 4096 Mar  9 08:05 e
    drwx------ 2 www-data root     4096 Mar  9 08:04 proxy_cache
    drwx------ 2 www-data root     4096 Mar  9 08:04 static_cache
    • X-FastCGI-Cache: HIT → Cache từ Redis đang được dùng.
    • X-FastCGI-Cache: MISS → Cache chưa lưu hoặc đã bị xóa.

    Bạn có thể xóa toàn bộ file và thư mục tại /var/cache/nginx/ và chạy lại lệnh curl như các bước trên và kiểm tra xem cache có lưu vào Redis chưa nhé! 🚀 Nếu có file cache trong thư mục này, tức là cache đang hoạt động.

    5. Kết Luận

    Qua bài viết này, mình đã hướng dẫn bạn từng bước để thiết lập một server chạy WordPress tối ưu với Nginx, MySQL, PHP và Redis. Nếu bạn có câu hỏi hoặc cần hỗ trợ, hãy để lại bình luận nhé! 🚀

    Bài viết gần đây

    spot_img

    Related Stories

    Leave A Reply

    Please enter your comment!
    Please enter your name here

    Đăng ký nhận thông tin bài viết qua email