Monday, March 10, 2025

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é! 🚀

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories